Merge "Fix rollback reason in rollback all case"
diff --git a/Android.bp b/Android.bp
index 926b4d8..9cd43fa 100644
--- a/Android.bp
+++ b/Android.bp
@@ -504,6 +504,13 @@
}
filegroup {
+ name: "framework-android-os-unit-testable-src",
+ srcs: [
+ "core/java/android/os/DdmSyncState.java",
+ ],
+}
+
+filegroup {
name: "framework-networkstack-shared-srcs",
srcs: [
// TODO: remove these annotations as soon as we can use andoid.support.annotations.*
diff --git a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
index 7f02cb3..2f6b689 100644
--- a/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
+++ b/apex/jobscheduler/framework/java/android/app/job/JobInfo.java
@@ -432,6 +432,7 @@
@UnsupportedAppUsage
private final ComponentName service;
private final int constraintFlags;
+ private final int mPreferredConstraintFlags;
private final TriggerContentUri[] triggerContentUris;
private final long triggerContentUpdateDelay;
private final long triggerContentMaxDelay;
@@ -522,6 +523,30 @@
}
/**
+ * @hide
+ * @see JobInfo.Builder#setPrefersBatteryNotLow(boolean)
+ */
+ public boolean isPreferBatteryNotLow() {
+ return (mPreferredConstraintFlags & CONSTRAINT_FLAG_BATTERY_NOT_LOW) != 0;
+ }
+
+ /**
+ * @hide
+ * @see JobInfo.Builder#setPrefersCharging(boolean)
+ */
+ public boolean isPreferCharging() {
+ return (mPreferredConstraintFlags & CONSTRAINT_FLAG_CHARGING) != 0;
+ }
+
+ /**
+ * @hide
+ * @see JobInfo.Builder#setPrefersDeviceIdle(boolean)
+ */
+ public boolean isPreferDeviceIdle() {
+ return (mPreferredConstraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0;
+ }
+
+ /**
* @see JobInfo.Builder#setRequiresCharging(boolean)
*/
public boolean isRequireCharging() {
@@ -557,6 +582,13 @@
}
/**
+ * @hide
+ */
+ public int getPreferredConstraintFlags() {
+ return mPreferredConstraintFlags;
+ }
+
+ /**
* Which content: URIs must change for the job to be scheduled. Returns null
* if there are none required.
* @see JobInfo.Builder#addTriggerContentUri(TriggerContentUri)
@@ -800,6 +832,9 @@
if (constraintFlags != j.constraintFlags) {
return false;
}
+ if (mPreferredConstraintFlags != j.mPreferredConstraintFlags) {
+ return false;
+ }
if (!Arrays.equals(triggerContentUris, j.triggerContentUris)) {
return false;
}
@@ -880,6 +915,7 @@
hashCode = 31 * hashCode + service.hashCode();
}
hashCode = 31 * hashCode + constraintFlags;
+ hashCode = 31 * hashCode + mPreferredConstraintFlags;
if (triggerContentUris != null) {
hashCode = 31 * hashCode + Arrays.hashCode(triggerContentUris);
}
@@ -922,6 +958,7 @@
}
service = in.readParcelable(null);
constraintFlags = in.readInt();
+ mPreferredConstraintFlags = in.readInt();
triggerContentUris = in.createTypedArray(TriggerContentUri.CREATOR);
triggerContentUpdateDelay = in.readLong();
triggerContentMaxDelay = in.readLong();
@@ -956,6 +993,7 @@
clipGrantFlags = b.mClipGrantFlags;
service = b.mJobService;
constraintFlags = b.mConstraintFlags;
+ mPreferredConstraintFlags = b.mPreferredConstraintFlags;
triggerContentUris = b.mTriggerContentUris != null
? b.mTriggerContentUris.toArray(new TriggerContentUri[b.mTriggerContentUris.size()])
: null;
@@ -999,6 +1037,7 @@
}
out.writeParcelable(service, flags);
out.writeInt(constraintFlags);
+ out.writeInt(mPreferredConstraintFlags);
out.writeTypedArray(triggerContentUris, flags);
out.writeLong(triggerContentUpdateDelay);
out.writeLong(triggerContentMaxDelay);
@@ -1146,6 +1185,7 @@
private int mFlags;
// Requirements.
private int mConstraintFlags;
+ private int mPreferredConstraintFlags;
private NetworkRequest mNetworkRequest;
private long mNetworkDownloadBytes = NETWORK_BYTES_UNKNOWN;
private long mNetworkUploadBytes = NETWORK_BYTES_UNKNOWN;
@@ -1199,6 +1239,7 @@
mBias = job.getBias();
mFlags = job.getFlags();
mConstraintFlags = job.getConstraintFlags();
+ mPreferredConstraintFlags = job.getPreferredConstraintFlags();
mNetworkRequest = job.getRequiredNetwork();
mNetworkDownloadBytes = job.getEstimatedNetworkDownloadBytes();
mNetworkUploadBytes = job.getEstimatedNetworkUploadBytes();
@@ -1341,9 +1382,6 @@
* Calling this method will override any requirements previously defined
* by {@link #setRequiredNetwork(NetworkRequest)}; you typically only
* want to call one of these methods.
- * <p> Starting in Android version {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE},
- * {@link JobScheduler} may try to shift the execution of jobs requiring
- * {@link #NETWORK_TYPE_ANY} to when there is access to an un-metered network.
* <p class="note">
* When your job executes in
* {@link JobService#onStartJob(JobParameters)}, be sure to use the
@@ -1505,10 +1543,105 @@
}
/**
- * Specify that to run this job, the device must be charging (or be a
+ * Specify that this job would prefer to be run when the device's battery is not low.
+ * This defaults to {@code false}.
+ *
+ * <p>The system may attempt to delay this job until the device's battery is not low,
+ * but may choose to run it even if the device's battery is low. JobScheduler will not stop
+ * this job if this constraint is no longer satisfied after the job has started running.
+ * If this job must only run when the device's battery is not low,
+ * use {@link #setRequiresBatteryNotLow(boolean)} instead.
+ *
+ * <p>
+ * Because it doesn't make sense for a constraint to be both preferred and required,
+ * calling both this and {@link #setRequiresBatteryNotLow(boolean)} with {@code true}
+ * will result in an {@link java.lang.IllegalArgumentException} when
+ * {@link android.app.job.JobInfo.Builder#build()} is called.
+ *
+ * @param prefersBatteryNotLow Pass {@code true} to prefer that the device's battery level
+ * not be low in order to run the job.
+ * @return This object for method chaining
+ * @see JobInfo#isPreferBatteryNotLow()
+ * @hide
+ */
+ @NonNull
+ public Builder setPrefersBatteryNotLow(boolean prefersBatteryNotLow) {
+ mPreferredConstraintFlags =
+ (mPreferredConstraintFlags & ~CONSTRAINT_FLAG_BATTERY_NOT_LOW)
+ | (prefersBatteryNotLow ? CONSTRAINT_FLAG_BATTERY_NOT_LOW : 0);
+ return this;
+ }
+
+ /**
+ * Specify that this job would prefer to be run when the device is charging (or be a
* non-battery-powered device connected to permanent power, such as Android TV
* devices). This defaults to {@code false}.
*
+ * <p>
+ * The system may attempt to delay this job until the device is charging, but may
+ * choose to run it even if the device is not charging. JobScheduler will not stop
+ * this job if this constraint is no longer satisfied after the job has started running.
+ * If this job must only run when the device is charging,
+ * use {@link #setRequiresCharging(boolean)} instead.
+ *
+ * <p>
+ * Because it doesn't make sense for a constraint to be both preferred and required,
+ * calling both this and {@link #setRequiresCharging(boolean)} with {@code true}
+ * will result in an {@link java.lang.IllegalArgumentException} when
+ * {@link android.app.job.JobInfo.Builder#build()} is called.
+ *
+ * @param prefersCharging Pass {@code true} to prefer that the device be
+ * charging in order to run the job.
+ * @return This object for method chaining
+ * @see JobInfo#isPreferCharging()
+ * @hide
+ */
+ @NonNull
+ public Builder setPrefersCharging(boolean prefersCharging) {
+ mPreferredConstraintFlags = (mPreferredConstraintFlags & ~CONSTRAINT_FLAG_CHARGING)
+ | (prefersCharging ? CONSTRAINT_FLAG_CHARGING : 0);
+ return this;
+ }
+
+ /**
+ * Specify that this job would prefer to be run when the device is not in active use.
+ * This defaults to {@code false}.
+ *
+ * <p>The system may attempt to delay this job until the device is not in active use,
+ * but may choose to run it even if the device is not idle. JobScheduler will not stop
+ * this job if this constraint is no longer satisfied after the job has started running.
+ * If this job must only run when the device is not in active use,
+ * use {@link #setRequiresDeviceIdle(boolean)} instead.
+ *
+ * <p>
+ * Because it doesn't make sense for a constraint to be both preferred and required,
+ * calling both this and {@link #setRequiresDeviceIdle(boolean)} with {@code true}
+ * will result in an {@link java.lang.IllegalArgumentException} when
+ * {@link android.app.job.JobInfo.Builder#build()} is called.
+ *
+ * <p class="note">Despite the similar naming, this job constraint is <em>not</em>
+ * related to the system's "device idle" or "doze" states. This constraint only
+ * determines whether a job is allowed to run while the device is directly in use.
+ *
+ * @param prefersDeviceIdle Pass {@code true} to prefer that the device not be in active
+ * use when running this job.
+ * @return This object for method chaining
+ * @see JobInfo#isRequireDeviceIdle()
+ * @hide
+ */
+ @NonNull
+ public Builder setPrefersDeviceIdle(boolean prefersDeviceIdle) {
+ mPreferredConstraintFlags = (mPreferredConstraintFlags & ~CONSTRAINT_FLAG_DEVICE_IDLE)
+ | (prefersDeviceIdle ? CONSTRAINT_FLAG_DEVICE_IDLE : 0);
+ return this;
+ }
+
+ /**
+ * Specify that to run this job, the device must be charging (or be a
+ * non-battery-powered device connected to permanent power, such as Android TV
+ * devices). This defaults to {@code false}. Setting this to {@code false} <b>DOES NOT</b>
+ * mean the job will only run when the device is not charging.
+ *
* <p class="note">For purposes of running jobs, a battery-powered device
* "charging" is not quite the same as simply being connected to power. If the
* device is so busy that the battery is draining despite a power connection, jobs
@@ -1530,7 +1663,9 @@
* Specify that to run this job, the device's battery level must not be low.
* This defaults to false. If true, the job will only run when the battery level
* is not low, which is generally the point where the user is given a "low battery"
- * warning.
+ * warning. Setting this to {@code false} <b>DOES NOT</b> mean the job will only run
+ * when the battery is low.
+ *
* @param batteryNotLow Whether or not the device's battery level must not be low.
* @see JobInfo#isRequireBatteryNotLow()
*/
@@ -1543,7 +1678,8 @@
/**
* When set {@code true}, ensure that this job will not run if the device is in active use.
* The default state is {@code false}: that is, the for the job to be runnable even when
- * someone is interacting with the device.
+ * someone is interacting with the device. Setting this to {@code false} <b>DOES NOT</b>
+ * mean the job will only run when the device is not idle.
*
* <p>This state is a loose definition provided by the system. In general, it means that
* the device is not currently being used interactively, and has not been in use for some
@@ -2156,6 +2292,29 @@
}
}
+ if ((constraintFlags & mPreferredConstraintFlags) != 0) {
+ // Something is marked as both preferred and required. Try to give a clear exception
+ // reason.
+ if ((constraintFlags & CONSTRAINT_FLAG_BATTERY_NOT_LOW) != 0
+ && (mPreferredConstraintFlags & CONSTRAINT_FLAG_BATTERY_NOT_LOW) != 0) {
+ throw new IllegalArgumentException(
+ "battery-not-low constraint cannot be both preferred and required");
+ }
+ if ((constraintFlags & CONSTRAINT_FLAG_CHARGING) != 0
+ && (mPreferredConstraintFlags & CONSTRAINT_FLAG_CHARGING) != 0) {
+ throw new IllegalArgumentException(
+ "charging constraint cannot be both preferred and required");
+ }
+ if ((constraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0
+ && (mPreferredConstraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0) {
+ throw new IllegalArgumentException(
+ "device idle constraint cannot be both preferred and required");
+ }
+ // Couldn't figure out what the overlap was. Just use a generic message.
+ throw new IllegalArgumentException(
+ "constraints cannot be both preferred and required");
+ }
+
if (isUserInitiated) {
if (hasEarlyConstraint) {
throw new IllegalArgumentException("A user-initiated job cannot have a time delay");
@@ -2173,7 +2332,8 @@
if (mPriority != PRIORITY_MAX) {
throw new IllegalArgumentException("A user-initiated job must be max priority.");
}
- if ((constraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0) {
+ if ((constraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0
+ || (mPreferredConstraintFlags & CONSTRAINT_FLAG_DEVICE_IDLE) != 0) {
throw new IllegalArgumentException(
"A user-initiated job cannot have a device-idle constraint");
}
diff --git a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
index 9b64edf..f50a902 100644
--- a/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
+++ b/apex/jobscheduler/framework/java/com/android/server/usage/AppStandbyInternal.java
@@ -225,6 +225,8 @@
void setActiveAdminApps(Set<String> adminPkgs, int userId);
+ void setAdminProtectedPackages(Set<String> packageNames, int userId);
+
/**
* @return {@code true} if the given package is an active device admin app.
*/
diff --git a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
index b7cf297..3fc87d3 100644
--- a/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
+++ b/apex/jobscheduler/service/java/com/android/server/AppStateTrackerImpl.java
@@ -429,7 +429,7 @@
/**
* Called when a uid goes into cached, so its alarms using a listener should be removed.
*/
- public void removeListenerAlarmsForCachedUid(int uid) {
+ public void handleUidCachedChanged(int uid, boolean cached) {
}
}
@@ -870,9 +870,7 @@
}
public void onUidCachedChanged(int uid, boolean cached) {
- if (cached) {
- obtainMessage(MSG_ON_UID_CACHED, uid, 0).sendToTarget();
- }
+ obtainMessage(MSG_ON_UID_CACHED, uid, cached ? 1 : 0).sendToTarget();
}
@Override
@@ -969,14 +967,14 @@
}
return;
case MSG_ON_UID_CACHED:
- handleUidCached(msg.arg1);
+ handleUidCached(msg.arg1, (msg.arg2 != 0));
return;
}
}
- private void handleUidCached(int uid) {
+ private void handleUidCached(int uid, boolean cached) {
for (Listener l : cloneListeners()) {
- l.removeListenerAlarmsForCachedUid(uid);
+ l.handleUidCachedChanged(uid, cached);
}
}
diff --git a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
index e38e21f..0650ce3 100644
--- a/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
+++ b/apex/jobscheduler/service/java/com/android/server/DeviceIdleController.java
@@ -1970,7 +1970,7 @@
} break;
case MSG_RESET_PRE_IDLE_TIMEOUT_FACTOR: {
updatePreIdleFactor();
- maybeDoImmediateMaintenance();
+ maybeDoImmediateMaintenance("idle factor");
} break;
case MSG_REPORT_STATIONARY_STATUS: {
final DeviceIdleInternal.StationaryListener newListener =
@@ -3517,11 +3517,11 @@
// doze alarm to after the upcoming AlarmClock alarm.
scheduleAlarmLocked(
mAlarmManager.getNextWakeFromIdleTime() - mInjector.getElapsedRealtime()
- + mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
+ + mConstants.QUICK_DOZE_DELAY_TIMEOUT);
} else {
// Wait a small amount of time in case something (eg: background service from
// recently closed app) needs to finish running.
- scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT, false);
+ scheduleAlarmLocked(mConstants.QUICK_DOZE_DELAY_TIMEOUT);
}
} else if (mState == STATE_ACTIVE) {
moveToStateLocked(STATE_INACTIVE, "no activity");
@@ -3536,9 +3536,9 @@
// alarm to after the upcoming AlarmClock alarm.
scheduleAlarmLocked(
mAlarmManager.getNextWakeFromIdleTime() - mInjector.getElapsedRealtime()
- + delay, false);
+ + delay);
} else {
- scheduleAlarmLocked(delay, false);
+ scheduleAlarmLocked(delay);
}
}
}
@@ -3753,7 +3753,7 @@
if (shouldUseIdleTimeoutFactorLocked()) {
delay = (long) (mPreIdleFactor * delay);
}
- scheduleAlarmLocked(delay, false);
+ scheduleAlarmLocked(delay);
moveToStateLocked(STATE_IDLE_PENDING, reason);
break;
case STATE_IDLE_PENDING:
@@ -3779,7 +3779,7 @@
case STATE_SENSING:
cancelSensingTimeoutAlarmLocked();
moveToStateLocked(STATE_LOCATING, reason);
- scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT, false);
+ scheduleAlarmLocked(mConstants.LOCATING_TIMEOUT);
LocationManager locationManager = mInjector.getLocationManager();
if (locationManager != null
&& locationManager.getProvider(LocationManager.NETWORK_PROVIDER) != null) {
@@ -3819,7 +3819,7 @@
// Everything is in place to go into IDLE state.
case STATE_IDLE_MAINTENANCE:
moveToStateLocked(STATE_IDLE, reason);
- scheduleAlarmLocked(mNextIdleDelay, true);
+ scheduleAlarmLocked(mNextIdleDelay);
if (DEBUG) Slog.d(TAG, "Moved to STATE_IDLE. Next alarm in " + mNextIdleDelay +
" ms.");
mNextIdleDelay = (long)(mNextIdleDelay * mConstants.IDLE_FACTOR);
@@ -3842,7 +3842,7 @@
mActiveIdleOpCount = 1;
mActiveIdleWakeLock.acquire();
moveToStateLocked(STATE_IDLE_MAINTENANCE, reason);
- scheduleAlarmLocked(mNextIdlePendingDelay, false);
+ scheduleAlarmLocked(mNextIdlePendingDelay);
if (DEBUG) Slog.d(TAG, "Moved from STATE_IDLE to STATE_IDLE_MAINTENANCE. " +
"Next alarm in " + mNextIdlePendingDelay + " ms.");
mMaintenanceStartTime = SystemClock.elapsedRealtime();
@@ -4013,19 +4013,18 @@
if (Math.abs(delay - newDelay) < MIN_STATE_STEP_ALARM_CHANGE) {
return;
}
- scheduleAlarmLocked(newDelay, false);
+ scheduleAlarmLocked(newDelay);
}
}
}
- private void maybeDoImmediateMaintenance() {
+ private void maybeDoImmediateMaintenance(String reason) {
synchronized (this) {
if (mState == STATE_IDLE) {
long duration = SystemClock.elapsedRealtime() - mIdleStartTime;
- /* Let's trgger a immediate maintenance,
- * if it has been idle for a long time */
+ // Trigger an immediate maintenance window if it has been IDLE for long enough.
if (duration > mConstants.IDLE_TIMEOUT) {
- scheduleAlarmLocked(0, false);
+ stepIdleStateLocked(reason);
}
}
}
@@ -4045,7 +4044,7 @@
void setIdleStartTimeForTest(long idleStartTime) {
synchronized (this) {
mIdleStartTime = idleStartTime;
- maybeDoImmediateMaintenance();
+ maybeDoImmediateMaintenance("testing");
}
}
@@ -4224,8 +4223,9 @@
}
@GuardedBy("this")
- void scheduleAlarmLocked(long delay, boolean idleUntil) {
- if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + idleUntil + ")");
+ @VisibleForTesting
+ void scheduleAlarmLocked(long delay) {
+ if (DEBUG) Slog.d(TAG, "scheduleAlarmLocked(" + delay + ", " + stateToString(mState) + ")");
if (mUseMotionSensor && mMotionSensor == null
&& mState != STATE_QUICK_DOZE_DELAY
@@ -4241,7 +4241,7 @@
return;
}
mNextAlarmTime = SystemClock.elapsedRealtime() + delay;
- if (idleUntil) {
+ if (mState == STATE_IDLE) {
mAlarmManager.setIdleUntil(AlarmManager.ELAPSED_REALTIME_WAKEUP,
mNextAlarmTime, "DeviceIdleController.deep", mDeepAlarmListener, mHandler);
} else if (mState == STATE_LOCATING) {
diff --git a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
index 394be6e..c76a43f 100644
--- a/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/alarm/AlarmManagerService.java
@@ -30,6 +30,9 @@
import static android.app.AlarmManager.INTERVAL_HOUR;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.RTC_WAKEUP;
+import static android.content.PermissionChecker.PERMISSION_GRANTED;
+import static android.content.PermissionChecker.PID_UNKNOWN;
+import static android.content.PermissionChecker.checkPermissionForPreflight;
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import static android.os.PowerExemptionManager.REASON_ALARM_MANAGER_ALARM_CLOCK;
import static android.os.PowerExemptionManager.REASON_DENIED;
@@ -55,6 +58,7 @@
import static com.android.server.alarm.Alarm.EXACT_ALLOW_REASON_PRIORITIZED;
import static com.android.server.alarm.Alarm.REQUESTER_POLICY_INDEX;
import static com.android.server.alarm.Alarm.TARE_POLICY_INDEX;
+import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED;
import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_ALARM_CANCELLED;
import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_DATA_CLEARED;
import static com.android.server.alarm.AlarmManagerService.RemovedAlarm.REMOVE_REASON_EXACT_PERMISSION_REVOKED;
@@ -87,11 +91,9 @@
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.PermissionChecker;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
import android.content.pm.UserPackage;
-import android.database.ContentObserver;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.BatteryStatsInternal;
@@ -182,7 +184,6 @@
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
-import java.util.List;
import java.util.Locale;
import java.util.Set;
import java.util.TimeZone;
@@ -269,7 +270,8 @@
/**
* A map from uid to the last op-mode we have seen for
- * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}
+ * {@link AppOpsManager#OP_SCHEDULE_EXACT_ALARM}. Used for evaluating permission state change
+ * when the denylist changes.
*/
@VisibleForTesting
@GuardedBy("mLock")
@@ -738,6 +740,8 @@
"kill_on_schedule_exact_alarm_revoked";
@VisibleForTesting
static final String KEY_TEMPORARY_QUOTA_BUMP = "temporary_quota_bump";
+ @VisibleForTesting
+ static final String KEY_CACHED_LISTENER_REMOVAL_DELAY = "cached_listener_removal_delay";
private static final long DEFAULT_MIN_FUTURITY = 5 * 1000;
private static final long DEFAULT_MIN_INTERVAL = 60 * 1000;
@@ -783,6 +787,8 @@
private static final boolean DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF = true;
+ private static final long DEFAULT_CACHED_LISTENER_REMOVAL_DELAY = 10_000;
+
// Minimum futurity of a new alarm
public long MIN_FUTURITY = DEFAULT_MIN_FUTURITY;
@@ -879,6 +885,13 @@
public boolean DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF =
DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF;
+ /**
+ * Exact listener alarms for apps that get cached are removed after this duration. This is
+ * a grace period to allow for transient procstate changes, e.g., when the app switches
+ * between different lifecycles.
+ */
+ public long CACHED_LISTENER_REMOVAL_DELAY = DEFAULT_CACHED_LISTENER_REMOVAL_DELAY;
+
private long mLastAllowWhileIdleWhitelistDuration = -1;
private int mVersion = 0;
@@ -1062,6 +1075,11 @@
KEY_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF,
DEFAULT_DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF);
break;
+ case KEY_CACHED_LISTENER_REMOVAL_DELAY:
+ CACHED_LISTENER_REMOVAL_DELAY = properties.getLong(
+ KEY_CACHED_LISTENER_REMOVAL_DELAY,
+ DEFAULT_CACHED_LISTENER_REMOVAL_DELAY);
+ break;
default:
if (name.startsWith(KEY_PREFIX_STANDBY_QUOTA) && !standbyQuotaUpdated) {
// The quotas need to be updated in order, so we can't just rely
@@ -1306,6 +1324,11 @@
DELAY_NONWAKEUP_ALARMS_WHILE_SCREEN_OFF);
pw.println();
+ pw.print(KEY_CACHED_LISTENER_REMOVAL_DELAY);
+ pw.print("=");
+ TimeUtils.formatDuration(CACHED_LISTENER_REMOVAL_DELAY, pw);
+ pw.println();
+
pw.decreaseIndent();
}
@@ -2097,20 +2120,31 @@
if (oldMode == newMode) {
return;
}
- final boolean allowedByDefault =
- isScheduleExactAlarmAllowedByDefault(packageName, uid);
+ final boolean deniedByDefault = isScheduleExactAlarmDeniedByDefault(
+ packageName, UserHandle.getUserId(uid));
final boolean hadPermission;
- if (oldMode != AppOpsManager.MODE_DEFAULT) {
- hadPermission = (oldMode == AppOpsManager.MODE_ALLOWED);
- } else {
- hadPermission = allowedByDefault;
- }
final boolean hasPermission;
- if (newMode != AppOpsManager.MODE_DEFAULT) {
- hasPermission = (newMode == AppOpsManager.MODE_ALLOWED);
+
+ if (deniedByDefault) {
+ final boolean permissionState = getContext().checkPermission(
+ Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN,
+ uid) == PackageManager.PERMISSION_GRANTED;
+ hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT)
+ ? permissionState
+ : (oldMode == AppOpsManager.MODE_ALLOWED);
+ hasPermission = (newMode == AppOpsManager.MODE_DEFAULT)
+ ? permissionState
+ : (newMode == AppOpsManager.MODE_ALLOWED);
} else {
- hasPermission = allowedByDefault;
+ final boolean allowedByDefault =
+ !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName);
+ hadPermission = (oldMode == AppOpsManager.MODE_DEFAULT)
+ ? allowedByDefault
+ : (oldMode == AppOpsManager.MODE_ALLOWED);
+ hasPermission = (newMode == AppOpsManager.MODE_DEFAULT)
+ ? allowedByDefault
+ : (newMode == AppOpsManager.MODE_ALLOWED);
}
if (hadPermission && !hasPermission) {
@@ -2754,41 +2788,13 @@
boolean hasUseExactAlarmInternal(String packageName, int uid) {
return isUseExactAlarmEnabled(packageName, UserHandle.getUserId(uid))
- && (PermissionChecker.checkPermissionForPreflight(getContext(),
- Manifest.permission.USE_EXACT_ALARM, PermissionChecker.PID_UNKNOWN, uid,
- packageName) == PermissionChecker.PERMISSION_GRANTED);
- }
-
- /**
- * Returns whether SCHEDULE_EXACT_ALARM is allowed by default.
- */
- boolean isScheduleExactAlarmAllowedByDefault(String packageName, int uid) {
- if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) {
-
- // This is essentially like changing the protection level of the permission to
- // (privileged|signature|role|appop), but have to implement this logic to maintain
- // compatibility for older apps.
- if (mPackageManagerInternal.isPlatformSigned(packageName)
- || mPackageManagerInternal.isUidPrivileged(uid)) {
- return true;
- }
- final long token = Binder.clearCallingIdentity();
- try {
- final List<String> wellbeingHolders = (mRoleManager != null)
- ? mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING)
- : Collections.emptyList();
- return wellbeingHolders.contains(packageName);
- } finally {
- Binder.restoreCallingIdentity(token);
- }
- }
- return !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName);
+ && (checkPermissionForPreflight(getContext(), Manifest.permission.USE_EXACT_ALARM,
+ PID_UNKNOWN, uid, packageName) == PERMISSION_GRANTED);
}
boolean hasScheduleExactAlarmInternal(String packageName, int uid) {
final long start = mStatLogger.getTime();
- // Not using getScheduleExactAlarmState as this can avoid some calls to AppOpsService.
// Not using #mLastOpScheduleExactAlarm as it may contain stale values.
// No locking needed as all internal containers being queried are immutable.
final boolean hasPermission;
@@ -2796,11 +2802,16 @@
hasPermission = false;
} else if (!isExactAlarmChangeEnabled(packageName, UserHandle.getUserId(uid))) {
hasPermission = false;
+ } else if (isScheduleExactAlarmDeniedByDefault(packageName, UserHandle.getUserId(uid))) {
+ hasPermission = (checkPermissionForPreflight(getContext(),
+ Manifest.permission.SCHEDULE_EXACT_ALARM, PID_UNKNOWN, uid, packageName)
+ == PERMISSION_GRANTED);
} else {
+ // Compatibility permission check for older apps.
final int mode = mAppOps.checkOpNoThrow(AppOpsManager.OP_SCHEDULE_EXACT_ALARM, uid,
packageName);
if (mode == AppOpsManager.MODE_DEFAULT) {
- hasPermission = isScheduleExactAlarmAllowedByDefault(packageName, uid);
+ hasPermission = !mConstants.EXACT_ALARM_DENY_LIST.contains(packageName);
} else {
hasPermission = (mode == AppOpsManager.MODE_ALLOWED);
}
@@ -4685,10 +4696,6 @@
return service.new ClockReceiver();
}
- void registerContentObserver(ContentObserver contentObserver, Uri uri) {
- mContext.getContentResolver().registerContentObserver(uri, false, contentObserver);
- }
-
void registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener) {
DeviceConfig.addOnPropertiesChangedListener(DeviceConfig.NAMESPACE_ALARM_MANAGER,
AppSchedulingModuleThread.getExecutor(), listener);
@@ -4983,6 +4990,7 @@
public static final int TARE_AFFORDABILITY_CHANGED = 12;
public static final int CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE = 13;
public static final int TEMPORARY_QUOTA_CHANGED = 14;
+ public static final int REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED = 15;
AlarmHandler() {
super(Looper.myLooper());
@@ -5103,6 +5111,21 @@
removeExactAlarmsOnPermissionRevoked(uid, packageName, /*killUid = */false);
}
break;
+ case REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED:
+ uid = (Integer) msg.obj;
+ synchronized (mLock) {
+ removeAlarmsInternalLocked(a -> {
+ if (a.uid != uid || a.listener == null || a.windowLength != 0) {
+ return false;
+ }
+ // TODO (b/265195908): Change to .w once we have some data on breakages.
+ Slog.wtf(TAG, "Alarm " + a.listenerTag + " being removed for "
+ + UserHandle.formatUid(a.uid) + ":" + a.packageName
+ + " because the app went into cached state");
+ return true;
+ }, REMOVE_REASON_LISTENER_CACHED);
+ }
+ break;
default:
// nope, just ignore it
break;
@@ -5459,20 +5482,30 @@
}
@Override
- public void removeListenerAlarmsForCachedUid(int uid) {
+ public void handleUidCachedChanged(int uid, boolean cached) {
if (!CompatChanges.isChangeEnabled(EXACT_LISTENER_ALARMS_DROPPED_ON_CACHED, uid)) {
return;
}
+ // Apps can quickly get frozen after being cached, breaking the exactness guarantee on
+ // listener alarms. So going forward, the contract of exact listener alarms explicitly
+ // states that they will be removed as soon as the app goes out of lifecycle. We still
+ // allow a short grace period for quick shuffling of proc-states that may happen
+ // unexpectedly when switching between different lifecycles and is generally hard for
+ // apps to avoid.
+
+ final long delay;
synchronized (mLock) {
- removeAlarmsInternalLocked(a -> {
- if (a.uid != uid || a.listener == null || a.windowLength != 0) {
- return false;
- }
- // TODO (b/265195908): Change to a .w once we have some data on breakages.
- Slog.wtf(TAG, "Alarm " + a.listenerTag + " being removed for " + a.packageName
- + " because the app went into cached state");
- return true;
- }, REMOVE_REASON_LISTENER_CACHED);
+ delay = mConstants.CACHED_LISTENER_REMOVAL_DELAY;
+ }
+ final Integer uidObj = uid;
+
+ if (cached && !mHandler.hasEqualMessages(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED,
+ uidObj)) {
+ mHandler.sendMessageDelayed(
+ mHandler.obtainMessage(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED, uidObj),
+ delay);
+ } else {
+ mHandler.removeEqualMessages(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED, uidObj);
}
}
};
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
index 89eb1a9..4477e94 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobConcurrencyManager.java
@@ -1259,10 +1259,14 @@
final BackgroundStartPrivileges bsp =
activityManagerInternal.getBackgroundStartPrivileges(uid);
- final boolean balAllowed = bsp.allowsBackgroundActivityStarts();
if (DEBUG) {
- Slog.d(TAG, "Job " + job.toShortString() + " bal state: " + bsp);
+ Slog.d(TAG, "Job " + job.toShortString() + " bsp state: " + bsp);
}
+ // Intentionally use the background activity start BSP here instead of
+ // the full BAL check since the former is transient and better indicates that the
+ // user recently interacted with the app, while the latter includes
+ // permanent exceptions that don't warrant bypassing normal concurrency policy.
+ final boolean balAllowed = bsp.allowsBackgroundActivityStarts();
cachedPrivilegedState.put(uid,
balAllowed ? PRIVILEGED_STATE_BAL : PRIVILEGED_STATE_NONE);
return balAllowed;
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
index 3cc67e7..4cf9c8c 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobSchedulerService.java
@@ -31,7 +31,6 @@
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
import android.app.AppGlobals;
-import android.app.BackgroundStartPrivileges;
import android.app.IUidObserver;
import android.app.compat.CompatChanges;
import android.app.job.IJobScheduler;
@@ -429,6 +428,7 @@
public void onPropertiesChanged(DeviceConfig.Properties properties) {
boolean apiQuotaScheduleUpdated = false;
boolean concurrencyUpdated = false;
+ boolean persistenceUpdated = false;
boolean runtimeUpdated = false;
for (int controller = 0; controller < mControllers.size(); controller++) {
final StateController sc = mControllers.get(controller);
@@ -478,19 +478,23 @@
case Constants.KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS:
case Constants.KEY_RUNTIME_MIN_GUARANTEE_MS:
case Constants.KEY_RUNTIME_MIN_EJ_GUARANTEE_MS:
- case Constants.KEY_RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS:
- case Constants.KEY_RUNTIME_USER_INITIATED_LIMIT_MS:
- case Constants.KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR:
- case Constants.KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS:
- case Constants.KEY_RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS:
+ case Constants.KEY_RUNTIME_MIN_UI_GUARANTEE_MS:
+ case Constants.KEY_RUNTIME_UI_LIMIT_MS:
+ case Constants.KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR:
+ case Constants.KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS:
+ case Constants.KEY_RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS:
if (!runtimeUpdated) {
mConstants.updateRuntimeConstantsLocked();
runtimeUpdated = true;
}
break;
+ case Constants.KEY_MAX_NUM_PERSISTED_JOB_WORK_ITEMS:
case Constants.KEY_PERSIST_IN_SPLIT_FILES:
- mConstants.updatePersistingConstantsLocked();
- mJobs.setUseSplitFiles(mConstants.PERSIST_IN_SPLIT_FILES);
+ if (!persistenceUpdated) {
+ mConstants.updatePersistingConstantsLocked();
+ mJobs.setUseSplitFiles(mConstants.PERSIST_IN_SPLIT_FILES);
+ persistenceUpdated = true;
+ }
break;
default:
if (name.startsWith(JobConcurrencyManager.CONFIG_KEY_PREFIX_CONCURRENCY)
@@ -572,20 +576,20 @@
"runtime_free_quota_max_limit_ms";
private static final String KEY_RUNTIME_MIN_GUARANTEE_MS = "runtime_min_guarantee_ms";
private static final String KEY_RUNTIME_MIN_EJ_GUARANTEE_MS = "runtime_min_ej_guarantee_ms";
- private static final String KEY_RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS =
- "runtime_min_user_initiated_guarantee_ms";
- private static final String KEY_RUNTIME_USER_INITIATED_LIMIT_MS =
- "runtime_user_initiated_limit_ms";
- private static final String
- KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR =
- "runtime_min_user_initiated_data_transfer_guarantee_buffer_factor";
- private static final String KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS =
- "runtime_min_user_initiated_data_transfer_guarantee_ms";
- private static final String KEY_RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS =
- "runtime_user_initiated_data_transfer_limit_ms";
+ private static final String KEY_RUNTIME_MIN_UI_GUARANTEE_MS = "runtime_min_ui_guarantee_ms";
+ private static final String KEY_RUNTIME_UI_LIMIT_MS = "runtime_ui_limit_ms";
+ private static final String KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR =
+ "runtime_min_ui_data_transfer_guarantee_buffer_factor";
+ private static final String KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS =
+ "runtime_min_ui_data_transfer_guarantee_ms";
+ private static final String KEY_RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS =
+ "runtime_use_data_estimates_for_limits";
private static final String KEY_PERSIST_IN_SPLIT_FILES = "persist_in_split_files";
+ private static final String KEY_MAX_NUM_PERSISTED_JOB_WORK_ITEMS =
+ "max_num_persisted_job_work_items";
+
private static final int DEFAULT_MIN_READY_NON_ACTIVE_JOBS_COUNT = 5;
private static final long DEFAULT_MAX_NON_ACTIVE_JOB_BATCH_DELAY_MS = 31 * MINUTE_IN_MILLIS;
private static final float DEFAULT_HEAVY_USE_FACTOR = .9f;
@@ -610,17 +614,17 @@
public static final long DEFAULT_RUNTIME_MIN_GUARANTEE_MS = 10 * MINUTE_IN_MILLIS;
@VisibleForTesting
public static final long DEFAULT_RUNTIME_MIN_EJ_GUARANTEE_MS = 3 * MINUTE_IN_MILLIS;
- public static final long DEFAULT_RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS =
- Math.max(10 * MINUTE_IN_MILLIS, DEFAULT_RUNTIME_MIN_GUARANTEE_MS);
- public static final long DEFAULT_RUNTIME_USER_INITIATED_LIMIT_MS =
- Math.max(60 * MINUTE_IN_MILLIS, DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS);
- public static final float
- DEFAULT_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR = 1.35f;
- public static final long DEFAULT_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS =
- Math.max(10 * MINUTE_IN_MILLIS, DEFAULT_RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS);
- public static final long DEFAULT_RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS =
- Math.min(Long.MAX_VALUE, DEFAULT_RUNTIME_USER_INITIATED_LIMIT_MS);
+ public static final long DEFAULT_RUNTIME_MIN_UI_GUARANTEE_MS =
+ Math.max(6 * HOUR_IN_MILLIS, DEFAULT_RUNTIME_MIN_GUARANTEE_MS);
+ public static final long DEFAULT_RUNTIME_UI_LIMIT_MS =
+ Math.max(12 * HOUR_IN_MILLIS, DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS);
+ public static final float DEFAULT_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR =
+ 1.35f;
+ public static final long DEFAULT_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS =
+ Math.max(10 * MINUTE_IN_MILLIS, DEFAULT_RUNTIME_MIN_UI_GUARANTEE_MS);
+ public static final boolean DEFAULT_RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS = false;
static final boolean DEFAULT_PERSIST_IN_SPLIT_FILES = true;
+ static final int DEFAULT_MAX_NUM_PERSISTED_JOB_WORK_ITEMS = 100_000;
/**
* Minimum # of non-ACTIVE jobs for which the JMS will be happy running some work early.
@@ -731,33 +735,35 @@
/**
* The minimum amount of time we try to guarantee normal user-initiated jobs will run for.
*/
- public long RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS =
- DEFAULT_RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS;
+ public long RUNTIME_MIN_UI_GUARANTEE_MS = DEFAULT_RUNTIME_MIN_UI_GUARANTEE_MS;
/**
* The maximum amount of time we will let a user-initiated job run for. This will only
* apply if there are no other limits that apply to the specific user-initiated job.
*/
- public long RUNTIME_USER_INITIATED_LIMIT_MS = DEFAULT_RUNTIME_USER_INITIATED_LIMIT_MS;
+ public long RUNTIME_UI_LIMIT_MS = DEFAULT_RUNTIME_UI_LIMIT_MS;
/**
* A factor to apply to estimated transfer durations for user-initiated data transfer jobs
* so that we give some extra time for unexpected situations. This will be at least 1 and
* so can just be multiplied with the original value to get the final value.
*/
- public float RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR =
- DEFAULT_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR;
+ public float RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR =
+ DEFAULT_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR;
/**
* The minimum amount of time we try to guarantee user-initiated data transfer jobs
- * will run for.
+ * will run for. This is only considered when using data estimates to calculate
+ * execution limits.
*/
- public long RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS =
- DEFAULT_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS;
+ public long RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS =
+ DEFAULT_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS;
- /** The maximum amount of time we will let a user-initiated data transfer job run for. */
- public long RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS =
- DEFAULT_RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS;
+ /**
+ * Whether to use data estimates to determine execution limits for execution limits.
+ */
+ public boolean RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS =
+ DEFAULT_RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS;
/**
* Whether to persist jobs in split files (by UID). If false, all persisted jobs will be
@@ -766,6 +772,11 @@
public boolean PERSIST_IN_SPLIT_FILES = DEFAULT_PERSIST_IN_SPLIT_FILES;
/**
+ * The maximum number of {@link JobWorkItem JobWorkItems} that can be persisted per job.
+ */
+ public int MAX_NUM_PERSISTED_JOB_WORK_ITEMS = DEFAULT_MAX_NUM_PERSISTED_JOB_WORK_ITEMS;
+
+ /**
* If true, use TARE policy for job limiting. If false, use quotas.
*/
public boolean USE_TARE_POLICY = EconomyManager.DEFAULT_ENABLE_POLICY_JOB_SCHEDULER
@@ -827,6 +838,10 @@
private void updatePersistingConstantsLocked() {
PERSIST_IN_SPLIT_FILES = DeviceConfig.getBoolean(DeviceConfig.NAMESPACE_JOB_SCHEDULER,
KEY_PERSIST_IN_SPLIT_FILES, DEFAULT_PERSIST_IN_SPLIT_FILES);
+ MAX_NUM_PERSISTED_JOB_WORK_ITEMS = DeviceConfig.getInt(
+ DeviceConfig.NAMESPACE_JOB_SCHEDULER,
+ KEY_MAX_NUM_PERSISTED_JOB_WORK_ITEMS,
+ DEFAULT_MAX_NUM_PERSISTED_JOB_WORK_ITEMS);
}
private void updatePrefetchConstantsLocked() {
@@ -862,11 +877,11 @@
DeviceConfig.NAMESPACE_JOB_SCHEDULER,
KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
KEY_RUNTIME_MIN_GUARANTEE_MS, KEY_RUNTIME_MIN_EJ_GUARANTEE_MS,
- KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR,
- KEY_RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS,
- KEY_RUNTIME_USER_INITIATED_LIMIT_MS,
- KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS,
- KEY_RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS);
+ KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR,
+ KEY_RUNTIME_MIN_UI_GUARANTEE_MS,
+ KEY_RUNTIME_UI_LIMIT_MS,
+ KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS,
+ KEY_RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS);
// Make sure min runtime for regular jobs is at least 10 minutes.
RUNTIME_MIN_GUARANTEE_MS = Math.max(10 * MINUTE_IN_MILLIS,
@@ -880,37 +895,30 @@
properties.getLong(KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
DEFAULT_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS));
// Make sure min runtime is at least as long as regular jobs.
- RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS = Math.max(RUNTIME_MIN_GUARANTEE_MS,
+ RUNTIME_MIN_UI_GUARANTEE_MS = Math.max(RUNTIME_MIN_GUARANTEE_MS,
properties.getLong(
- KEY_RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS,
- DEFAULT_RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS));
+ KEY_RUNTIME_MIN_UI_GUARANTEE_MS, DEFAULT_RUNTIME_MIN_UI_GUARANTEE_MS));
// Max limit should be at least the min guarantee AND the free quota.
- RUNTIME_USER_INITIATED_LIMIT_MS = Math.max(RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
- Math.max(RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS,
+ RUNTIME_UI_LIMIT_MS = Math.max(RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
+ Math.max(RUNTIME_MIN_UI_GUARANTEE_MS,
properties.getLong(
- KEY_RUNTIME_USER_INITIATED_LIMIT_MS,
- DEFAULT_RUNTIME_USER_INITIATED_LIMIT_MS)));
+ KEY_RUNTIME_UI_LIMIT_MS, DEFAULT_RUNTIME_UI_LIMIT_MS)));
// The buffer factor should be at least 1 (so we don't decrease the time).
- RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR = Math.max(1,
+ RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR = Math.max(1,
properties.getFloat(
- KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR,
- DEFAULT_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR
+ KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR,
+ DEFAULT_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR
));
// Make sure min runtime is at least as long as other user-initiated jobs.
- RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS = Math.max(
- RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS,
+ RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS = Math.max(
+ RUNTIME_MIN_UI_GUARANTEE_MS,
properties.getLong(
- KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS,
- DEFAULT_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS));
- // User-initiated requires RUN_USER_INITIATED_JOBS permission, so the upper limit will
- // be higher than other jobs.
- // Max limit should be the min guarantee and the max of other user-initiated jobs.
- RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS = Math.max(
- RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS,
- Math.max(RUNTIME_USER_INITIATED_LIMIT_MS,
- properties.getLong(
- KEY_RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS,
- DEFAULT_RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS)));
+ KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS,
+ DEFAULT_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS));
+
+ RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS = properties.getBoolean(
+ KEY_RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS,
+ DEFAULT_RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS);
}
private boolean updateTareSettingsLocked(@EconomyManager.EnabledMode int enabledMode) {
@@ -958,18 +966,18 @@
pw.print(KEY_RUNTIME_MIN_EJ_GUARANTEE_MS, RUNTIME_MIN_EJ_GUARANTEE_MS).println();
pw.print(KEY_RUNTIME_FREE_QUOTA_MAX_LIMIT_MS, RUNTIME_FREE_QUOTA_MAX_LIMIT_MS)
.println();
- pw.print(KEY_RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS,
- RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS).println();
- pw.print(KEY_RUNTIME_USER_INITIATED_LIMIT_MS,
- RUNTIME_USER_INITIATED_LIMIT_MS).println();
- pw.print(KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR,
- RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR).println();
- pw.print(KEY_RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS,
- RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS).println();
- pw.print(KEY_RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS,
- RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS).println();
+ pw.print(KEY_RUNTIME_MIN_UI_GUARANTEE_MS, RUNTIME_MIN_UI_GUARANTEE_MS).println();
+ pw.print(KEY_RUNTIME_UI_LIMIT_MS, RUNTIME_UI_LIMIT_MS).println();
+ pw.print(KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR,
+ RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR).println();
+ pw.print(KEY_RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS,
+ RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS).println();
+ pw.print(KEY_RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS,
+ RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS).println();
pw.print(KEY_PERSIST_IN_SPLIT_FILES, PERSIST_IN_SPLIT_FILES).println();
+ pw.print(KEY_MAX_NUM_PERSISTED_JOB_WORK_ITEMS, MAX_NUM_PERSISTED_JOB_WORK_ITEMS)
+ .println();
pw.print(Settings.Global.ENABLE_TARE, USE_TARE_POLICY).println();
@@ -1353,6 +1361,25 @@
// Fast path: we are adding work to an existing job, and the JobInfo is not
// changing. We can just directly enqueue this work in to the job.
if (toCancel.getJob().equals(job)) {
+ // On T and below, JobWorkItem count was unlimited but they could not be
+ // persisted. Now in U and above, we allow persisting them. In both cases,
+ // there is a danger of apps adding too many JobWorkItems and causing the
+ // system to OOM since we keep everything in memory. The persisting danger
+ // is greater because it could technically lead to a boot loop if the system
+ // keeps trying to load all the JobWorkItems that led to the initial OOM.
+ // Therefore, for now (partly for app compatibility), we tackle the latter
+ // and limit the number of JobWorkItems that can be persisted.
+ // Moving forward, we should look into two things:
+ // 1. Limiting the number of unpersisted JobWorkItems
+ // 2. Offloading some state to disk so we don't keep everything in memory
+ // TODO(273758274): improve JobScheduler's resilience and memory management
+ if (toCancel.getWorkCount() >= mConstants.MAX_NUM_PERSISTED_JOB_WORK_ITEMS
+ && toCancel.isPersisted()) {
+ Slog.w(TAG, "Too many JWIs for uid " + uId);
+ throw new IllegalStateException("Apps may not persist more than "
+ + mConstants.MAX_NUM_PERSISTED_JOB_WORK_ITEMS
+ + " JobWorkItems per job");
+ }
toCancel.enqueueWorkLocked(work);
mJobs.touchJob(toCancel);
@@ -1397,6 +1424,26 @@
jobStatus.prepareLocked();
if (toCancel != null) {
+ // On T and below, JobWorkItem count was unlimited but they could not be
+ // persisted. Now in U and above, we allow persisting them. In both cases,
+ // there is a danger of apps adding too many JobWorkItems and causing the
+ // system to OOM since we keep everything in memory. The persisting danger
+ // is greater because it could technically lead to a boot loop if the system
+ // keeps trying to load all the JobWorkItems that led to the initial OOM.
+ // Therefore, for now (partly for app compatibility), we tackle the latter
+ // and limit the number of JobWorkItems that can be persisted.
+ // Moving forward, we should look into two things:
+ // 1. Limiting the number of unpersisted JobWorkItems
+ // 2. Offloading some state to disk so we don't keep everything in memory
+ // TODO(273758274): improve JobScheduler's resilience and memory management
+ if (work != null && toCancel.isPersisted()
+ && toCancel.getWorkCount() >= mConstants.MAX_NUM_PERSISTED_JOB_WORK_ITEMS) {
+ Slog.w(TAG, "Too many JWIs for uid " + uId);
+ throw new IllegalStateException("Apps may not persist more than "
+ + mConstants.MAX_NUM_PERSISTED_JOB_WORK_ITEMS
+ + " JobWorkItems per job");
+ }
+
// Implicitly replaces the existing job record with the new instance
cancelJobImplLocked(toCancel, jobStatus, JobParameters.STOP_REASON_CANCELLED_BY_APP,
JobParameters.INTERNAL_STOP_REASON_CANCELED, "job rescheduled by app");
@@ -1438,7 +1485,9 @@
/* isDeviceIdle */ false,
/* hasConnectivityConstraintSatisfied */ false,
/* hasContentTriggerConstraintSatisfied */ false,
- 0);
+ 0,
+ jobStatus.getJob().isUserInitiated(),
+ /* isRunningAsUserInitiatedJob */ false);
// If the job is immediately ready to run, then we can just immediately
// put it in the pending list and try to schedule it. This is especially
@@ -1857,7 +1906,9 @@
cancelled.isConstraintSatisfied(JobInfo.CONSTRAINT_FLAG_DEVICE_IDLE),
cancelled.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY),
cancelled.isConstraintSatisfied(JobStatus.CONSTRAINT_CONTENT_TRIGGER),
- 0);
+ 0,
+ cancelled.getJob().isUserInitiated(),
+ /* isRunningAsUserInitiatedJob */ false);
}
// If this is a replacement, bring in the new version of the job
if (incomingJob != null) {
@@ -3252,23 +3303,26 @@
if (job.shouldTreatAsUserInitiatedJob()
&& checkRunUserInitiatedJobsPermission(
job.getSourceUid(), job.getSourcePackageName())) {
- if (job.getJob().getRequiredNetwork() != null) { // UI+DT
- final long estimatedTransferTimeMs =
- mConnectivityController.getEstimatedTransferTimeMs(job);
- if (estimatedTransferTimeMs == ConnectivityController.UNKNOWN_TIME) {
- return mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS;
+ if (job.getJob().getRequiredNetwork() != null) {
+ // User-initiated data transfers.
+ if (mConstants.RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS) {
+ final long estimatedTransferTimeMs =
+ mConnectivityController.getEstimatedTransferTimeMs(job);
+ if (estimatedTransferTimeMs == ConnectivityController.UNKNOWN_TIME) {
+ return mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS;
+ }
+ // Try to give the job at least as much time as we think the transfer
+ // will take, but cap it at the maximum limit.
+ final long factoredTransferTimeMs = (long) (estimatedTransferTimeMs
+ * mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR);
+ return Math.min(mConstants.RUNTIME_UI_LIMIT_MS,
+ Math.max(factoredTransferTimeMs,
+ mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS));
}
- // Try to give the job at least as much time as we think the transfer will take,
- // but cap it at the maximum limit
- final long factoredTransferTimeMs = (long) (estimatedTransferTimeMs
- * mConstants
- .RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR);
- return Math.min(mConstants.RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS,
- Math.max(factoredTransferTimeMs,
- mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS
- ));
+ return Math.max(mConstants.RUNTIME_MIN_UI_GUARANTEE_MS,
+ mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS);
}
- return mConstants.RUNTIME_MIN_USER_INITIATED_GUARANTEE_MS;
+ return mConstants.RUNTIME_MIN_UI_GUARANTEE_MS;
} else if (job.shouldTreatAsExpeditedJob()) {
// Don't guarantee RESTRICTED jobs more than 5 minutes.
return job.getEffectiveStandbyBucket() != RESTRICTED_INDEX
@@ -3283,14 +3337,10 @@
/** Returns the maximum amount of time this job could run for. */
public long getMaxJobExecutionTimeMs(JobStatus job) {
synchronized (mLock) {
- final boolean allowLongerJob = job.shouldTreatAsUserInitiatedJob()
+ if (job.shouldTreatAsUserInitiatedJob()
&& checkRunUserInitiatedJobsPermission(
- job.getSourceUid(), job.getSourcePackageName());
- if (job.getJob().getRequiredNetwork() != null && allowLongerJob) { // UI+DT
- return mConstants.RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS;
- }
- if (allowLongerJob) { // UI with LRJ permission
- return mConstants.RUNTIME_USER_INITIATED_LIMIT_MS;
+ job.getSourceUid(), job.getSourcePackageName())) {
+ return mConstants.RUNTIME_UI_LIMIT_MS;
}
if (job.shouldTreatAsUserInitiatedJob()) {
return mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS;
@@ -3731,7 +3781,8 @@
return canPersist;
}
- private int validateJob(@NonNull JobInfo job, int callingUid, int sourceUserId,
+ private int validateJob(@NonNull JobInfo job, int callingUid, int callingPid,
+ int sourceUserId,
@Nullable String sourcePkgName, @Nullable JobWorkItem jobWorkItem) {
final boolean rejectNegativeNetworkEstimates = CompatChanges.isChangeEnabled(
JobInfo.REJECT_NEGATIVE_NETWORK_ESTIMATES, callingUid);
@@ -3764,6 +3815,8 @@
}
// We aim to check the permission of both the source and calling app so that apps
// don't attempt to bypass the permission by using other apps to do the work.
+ boolean isInStateToScheduleUiJobSource = false;
+ final String callingPkgName = job.getService().getPackageName();
if (sourceUid != -1) {
// Check the permission of the source app.
final int sourceResult =
@@ -3771,8 +3824,13 @@
if (sourceResult != JobScheduler.RESULT_SUCCESS) {
return sourceResult;
}
+ final int sourcePid =
+ callingUid == sourceUid && callingPkgName.equals(sourcePkgName)
+ ? callingPid : -1;
+ isInStateToScheduleUiJobSource = isInStateToScheduleUserInitiatedJobs(
+ sourceUid, sourcePid, sourcePkgName);
}
- final String callingPkgName = job.getService().getPackageName();
+ boolean isInStateToScheduleUiJobCalling = false;
if (callingUid != sourceUid || !callingPkgName.equals(sourcePkgName)) {
// Source app is different from calling app. Make sure the calling app also has
// the permission.
@@ -3781,25 +3839,17 @@
if (callingResult != JobScheduler.RESULT_SUCCESS) {
return callingResult;
}
+ // Avoid rechecking the state if the source app is able to schedule the job.
+ if (!isInStateToScheduleUiJobSource) {
+ isInStateToScheduleUiJobCalling = isInStateToScheduleUserInitiatedJobs(
+ callingUid, callingPid, callingPkgName);
+ }
}
- final int uid = sourceUid != -1 ? sourceUid : callingUid;
- final int procState = mActivityManagerInternal.getUidProcessState(uid);
- if (DEBUG) {
- Slog.d(TAG, "Uid " + uid + " proc state="
- + ActivityManager.procStateToString(procState));
- }
- if (procState != ActivityManager.PROCESS_STATE_TOP) {
- final BackgroundStartPrivileges bsp =
- mActivityManagerInternal.getBackgroundStartPrivileges(uid);
- if (DEBUG) {
- Slog.d(TAG, "Uid " + uid + ": " + bsp);
- }
- if (!bsp.allowsBackgroundActivityStarts()) {
- Slog.e(TAG,
- "Uid " + uid + " not in a state to schedule user-initiated jobs");
- return JobScheduler.RESULT_FAILURE;
- }
+ if (!isInStateToScheduleUiJobSource && !isInStateToScheduleUiJobCalling) {
+ Slog.e(TAG, "Uid(s) " + sourceUid + "/" + callingUid
+ + " not in a state to schedule user-initiated jobs");
+ return JobScheduler.RESULT_FAILURE;
}
}
if (jobWorkItem != null) {
@@ -3845,6 +3895,24 @@
return JobScheduler.RESULT_SUCCESS;
}
+ private boolean isInStateToScheduleUserInitiatedJobs(int uid, int pid, String pkgName) {
+ final int procState = mActivityManagerInternal.getUidProcessState(uid);
+ if (DEBUG) {
+ Slog.d(TAG, "Uid " + uid + " proc state="
+ + ActivityManager.procStateToString(procState));
+ }
+ if (procState == ActivityManager.PROCESS_STATE_TOP) {
+ return true;
+ }
+ final boolean canScheduleUiJobsInBg =
+ mActivityManagerInternal.canScheduleUserInitiatedJobs(uid, pid, pkgName);
+ if (DEBUG) {
+ Slog.d(TAG, "Uid " + uid
+ + " AM.canScheduleUserInitiatedJobs= " + canScheduleUiJobsInBg);
+ }
+ return canScheduleUiJobsInBg;
+ }
+
// IJobScheduler implementation
@Override
public int schedule(String namespace, JobInfo job) throws RemoteException {
@@ -3857,7 +3925,7 @@
enforceValidJobRequest(uid, pid, job);
- final int result = validateJob(job, uid, -1, null, null);
+ final int result = validateJob(job, uid, pid, -1, null, null);
if (result != JobScheduler.RESULT_SUCCESS) {
return result;
}
@@ -3890,7 +3958,7 @@
throw new NullPointerException("work is null");
}
- final int result = validateJob(job, uid, -1, null, work);
+ final int result = validateJob(job, uid, pid, -1, null, work);
if (result != JobScheduler.RESULT_SUCCESS) {
return result;
}
@@ -3912,6 +3980,7 @@
public int scheduleAsPackage(String namespace, JobInfo job, String packageName, int userId,
String tag) throws RemoteException {
final int callerUid = Binder.getCallingUid();
+ final int callerPid = Binder.getCallingPid();
if (DEBUG) {
Slog.d(TAG, "Caller uid " + callerUid + " scheduling job: " + job.toString()
+ " on behalf of " + packageName + "/");
@@ -3928,7 +3997,7 @@
+ " not permitted to schedule jobs for other apps");
}
- int result = validateJob(job, callerUid, userId, packageName, null);
+ int result = validateJob(job, callerUid, callerPid, userId, packageName, null);
if (result != JobScheduler.RESULT_SUCCESS) {
return result;
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
index e60ed4a..4c339ac 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobServiceContext.java
@@ -462,7 +462,9 @@
job.isConstraintSatisfied(JobInfo.CONSTRAINT_FLAG_DEVICE_IDLE),
job.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY),
job.isConstraintSatisfied(JobStatus.CONSTRAINT_CONTENT_TRIGGER),
- mExecutionStartTimeElapsed - job.enqueueTime);
+ mExecutionStartTimeElapsed - job.enqueueTime,
+ job.getJob().isUserInitiated(),
+ job.shouldTreatAsUserInitiatedJob());
if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
// Use the context's ID to distinguish traces since there'll only be one job
// running per context.
@@ -1361,7 +1363,9 @@
completedJob.isConstraintSatisfied(JobInfo.CONSTRAINT_FLAG_DEVICE_IDLE),
completedJob.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY),
completedJob.isConstraintSatisfied(JobStatus.CONSTRAINT_CONTENT_TRIGGER),
- 0);
+ 0,
+ completedJob.getJob().isUserInitiated(),
+ completedJob.startedAsUserInitiatedJob);
if (Trace.isTagEnabled(Trace.TRACE_TAG_SYSTEM_SERVER)) {
Trace.asyncTraceForTrackEnd(Trace.TRACE_TAG_SYSTEM_SERVER, "JobScheduler",
getId());
diff --git a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
index 0dcb0b245..a96a4ef 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/JobStore.java
@@ -883,6 +883,15 @@
if (job.isRequireStorageNotLow()) {
out.attribute(null, "storage-not-low", Boolean.toString(true));
}
+ if (job.isPreferBatteryNotLow()) {
+ out.attributeBoolean(null, "prefer-battery-not-low", true);
+ }
+ if (job.isPreferCharging()) {
+ out.attributeBoolean(null, "prefer-charging", true);
+ }
+ if (job.isPreferDeviceIdle()) {
+ out.attributeBoolean(null, "prefer-idle", true);
+ }
out.endTag(null, XML_TAG_PARAMS_CONSTRAINTS);
}
@@ -1538,6 +1547,13 @@
if (val != null) {
jobBuilder.setRequiresStorageNotLow(true);
}
+
+ jobBuilder.setPrefersBatteryNotLow(
+ parser.getAttributeBoolean(null, "prefer-battery-not-low", false));
+ jobBuilder.setPrefersCharging(
+ parser.getAttributeBoolean(null, "prefer-charging", false));
+ jobBuilder.setPrefersDeviceIdle(
+ parser.getAttributeBoolean(null, "prefer-idle", false));
}
/**
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
index e55bda7..3859d89 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/ConnectivityController.java
@@ -1147,10 +1147,9 @@
final boolean changed = jobStatus.setConnectivityConstraintSatisfied(nowElapsed, satisfied);
+ jobStatus.setHasAccessToUnmetered(satisfied && capabilities != null
+ && capabilities.hasCapability(NET_CAPABILITY_NOT_METERED));
if (jobStatus.getPreferUnmetered()) {
- jobStatus.setHasAccessToUnmetered(satisfied && capabilities != null
- && capabilities.hasCapability(NET_CAPABILITY_NOT_METERED));
-
jobStatus.setFlexibilityConstraintSatisfied(nowElapsed,
mFlexibilityController.isFlexibilitySatisfiedLocked(jobStatus));
}
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
index 620c48d..234a93c 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/FlexibilityController.java
@@ -239,14 +239,14 @@
return !mFlexibilityEnabled
|| mService.getUidBias(js.getSourceUid()) == JobInfo.BIAS_TOP_APP
|| mService.isCurrentlyRunningLocked(js)
- || getNumSatisfiedRequiredConstraintsLocked(js)
+ || getNumSatisfiedFlexibleConstraintsLocked(js)
>= js.getNumRequiredFlexibleConstraints();
}
@VisibleForTesting
@GuardedBy("mLock")
- int getNumSatisfiedRequiredConstraintsLocked(JobStatus js) {
- return Integer.bitCount(mSatisfiedFlexibleConstraints)
+ int getNumSatisfiedFlexibleConstraintsLocked(JobStatus js) {
+ return Integer.bitCount(mSatisfiedFlexibleConstraints & js.getPreferredConstraintFlags())
+ (js.getHasAccessToUnmetered() ? 1 : 0);
}
@@ -651,7 +651,7 @@
static final String KEY_RESCHEDULED_JOB_DEADLINE_MS =
FC_CONFIG_PREFIX + "rescheduled_job_deadline_ms";
- private static final boolean DEFAULT_FLEXIBILITY_ENABLED = false;
+ private static final boolean DEFAULT_FLEXIBILITY_ENABLED = true;
@VisibleForTesting
static final long DEFAULT_DEADLINE_PROXIMITY_LIMIT_MS = 15 * MINUTE_IN_MILLIS;
@VisibleForTesting
diff --git a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
index 537a670..17dde90 100644
--- a/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
+++ b/apex/jobscheduler/service/java/com/android/server/job/controllers/JobStatus.java
@@ -16,7 +16,6 @@
package com.android.server.job.controllers;
-import static android.net.NetworkCapabilities.NET_CAPABILITY_NOT_METERED;
import static android.text.format.DateUtils.HOUR_IN_MILLIS;
import static com.android.server.job.JobSchedulerService.ACTIVE_INDEX;
@@ -25,8 +24,6 @@
import static com.android.server.job.JobSchedulerService.RESTRICTED_INDEX;
import static com.android.server.job.JobSchedulerService.WORKING_INDEX;
import static com.android.server.job.JobSchedulerService.sElapsedRealtimeClock;
-import static com.android.server.job.controllers.FlexibilityController.NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS;
-import static com.android.server.job.controllers.FlexibilityController.SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS;
import android.annotation.ElapsedRealtimeLong;
import android.annotation.NonNull;
@@ -115,12 +112,11 @@
static final int CONSTRAINT_WITHIN_QUOTA = 1 << 24; // Implicit constraint
static final int CONSTRAINT_PREFETCH = 1 << 23;
static final int CONSTRAINT_BACKGROUND_NOT_RESTRICTED = 1 << 22; // Implicit constraint
- static final int CONSTRAINT_FLEXIBLE = 1 << 21; // Implicit constraint
+ static final int CONSTRAINT_FLEXIBLE = 1 << 21;
private static final int IMPLICIT_CONSTRAINTS = 0
| CONSTRAINT_BACKGROUND_NOT_RESTRICTED
| CONSTRAINT_DEVICE_NOT_DOZING
- | CONSTRAINT_FLEXIBLE
| CONSTRAINT_TARE_WEALTH
| CONSTRAINT_WITHIN_QUOTA;
@@ -298,6 +294,7 @@
// Constraints.
final int requiredConstraints;
+ private final int mPreferredConstraints;
private final int mRequiredConstraintsOfInterest;
int satisfiedConstraints = 0;
private int mSatisfiedConstraintsOfInterest = 0;
@@ -618,24 +615,26 @@
}
mHasExemptedMediaUrisOnly = exemptedMediaUrisOnly;
- mPreferUnmetered = job.getRequiredNetwork() != null
- && !job.getRequiredNetwork().hasCapability(NET_CAPABILITY_NOT_METERED);
+ mPreferredConstraints = job.getPreferredConstraintFlags();
- final boolean lacksSomeFlexibleConstraints =
- ((~requiredConstraints) & SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS) != 0
- || mPreferUnmetered;
+ // Exposing a preferredNetworkRequest API requires that we make sure that the preferred
+ // NetworkRequest is a subset of the required NetworkRequest. We currently don't have the
+ // code to ensure that, so disable this part for now.
+ // TODO(236261941): look into enabling flexible network constraint requests
+ mPreferUnmetered = false;
+ // && job.getRequiredNetwork() != null
+ // && !job.getRequiredNetwork().hasCapability(NET_CAPABILITY_NOT_METERED);
+
final boolean satisfiesMinWindowException =
(latestRunTimeElapsedMillis - earliestRunTimeElapsedMillis)
>= MIN_WINDOW_FOR_FLEXIBILITY_MS;
// The first time a job is rescheduled it will not be subject to flexible constraints.
// Otherwise, every consecutive reschedule increases a jobs' flexibility deadline.
- if (!isRequestedExpeditedJob() && !job.isUserInitiated()
+ if (mPreferredConstraints != 0 && !isRequestedExpeditedJob() && !job.isUserInitiated()
&& satisfiesMinWindowException
- && (numFailures + numSystemStops) != 1
- && lacksSomeFlexibleConstraints) {
- mNumRequiredFlexibleConstraints =
- NUM_SYSTEM_WIDE_FLEXIBLE_CONSTRAINTS + (mPreferUnmetered ? 1 : 0);
+ && (numFailures + numSystemStops) != 1) {
+ mNumRequiredFlexibleConstraints = Integer.bitCount(mPreferredConstraints);
requiredConstraints |= CONSTRAINT_FLEXIBLE;
} else {
mNumRequiredFlexibleConstraints = 0;
@@ -814,6 +813,13 @@
return null;
}
+ /** Returns the number of {@link JobWorkItem JobWorkItems} attached to this job. */
+ public int getWorkCount() {
+ final int pendingCount = pendingWork == null ? 0 : pendingWork.size();
+ final int executingCount = executingWork == null ? 0 : executingWork.size();
+ return pendingCount + executingCount;
+ }
+
public boolean hasWorkLocked() {
return (pendingWork != null && pendingWork.size() > 0) || hasExecutingWorkLocked();
}
@@ -1135,6 +1141,10 @@
mInternalFlags |= flags;
}
+ int getPreferredConstraintFlags() {
+ return mPreferredConstraints;
+ }
+
public int getSatisfiedConstraintFlags() {
return satisfiedConstraints;
}
@@ -2494,6 +2504,9 @@
pw.print("Required constraints:");
dumpConstraints(pw, requiredConstraints);
pw.println();
+ pw.print("Preferred constraints:");
+ dumpConstraints(pw, mPreferredConstraints);
+ pw.println();
pw.print("Dynamic constraints:");
dumpConstraints(pw, mDynamicConstraints);
pw.println();
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java b/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java
index 1ff389d..dffed0f 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/InstalledPackageInfo.java
@@ -19,6 +19,7 @@
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.UserIdInt;
import android.app.AppGlobals;
import android.content.Context;
import android.content.PermissionChecker;
@@ -41,7 +42,8 @@
@Nullable
public final String installerPackageName;
- InstalledPackageInfo(@NonNull Context context, @NonNull PackageInfo packageInfo) {
+ InstalledPackageInfo(@NonNull Context context, @UserIdInt int userId,
+ @NonNull PackageInfo packageInfo) {
final ApplicationInfo applicationInfo = packageInfo.applicationInfo;
uid = applicationInfo == null ? NO_UID : applicationInfo.uid;
packageName = packageInfo.packageName;
@@ -55,7 +57,8 @@
applicationInfo.uid, packageName);
InstallSourceInfo installSourceInfo = null;
try {
- installSourceInfo = AppGlobals.getPackageManager().getInstallSourceInfo(packageName);
+ installSourceInfo = AppGlobals.getPackageManager().getInstallSourceInfo(packageName,
+ userId);
} catch (RemoteException e) {
// Shouldn't happen.
}
diff --git a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
index caf72e8..ffb2c03 100644
--- a/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
+++ b/apex/jobscheduler/service/java/com/android/server/tare/InternalResourceService.java
@@ -625,7 +625,8 @@
mPackageToUidCache.add(userId, pkgName, uid);
}
synchronized (mLock) {
- final InstalledPackageInfo ipo = new InstalledPackageInfo(getContext(), packageInfo);
+ final InstalledPackageInfo ipo = new InstalledPackageInfo(getContext(), userId,
+ packageInfo);
final InstalledPackageInfo oldIpo = mPkgCache.add(userId, pkgName, ipo);
maybeUpdateInstallerStatusLocked(oldIpo, ipo);
mUidToPackageCache.add(uid, pkgName);
@@ -683,7 +684,7 @@
mPackageManager.getInstalledPackagesAsUser(PACKAGE_QUERY_FLAGS, userId);
for (int i = pkgs.size() - 1; i >= 0; --i) {
final InstalledPackageInfo ipo =
- new InstalledPackageInfo(getContext(), pkgs.get(i));
+ new InstalledPackageInfo(getContext(), userId, pkgs.get(i));
final InstalledPackageInfo oldIpo = mPkgCache.add(userId, ipo.packageName, ipo);
maybeUpdateInstallerStatusLocked(oldIpo, ipo);
}
@@ -963,7 +964,7 @@
mPackageManager.getInstalledPackagesAsUser(PACKAGE_QUERY_FLAGS, userId);
for (int i = pkgs.size() - 1; i >= 0; --i) {
final InstalledPackageInfo ipo =
- new InstalledPackageInfo(getContext(), pkgs.get(i));
+ new InstalledPackageInfo(getContext(), userId, pkgs.get(i));
final InstalledPackageInfo oldIpo = mPkgCache.add(userId, ipo.packageName, ipo);
maybeUpdateInstallerStatusLocked(oldIpo, ipo);
}
diff --git a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
index c3118ff..55e6815 100644
--- a/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
+++ b/apex/jobscheduler/service/java/com/android/server/usage/AppStandbyController.java
@@ -268,6 +268,10 @@
@GuardedBy("mActiveAdminApps")
private final SparseArray<Set<String>> mActiveAdminApps = new SparseArray<>();
+ /** List of admin protected packages. Can contain {@link android.os.UserHandle#USER_ALL}. */
+ @GuardedBy("mAdminProtectedPackages")
+ private final SparseArray<Set<String>> mAdminProtectedPackages = new SparseArray<>();
+
/**
* Set of system apps that are headless (don't have any "front door" activities, enabled or
* disabled). Presence in this map indicates that the app is a headless system app.
@@ -485,14 +489,6 @@
| PackageManager.MATCH_DIRECT_BOOT_AWARE
| PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
- /**
- * Whether we should allow apps into the
- * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket or not.
- * If false, any attempts to put an app into the bucket will put the app into the
- * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RARE} bucket instead.
- */
- private boolean mAllowRestrictedBucket;
-
private volatile boolean mAppIdleEnabled;
private volatile boolean mIsCharging;
private boolean mSystemServicesReady = false;
@@ -1054,13 +1050,6 @@
Slog.d(TAG, "Bringing down to RESTRICTED due to timeout");
}
}
- if (newBucket == STANDBY_BUCKET_RESTRICTED && !mAllowRestrictedBucket) {
- newBucket = STANDBY_BUCKET_RARE;
- // Leave the reason alone.
- if (DEBUG) {
- Slog.d(TAG, "Bringing up from RESTRICTED to RARE due to off switch");
- }
- }
if (newBucket > minBucket) {
newBucket = minBucket;
// Leave the reason alone.
@@ -1380,6 +1369,9 @@
synchronized (mActiveAdminApps) {
mActiveAdminApps.remove(userId);
}
+ synchronized (mAdminProtectedPackages) {
+ mAdminProtectedPackages.remove(userId);
+ }
}
}
@@ -1469,6 +1461,10 @@
return STANDBY_BUCKET_EXEMPTED;
}
+ if (isAdminProtectedPackages(packageName, userId)) {
+ return STANDBY_BUCKET_EXEMPTED;
+ }
+
if (isActiveNetworkScorer(packageName)) {
return STANDBY_BUCKET_EXEMPTED;
}
@@ -1678,7 +1674,7 @@
final int reason = (REASON_MAIN_MASK & mainReason) | (REASON_SUB_MASK & restrictReason);
final long nowElapsed = mInjector.elapsedRealtime();
- final int bucket = mAllowRestrictedBucket ? STANDBY_BUCKET_RESTRICTED : STANDBY_BUCKET_RARE;
+ final int bucket = STANDBY_BUCKET_RESTRICTED;
setAppStandbyBucket(packageName, userId, bucket, reason, nowElapsed, false);
}
@@ -1782,9 +1778,6 @@
Slog.e(TAG, "Tried to set bucket of uninstalled app: " + packageName);
return;
}
- if (newBucket == STANDBY_BUCKET_RESTRICTED && !mAllowRestrictedBucket) {
- newBucket = STANDBY_BUCKET_RARE;
- }
AppIdleHistory.AppUsageHistory app = mAppIdleHistory.getAppUsageHistory(packageName,
userId, elapsedRealtime);
boolean predicted = (reason & REASON_MAIN_MASK) == REASON_MAIN_PREDICTED;
@@ -1910,7 +1903,6 @@
+ " due to min timeout");
}
} else if (newBucket == STANDBY_BUCKET_RARE
- && mAllowRestrictedBucket
&& getBucketForLocked(packageName, userId, elapsedRealtime)
== STANDBY_BUCKET_RESTRICTED) {
// Prediction doesn't think the app will be used anytime soon and
@@ -1948,6 +1940,17 @@
}
}
+ private boolean isAdminProtectedPackages(String packageName, int userId) {
+ synchronized (mAdminProtectedPackages) {
+ if (mAdminProtectedPackages.contains(UserHandle.USER_ALL)
+ && mAdminProtectedPackages.get(UserHandle.USER_ALL).contains(packageName)) {
+ return true;
+ }
+ return mAdminProtectedPackages.contains(userId)
+ && mAdminProtectedPackages.get(userId).contains(packageName);
+ }
+ }
+
@Override
public void addActiveDeviceAdmin(String adminPkg, int userId) {
synchronized (mActiveAdminApps) {
@@ -1972,6 +1975,17 @@
}
@Override
+ public void setAdminProtectedPackages(Set<String> packageNames, int userId) {
+ synchronized (mAdminProtectedPackages) {
+ if (packageNames == null || packageNames.isEmpty()) {
+ mAdminProtectedPackages.remove(userId);
+ } else {
+ mAdminProtectedPackages.put(userId, packageNames);
+ }
+ }
+ }
+
+ @Override
public void onAdminDataAvailable() {
mAdminDataAvailableLatch.countDown();
}
@@ -1993,6 +2007,13 @@
}
}
+ @VisibleForTesting
+ Set<String> getAdminProtectedPackagesForTest(int userId) {
+ synchronized (mAdminProtectedPackages) {
+ return mAdminProtectedPackages.get(userId);
+ }
+ }
+
/**
* Returns {@code true} if the supplied package is the device provisioning app. Otherwise,
* returns {@code false}.
@@ -2489,8 +2510,6 @@
pw.println();
pw.print("mAppIdleEnabled="); pw.print(mAppIdleEnabled);
- pw.print(" mAllowRestrictedBucket=");
- pw.print(mAllowRestrictedBucket);
pw.print(" mIsCharging=");
pw.print(mIsCharging);
pw.println();
@@ -2671,12 +2690,6 @@
}
}
- boolean isRestrictedBucketEnabled() {
- return Global.getInt(mContext.getContentResolver(),
- Global.ENABLE_RESTRICTED_BUCKET,
- Global.DEFAULT_ENABLE_RESTRICTED_BUCKET) == 1;
- }
-
File getDataSystemDirectory() {
return Environment.getDataSystemDirectory();
}
@@ -3039,11 +3052,6 @@
// APP_STANDBY_ENABLED is a SystemApi that some apps may be watching, so best to
// leave it in Settings.
cr.registerContentObserver(Global.getUriFor(Global.APP_STANDBY_ENABLED), false, this);
- // Leave ENABLE_RESTRICTED_BUCKET as a user-controlled setting which will stay in
- // Settings.
- // TODO: make setting user-specific
- cr.registerContentObserver(Global.getUriFor(Global.ENABLE_RESTRICTED_BUCKET),
- false, this);
// ADAPTIVE_BATTERY_MANAGEMENT_ENABLED is a user setting, so it has to stay in Settings.
cr.registerContentObserver(Global.getUriFor(Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED),
false, this);
@@ -3244,10 +3252,6 @@
Global.ADAPTIVE_BATTERY_MANAGEMENT_ENABLED));
}
- synchronized (mAppIdleLock) {
- mAllowRestrictedBucket = mInjector.isRestrictedBucketEnabled();
- }
-
setAppIdleEnabled(mInjector.isAppIdleEnabled());
}
diff --git a/api/Android.bp b/api/Android.bp
index 73dbd28..24b3004 100644
--- a/api/Android.bp
+++ b/api/Android.bp
@@ -41,23 +41,6 @@
}
python_binary_host {
- name: "api_versions_trimmer",
- srcs: ["api_versions_trimmer.py"],
-}
-
-python_test_host {
- name: "api_versions_trimmer_unittests",
- main: "api_versions_trimmer_unittests.py",
- srcs: [
- "api_versions_trimmer_unittests.py",
- "api_versions_trimmer.py",
- ],
- test_options: {
- unit_test: true,
- },
-}
-
-python_binary_host {
name: "merge_annotation_zips",
srcs: ["merge_annotation_zips.py"],
}
diff --git a/api/api.go b/api/api.go
index 25d9728..09c2383 100644
--- a/api/api.go
+++ b/api/api.go
@@ -194,55 +194,6 @@
}
}
-func createFilteredApiVersions(ctx android.LoadHookContext, modules []string) {
- // For the filtered api versions, we prune all APIs except art module's APIs. because
- // 1) ART apis are available by default to all modules, while other module-to-module deps are
- // explicit and probably receive more scrutiny anyway
- // 2) The number of ART/libcore APIs is large, so not linting them would create a large gap
- // 3) It's a compromise. Ideally we wouldn't be filtering out any module APIs, and have
- // per-module lint databases that excludes just that module's APIs. Alas, that's more
- // difficult to achieve.
- modules = remove(modules, art)
-
- for _, i := range []struct{
- name string
- out string
- in string
- }{
- {
- // We shouldn't need public-filtered or system-filtered.
- // public-filtered is currently used to lint things that
- // use the module sdk or the system server sdk, but those
- // should be switched over to module-filtered and
- // system-server-filtered, and then public-filtered can
- // be removed.
- name: "api-versions-xml-public-filtered",
- out: "api-versions-public-filtered.xml",
- in: ":api_versions_public{.api_versions.xml}",
- }, {
- name: "api-versions-xml-module-lib-filtered",
- out: "api-versions-module-lib-filtered.xml",
- in: ":api_versions_module_lib{.api_versions.xml}",
- }, {
- name: "api-versions-xml-system-server-filtered",
- out: "api-versions-system-server-filtered.xml",
- in: ":api_versions_system_server{.api_versions.xml}",
- },
- } {
- props := genruleProps{}
- props.Name = proptools.StringPtr(i.name)
- props.Out = []string{i.out}
- // Note: order matters: first parameter is the full api-versions.xml
- // after that the stubs files in any order
- // stubs files are all modules that export API surfaces EXCEPT ART
- props.Srcs = append([]string{i.in}, createSrcs(modules, ".stubs{.jar}")...)
- props.Tools = []string{"api_versions_trimmer"}
- props.Cmd = proptools.StringPtr("$(location api_versions_trimmer) $(out) $(in)")
- props.Dists = []android.Dist{{Targets: []string{"sdk"}}}
- ctx.CreateModule(genrule.GenRuleFactory, &props, &bp2buildNotAvailable)
- }
-}
-
func createMergedPublicStubs(ctx android.LoadHookContext, modules []string) {
props := libraryProps{}
props.Name = proptools.StringPtr("all-modules-public-stubs")
@@ -395,8 +346,6 @@
createMergedAnnotationsFilegroups(ctx, bootclasspath, system_server_classpath)
- createFilteredApiVersions(ctx, bootclasspath)
-
createPublicStubsSourceFilegroup(ctx, bootclasspath)
}
@@ -418,7 +367,6 @@
// combined_apis bp2build converter
func (a *CombinedApis) ConvertWithBp2build(ctx android.TopDownMutatorContext) {
basePrefix := "non-updatable"
- scopeNames := []string{"public", "system", "module-lib", "system-server"}
scopeToSuffix := map[string]string{
"public": "-current.txt",
"system": "-system-current.txt",
@@ -426,8 +374,7 @@
"system-server": "-system-server-current.txt",
}
- for _, scopeName := range scopeNames{
- suffix := scopeToSuffix[scopeName]
+ for scopeName, suffix := range scopeToSuffix{
name := a.Name() + suffix
var scope bazel.StringAttribute
diff --git a/api/api_versions_trimmer.py b/api/api_versions_trimmer.py
deleted file mode 100755
index 9afd95a..0000000
--- a/api/api_versions_trimmer.py
+++ /dev/null
@@ -1,136 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-"""Script to remove mainline APIs from the api-versions.xml."""
-
-import argparse
-import re
-import xml.etree.ElementTree as ET
-import zipfile
-
-
-def read_classes(stubs):
- """Read classes from the stubs file.
-
- Args:
- stubs: argument can be a path to a file (a string), a file-like object or a
- path-like object
-
- Returns:
- a set of the classes found in the file (set of strings)
- """
- classes = set()
- with zipfile.ZipFile(stubs) as z:
- for info in z.infolist():
- if (not info.is_dir()
- and info.filename.endswith(".class")
- and not info.filename.startswith("META-INF")):
- # drop ".class" extension
- classes.add(info.filename[:-6])
- return classes
-
-
-def filter_method_tag(method, classes_to_remove):
- """Updates the signature of this method by calling filter_method_signature.
-
- Updates the method passed into this function.
-
- Args:
- method: xml element that represents a method
- classes_to_remove: set of classes you to remove
- """
- filtered = filter_method_signature(method.get("name"), classes_to_remove)
- method.set("name", filtered)
-
-
-def filter_method_signature(signature, classes_to_remove):
- """Removes mentions of certain classes from this method signature.
-
- Replaces any existing classes that need to be removed, with java/lang/Object
-
- Args:
- signature: string that is a java representation of a method signature
- classes_to_remove: set of classes you to remove
- """
- regex = re.compile("L.*?;")
- start = signature.find("(")
- matches = set(regex.findall(signature[start:]))
- for m in matches:
- # m[1:-1] to drop the leading `L` and `;` ending
- if m[1:-1] in classes_to_remove:
- signature = signature.replace(m, "Ljava/lang/Object;")
- return signature
-
-
-def filter_lint_database(database, classes_to_remove, output):
- """Reads a lint database and writes a filtered version without some classes.
-
- Reads database from api-versions.xml and removes any references to classes
- in the second argument. Writes the result (another xml with the same format
- of the database) to output.
-
- Args:
- database: path to xml with lint database to read
- classes_to_remove: iterable (ideally a set or similar for quick
- lookups) that enumerates the classes that should be removed
- output: path to write the filtered database
- """
- xml = ET.parse(database)
- root = xml.getroot()
- for c in xml.findall("class"):
- cname = c.get("name")
- if cname in classes_to_remove:
- root.remove(c)
- else:
- # find the <extends /> tag inside this class to see if the parent
- # has been removed from the known classes (attribute called name)
- super_classes = c.findall("extends")
- for super_class in super_classes:
- super_class_name = super_class.get("name")
- if super_class_name in classes_to_remove:
- super_class.set("name", "java/lang/Object")
- interfaces = c.findall("implements")
- for interface in interfaces:
- interface_name = interface.get("name")
- if interface_name in classes_to_remove:
- c.remove(interface)
- for method in c.findall("method"):
- filter_method_tag(method, classes_to_remove)
- xml.write(output)
-
-
-def main():
- """Run the program."""
- parser = argparse.ArgumentParser(
- description=
- ("Read a lint database (api-versions.xml) and many stubs jar files. "
- "Produce another database file that doesn't include the classes present "
- "in the stubs file(s)."))
- parser.add_argument("output", help="Destination of the result (xml file).")
- parser.add_argument(
- "api_versions",
- help="The lint database (api-versions.xml file) to read data from"
- )
- parser.add_argument("stubs", nargs="+", help="The stubs jar file(s)")
- parsed = parser.parse_args()
- classes = set()
- for stub in parsed.stubs:
- classes.update(read_classes(stub))
- filter_lint_database(parsed.api_versions, classes, parsed.output)
-
-
-if __name__ == "__main__":
- main()
diff --git a/api/api_versions_trimmer_unittests.py b/api/api_versions_trimmer_unittests.py
deleted file mode 100644
index d2e5b7d..0000000
--- a/api/api_versions_trimmer_unittests.py
+++ /dev/null
@@ -1,307 +0,0 @@
-#!/usr/bin/env python3
-#
-# Copyright (C) 2021 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import io
-import re
-import unittest
-import xml.etree.ElementTree as ET
-import zipfile
-
-import api_versions_trimmer
-
-
-def create_in_memory_zip_file(files):
- f = io.BytesIO()
- with zipfile.ZipFile(f, "w") as z:
- for fname in files:
- with z.open(fname, mode="w") as class_file:
- class_file.write(b"")
- return f
-
-
-def indent(elem, level=0):
- i = "\n" + level * " "
- j = "\n" + (level - 1) * " "
- if len(elem):
- if not elem.text or not elem.text.strip():
- elem.text = i + " "
- if not elem.tail or not elem.tail.strip():
- elem.tail = i
- for subelem in elem:
- indent(subelem, level + 1)
- if not elem.tail or not elem.tail.strip():
- elem.tail = j
- else:
- if level and (not elem.tail or not elem.tail.strip()):
- elem.tail = j
- return elem
-
-
-def pretty_print(s):
- tree = ET.parse(io.StringIO(s))
- el = indent(tree.getroot())
- res = ET.tostring(el).decode("utf-8")
- # remove empty lines inside the result because this still breaks some
- # comparisons
- return re.sub(r"\n\s*\n", "\n", res, re.MULTILINE)
-
-
-class ApiVersionsTrimmerUnittests(unittest.TestCase):
-
- def setUp(self):
- # so it prints diffs in long strings (xml files)
- self.maxDiff = None
-
- def test_read_classes(self):
- f = create_in_memory_zip_file(
- ["a/b/C.class",
- "a/b/D.class",
- ]
- )
- res = api_versions_trimmer.read_classes(f)
- self.assertEqual({"a/b/C", "a/b/D"}, res)
-
- def test_read_classes_ignore_dex(self):
- f = create_in_memory_zip_file(
- ["a/b/C.class",
- "a/b/D.class",
- "a/b/E.dex",
- "f.dex",
- ]
- )
- res = api_versions_trimmer.read_classes(f)
- self.assertEqual({"a/b/C", "a/b/D"}, res)
-
- def test_read_classes_ignore_manifest(self):
- f = create_in_memory_zip_file(
- ["a/b/C.class",
- "a/b/D.class",
- "META-INFO/G.class"
- ]
- )
- res = api_versions_trimmer.read_classes(f)
- self.assertEqual({"a/b/C", "a/b/D"}, res)
-
- def test_filter_method_signature(self):
- xml = """
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
- """
- method = ET.fromstring(xml)
- classes_to_remove = {"android/accessibilityservice/GestureDescription"}
- expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
- api_versions_trimmer.filter_method_tag(method, classes_to_remove)
- self.assertEqual(expected, method.get("name"))
-
- def test_filter_method_signature_with_L_in_method(self):
- xml = """
- <method name="dispatchLeftGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
- """
- method = ET.fromstring(xml)
- classes_to_remove = {"android/accessibilityservice/GestureDescription"}
- expected = "dispatchLeftGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
- api_versions_trimmer.filter_method_tag(method, classes_to_remove)
- self.assertEqual(expected, method.get("name"))
-
- def test_filter_method_signature_with_L_in_class(self):
- xml = """
- <method name="dispatchGesture(Landroid/accessibilityservice/LeftGestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
- """
- method = ET.fromstring(xml)
- classes_to_remove = {"android/accessibilityservice/LeftGestureDescription"}
- expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
- api_versions_trimmer.filter_method_tag(method, classes_to_remove)
- self.assertEqual(expected, method.get("name"))
-
- def test_filter_method_signature_with_inner_class(self):
- xml = """
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription$Inner;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z" since="24"/>
- """
- method = ET.fromstring(xml)
- classes_to_remove = {"android/accessibilityservice/GestureDescription$Inner"}
- expected = "dispatchGesture(Ljava/lang/Object;Landroid/accessibilityservice/AccessibilityService$GestureResultCallback;Landroid/os/Handler;)Z"
- api_versions_trimmer.filter_method_tag(method, classes_to_remove)
- self.assertEqual(expected, method.get("name"))
-
- def _run_filter_db_test(self, database_str, expected):
- """Performs the pattern of testing the filter_lint_database method.
-
- Filters instances of the class "a/b/C" (hard-coded) from the database string
- and compares the result with the expected result (performs formatting of
- the xml of both inputs)
-
- Args:
- database_str: string, the contents of the lint database (api-versions.xml)
- expected: string, the expected result after filtering the original
- database
- """
- database = io.StringIO(database_str)
- classes_to_remove = {"a/b/C"}
- output = io.BytesIO()
- api_versions_trimmer.filter_lint_database(
- database,
- classes_to_remove,
- output
- )
- expected = pretty_print(expected)
- res = pretty_print(output.getvalue().decode("utf-8"))
- self.assertEqual(expected, res)
-
- def test_filter_lint_database_updates_method_signature_params(self):
- self._run_filter_db_test(
- database_str="""
- <api version="2">
- <!-- will be removed -->
- <class name="a/b/C" since="1">
- <extends name="java/lang/Object"/>
- </class>
-
- <class name="a/b/E" since="1">
- <!-- extends will be modified -->
- <extends name="a/b/C"/>
- <!-- first parameter will be modified -->
- <method name="dispatchGesture(La/b/C;Landroid/os/Handler;)Z" since="24"/>
- <!-- second should remain untouched -->
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
- </class>
- </api>
- """,
- expected="""
- <api version="2">
- <class name="a/b/E" since="1">
- <extends name="java/lang/Object"/>
- <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/>
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
- </class>
- </api>
- """)
-
- def test_filter_lint_database_updates_method_signature_return(self):
- self._run_filter_db_test(
- database_str="""
- <api version="2">
- <!-- will be removed -->
- <class name="a/b/C" since="1">
- <extends name="java/lang/Object"/>
- </class>
-
- <class name="a/b/E" since="1">
- <!-- extends will be modified -->
- <extends name="a/b/C"/>
- <!-- return type should be changed -->
- <method name="gestureIdToString(I)La/b/C;" since="24"/>
- </class>
- </api>
- """,
- expected="""
- <api version="2">
- <class name="a/b/E" since="1">
-
- <extends name="java/lang/Object"/>
-
- <method name="gestureIdToString(I)Ljava/lang/Object;" since="24"/>
- </class>
- </api>
- """)
-
- def test_filter_lint_database_removes_implements(self):
- self._run_filter_db_test(
- database_str="""
- <api version="2">
- <!-- will be removed -->
- <class name="a/b/C" since="1">
- <extends name="java/lang/Object"/>
- </class>
-
- <class name="a/b/D" since="1">
- <extends name="java/lang/Object"/>
- <implements name="a/b/C"/>
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
- </class>
- </api>
- """,
- expected="""
- <api version="2">
-
- <class name="a/b/D" since="1">
- <extends name="java/lang/Object"/>
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
- </class>
- </api>
- """)
-
- def test_filter_lint_database_updates_extends(self):
- self._run_filter_db_test(
- database_str="""
- <api version="2">
- <!-- will be removed -->
- <class name="a/b/C" since="1">
- <extends name="java/lang/Object"/>
- </class>
-
- <class name="a/b/E" since="1">
- <!-- extends will be modified -->
- <extends name="a/b/C"/>
- <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/>
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
- </class>
- </api>
- """,
- expected="""
- <api version="2">
- <class name="a/b/E" since="1">
- <extends name="java/lang/Object"/>
- <method name="dispatchGesture(Ljava/lang/Object;Landroid/os/Handler;)Z" since="24"/>
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
- </class>
- </api>
- """)
-
- def test_filter_lint_database_removes_class(self):
- self._run_filter_db_test(
- database_str="""
- <api version="2">
- <!-- will be removed -->
- <class name="a/b/C" since="1">
- <extends name="java/lang/Object"/>
- </class>
-
- <class name="a/b/D" since="1">
- <extends name="java/lang/Object"/>
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
- </class>
- </api>
- """,
- expected="""
- <api version="2">
-
- <class name="a/b/D" since="1">
- <extends name="java/lang/Object"/>
- <method name="dispatchGesture(Landroid/accessibilityservice/GestureDescription;Landroid/accessibilityservice/AccessibilityService$GestureRe
-sultCallback;Landroid/os/Handler;)Z" since="24"/>
- </class>
- </api>
- """)
-
-
-if __name__ == "__main__":
- unittest.main(verbosity=2)
diff --git a/cmds/bootanimation/BootAnimation.cpp b/cmds/bootanimation/BootAnimation.cpp
index 00d9a4b..c4e8b0e 100644
--- a/cmds/bootanimation/BootAnimation.cpp
+++ b/cmds/bootanimation/BootAnimation.cpp
@@ -458,6 +458,7 @@
EGLConfig BootAnimation::getEglConfig(const EGLDisplay& display) {
const EGLint attribs[] = {
+ EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT,
EGL_RED_SIZE, 8,
EGL_GREEN_SIZE, 8,
EGL_BLUE_SIZE, 8,
diff --git a/cmds/svc/src/com/android/commands/svc/PowerCommand.java b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
index 957ebfb..a7560b2 100644
--- a/cmds/svc/src/com/android/commands/svc/PowerCommand.java
+++ b/cmds/svc/src/com/android/commands/svc/PowerCommand.java
@@ -40,7 +40,7 @@
public String longHelp() {
return shortHelp() + "\n"
+ "\n"
- + "usage: svc power stayon [true|false|usb|ac|wireless]\n"
+ + "usage: svc power stayon [true|false|usb|ac|wireless|dock]\n"
+ " Set the 'keep awake while plugged in' setting.\n"
+ " svc power reboot [reason]\n"
+ " Perform a runtime shutdown and reboot device with specified reason.\n"
@@ -66,9 +66,10 @@
if ("stayon".equals(args[1]) && args.length == 3) {
int val;
if ("true".equals(args[2])) {
- val = BatteryManager.BATTERY_PLUGGED_AC |
- BatteryManager.BATTERY_PLUGGED_USB |
- BatteryManager.BATTERY_PLUGGED_WIRELESS;
+ val = BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS
+ | BatteryManager.BATTERY_PLUGGED_DOCK;
}
else if ("false".equals(args[2])) {
val = 0;
@@ -78,6 +79,8 @@
val = BatteryManager.BATTERY_PLUGGED_AC;
} else if ("wireless".equals(args[2])) {
val = BatteryManager.BATTERY_PLUGGED_WIRELESS;
+ } else if ("dock".equals(args[2])) {
+ val = BatteryManager.BATTERY_PLUGGED_DOCK;
} else {
break fail;
}
diff --git a/core/api/current.txt b/core/api/current.txt
index facb4b2..881a677 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -83,6 +83,7 @@
field public static final String CLEAR_APP_CACHE = "android.permission.CLEAR_APP_CACHE";
field public static final String CONFIGURE_WIFI_DISPLAY = "android.permission.CONFIGURE_WIFI_DISPLAY";
field public static final String CONTROL_LOCATION_UPDATES = "android.permission.CONTROL_LOCATION_UPDATES";
+ field public static final String CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS = "android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS";
field public static final String CREDENTIAL_MANAGER_SET_ORIGIN = "android.permission.CREDENTIAL_MANAGER_SET_ORIGIN";
field public static final String DELETE_CACHE_FILES = "android.permission.DELETE_CACHE_FILES";
field public static final String DELETE_PACKAGES = "android.permission.DELETE_PACKAGES";
@@ -224,6 +225,7 @@
field @Deprecated public static final String PERSISTENT_ACTIVITY = "android.permission.PERSISTENT_ACTIVITY";
field public static final String POST_NOTIFICATIONS = "android.permission.POST_NOTIFICATIONS";
field @Deprecated public static final String PROCESS_OUTGOING_CALLS = "android.permission.PROCESS_OUTGOING_CALLS";
+ field public static final String PROVIDE_OWN_AUTOFILL_SUGGESTIONS = "android.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS";
field public static final String PROVIDE_REMOTE_CREDENTIALS = "android.permission.PROVIDE_REMOTE_CREDENTIALS";
field public static final String QUERY_ALL_PACKAGES = "android.permission.QUERY_ALL_PACKAGES";
field public static final String READ_ASSISTANT_APP_SEARCH_DATA = "android.permission.READ_ASSISTANT_APP_SEARCH_DATA";
@@ -2033,6 +2035,8 @@
field public static final int system_on_tertiary_light;
field public static final int system_outline_dark;
field public static final int system_outline_light;
+ field public static final int system_outline_variant_dark;
+ field public static final int system_outline_variant_light;
field public static final int system_palette_key_color_neutral_dark;
field public static final int system_palette_key_color_neutral_light;
field public static final int system_palette_key_color_neutral_variant_dark;
@@ -5271,18 +5275,15 @@
public class BroadcastOptions {
method public void clearDeferralPolicy();
- method public void clearDeliveryGroupMatchingFilter();
method public void clearDeliveryGroupMatchingKey();
method public void clearDeliveryGroupPolicy();
method @NonNull public static android.app.BroadcastOptions fromBundle(@NonNull android.os.Bundle);
method public int getDeferralPolicy();
- method @Nullable public android.content.IntentFilter getDeliveryGroupMatchingFilter();
method @Nullable public String getDeliveryGroupMatchingKey();
method public int getDeliveryGroupPolicy();
method public boolean isShareIdentityEnabled();
method @NonNull public static android.app.BroadcastOptions makeBasic();
method @NonNull public android.app.BroadcastOptions setDeferralPolicy(int);
- method @NonNull public android.app.BroadcastOptions setDeliveryGroupMatchingFilter(@NonNull android.content.IntentFilter);
method @NonNull public android.app.BroadcastOptions setDeliveryGroupMatchingKey(@NonNull String, @NonNull String);
method @NonNull public android.app.BroadcastOptions setDeliveryGroupPolicy(int);
method @NonNull public android.app.BroadcastOptions setShareIdentityEnabled(boolean);
@@ -6613,6 +6614,7 @@
ctor public Notification.MediaStyle();
ctor @Deprecated public Notification.MediaStyle(android.app.Notification.Builder);
method public android.app.Notification.MediaStyle setMediaSession(android.media.session.MediaSession.Token);
+ method @NonNull @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public android.app.Notification.MediaStyle setRemotePlaybackInfo(@NonNull CharSequence, @DrawableRes int, @Nullable android.app.PendingIntent);
method public android.app.Notification.MediaStyle setShowActionsInCompactView(int...);
}
@@ -6659,6 +6661,21 @@
field protected android.app.Notification.Builder mBuilder;
}
+ public static final class Notification.TvExtender implements android.app.Notification.Extender {
+ ctor public Notification.TvExtender();
+ ctor public Notification.TvExtender(@NonNull android.app.Notification);
+ method @NonNull public android.app.Notification.Builder extend(@NonNull android.app.Notification.Builder);
+ method @Nullable public String getChannelId();
+ method @Nullable public android.app.PendingIntent getContentIntent();
+ method @Nullable public android.app.PendingIntent getDeleteIntent();
+ method public boolean isAvailableOnTv();
+ method public boolean isSuppressShowOverApps();
+ method @NonNull public android.app.Notification.TvExtender setChannelId(@Nullable String);
+ method @NonNull public android.app.Notification.TvExtender setContentIntent(@Nullable android.app.PendingIntent);
+ method @NonNull public android.app.Notification.TvExtender setDeleteIntent(@Nullable android.app.PendingIntent);
+ method @NonNull public android.app.Notification.TvExtender setSuppressShowOverApps(boolean);
+ }
+
public static final class Notification.WearableExtender implements android.app.Notification.Extender {
ctor public Notification.WearableExtender();
ctor public Notification.WearableExtender(android.app.Notification);
@@ -6933,6 +6950,7 @@
method public void send() throws android.app.PendingIntent.CanceledException;
method public void send(int) throws android.app.PendingIntent.CanceledException;
method public void send(android.content.Context, int, @Nullable android.content.Intent) throws android.app.PendingIntent.CanceledException;
+ method public void send(@Nullable android.os.Bundle) throws android.app.PendingIntent.CanceledException;
method public void send(int, @Nullable android.app.PendingIntent.OnFinished, @Nullable android.os.Handler) throws android.app.PendingIntent.CanceledException;
method public void send(android.content.Context, int, @Nullable android.content.Intent, @Nullable android.app.PendingIntent.OnFinished, @Nullable android.os.Handler) throws android.app.PendingIntent.CanceledException;
method public void send(android.content.Context, int, @Nullable android.content.Intent, @Nullable android.app.PendingIntent.OnFinished, @Nullable android.os.Handler, @Nullable String) throws android.app.PendingIntent.CanceledException;
@@ -7565,23 +7583,23 @@
method public android.content.Intent getCropAndSetWallpaperIntent(android.net.Uri);
method public int getDesiredMinimumHeight();
method public int getDesiredMinimumWidth();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public android.graphics.drawable.Drawable getDrawable();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public android.graphics.drawable.Drawable getDrawable(int);
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public android.graphics.drawable.Drawable getFastDrawable();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public android.graphics.drawable.Drawable getFastDrawable(int);
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_EXTERNAL_STORAGE, "android.permission.READ_WALLPAPER_INTERNAL"}) public android.graphics.drawable.Drawable getDrawable();
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_EXTERNAL_STORAGE, "android.permission.READ_WALLPAPER_INTERNAL"}) public android.graphics.drawable.Drawable getDrawable(int);
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_EXTERNAL_STORAGE, "android.permission.READ_WALLPAPER_INTERNAL"}) public android.graphics.drawable.Drawable getFastDrawable();
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_EXTERNAL_STORAGE, "android.permission.READ_WALLPAPER_INTERNAL"}) public android.graphics.drawable.Drawable getFastDrawable(int);
method public static android.app.WallpaperManager getInstance(android.content.Context);
method @Nullable public android.app.WallpaperColors getWallpaperColors(int);
- method @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public android.os.ParcelFileDescriptor getWallpaperFile(int);
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_EXTERNAL_STORAGE, "android.permission.READ_WALLPAPER_INTERNAL"}) public android.os.ParcelFileDescriptor getWallpaperFile(int);
method public int getWallpaperId(int);
method public android.app.WallpaperInfo getWallpaperInfo();
method @Nullable public android.app.WallpaperInfo getWallpaperInfo(int);
method public boolean hasResourceWallpaper(@RawRes int);
method public boolean isSetWallpaperAllowed();
method public boolean isWallpaperSupported();
- method @Nullable public android.graphics.drawable.Drawable peekDrawable();
- method @Nullable public android.graphics.drawable.Drawable peekDrawable(int);
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public android.graphics.drawable.Drawable peekFastDrawable();
- method @Nullable @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public android.graphics.drawable.Drawable peekFastDrawable(int);
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_EXTERNAL_STORAGE, "android.permission.READ_WALLPAPER_INTERNAL"}) public android.graphics.drawable.Drawable peekDrawable();
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_EXTERNAL_STORAGE, "android.permission.READ_WALLPAPER_INTERNAL"}) public android.graphics.drawable.Drawable peekDrawable(int);
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_EXTERNAL_STORAGE, "android.permission.READ_WALLPAPER_INTERNAL"}) public android.graphics.drawable.Drawable peekFastDrawable();
+ method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_EXTERNAL_STORAGE, "android.permission.READ_WALLPAPER_INTERNAL"}) public android.graphics.drawable.Drawable peekFastDrawable(int);
method public void removeOnColorsChangedListener(@NonNull android.app.WallpaperManager.OnColorsChangedListener);
method public void sendWallpaperCommand(android.os.IBinder, String, int, int, int, android.os.Bundle);
method @RequiresPermission(android.Manifest.permission.SET_WALLPAPER) public void setBitmap(android.graphics.Bitmap) throws java.io.IOException;
@@ -7884,6 +7902,7 @@
method @Deprecated public boolean isCallerApplicationRestrictionsManagingPackage();
method public boolean isCommonCriteriaModeEnabled(@Nullable android.content.ComponentName);
method public boolean isComplianceAcknowledgementRequired();
+ method public boolean isDeviceFinanced();
method public boolean isDeviceIdAttestationSupported();
method public boolean isDeviceOwnerApp(String);
method public boolean isEphemeralUser(@NonNull android.content.ComponentName);
@@ -8039,6 +8058,7 @@
field public static final String ACTION_APPLICATION_DELEGATION_SCOPES_CHANGED = "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED";
field public static final String ACTION_CHECK_POLICY_COMPLIANCE = "android.app.action.CHECK_POLICY_COMPLIANCE";
field public static final String ACTION_DEVICE_ADMIN_SERVICE = "android.app.action.DEVICE_ADMIN_SERVICE";
+ field public static final String ACTION_DEVICE_FINANCING_STATE_CHANGED = "android.app.admin.action.DEVICE_FINANCING_STATE_CHANGED";
field public static final String ACTION_DEVICE_OWNER_CHANGED = "android.app.action.DEVICE_OWNER_CHANGED";
field public static final String ACTION_DEVICE_POLICY_RESOURCE_UPDATED = "android.app.action.DEVICE_POLICY_RESOURCE_UPDATED";
field public static final String ACTION_GET_PROVISIONING_MODE = "android.app.action.GET_PROVISIONING_MODE";
@@ -11175,7 +11195,6 @@
method public final String getDataScheme(int);
method public final android.os.PatternMatcher getDataSchemeSpecificPart(int);
method public final String getDataType(int);
- method @NonNull public final android.os.PersistableBundle getExtras();
method public final int getPriority();
method public final boolean hasAction(String);
method public final boolean hasCategory(String);
@@ -11194,7 +11213,6 @@
method public void readFromXml(org.xmlpull.v1.XmlPullParser) throws java.io.IOException, org.xmlpull.v1.XmlPullParserException;
method public final java.util.Iterator<android.os.PatternMatcher> schemeSpecificPartsIterator();
method public final java.util.Iterator<java.lang.String> schemesIterator();
- method public final void setExtras(@NonNull android.os.PersistableBundle);
method public final void setPriority(int);
method public final java.util.Iterator<java.lang.String> typesIterator();
method public final void writeToParcel(android.os.Parcel, int);
@@ -13660,8 +13678,9 @@
}
public final class CredentialOption implements android.os.Parcelable {
- ctor public CredentialOption(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.Bundle, boolean);
+ ctor @Deprecated public CredentialOption(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.Bundle, boolean);
method public int describeContents();
+ method @NonNull public java.util.Set<android.content.ComponentName> getAllowedProviders();
method @NonNull public android.os.Bundle getCandidateQueryData();
method @NonNull public android.os.Bundle getCredentialRetrievalData();
method @NonNull public String getType();
@@ -13671,6 +13690,14 @@
field public static final String FLATTENED_REQUEST = "android.credentials.GetCredentialOption.FLATTENED_REQUEST_STRING";
}
+ public static final class CredentialOption.Builder {
+ ctor public CredentialOption.Builder(@NonNull String, @NonNull android.os.Bundle, @NonNull android.os.Bundle);
+ method @NonNull public android.credentials.CredentialOption.Builder addAllowedProvider(@NonNull android.content.ComponentName);
+ method @NonNull public android.credentials.CredentialOption build();
+ method @NonNull public android.credentials.CredentialOption.Builder setAllowedProviders(@NonNull java.util.Set<android.content.ComponentName>);
+ method @NonNull public android.credentials.CredentialOption.Builder setIsSystemProviderRequired(boolean);
+ }
+
public class GetCredentialException extends java.lang.Exception {
ctor public GetCredentialException(@NonNull String, @Nullable String);
ctor public GetCredentialException(@NonNull String, @Nullable String, @Nullable Throwable);
@@ -18756,7 +18783,6 @@
field public static final int CONTROL_AF_TRIGGER_CANCEL = 2; // 0x2
field public static final int CONTROL_AF_TRIGGER_IDLE = 0; // 0x0
field public static final int CONTROL_AF_TRIGGER_START = 1; // 0x1
- field public static final int CONTROL_AUTOFRAMING_AUTO = 2; // 0x2
field public static final int CONTROL_AUTOFRAMING_OFF = 0; // 0x0
field public static final int CONTROL_AUTOFRAMING_ON = 1; // 0x1
field public static final int CONTROL_AUTOFRAMING_STATE_CONVERGED = 2; // 0x2
@@ -27336,9 +27362,13 @@
field public static final int TIME_SHIFT_STATUS_UNAVAILABLE = 2; // 0x2
field public static final int TIME_SHIFT_STATUS_UNKNOWN = 0; // 0x0
field public static final int TIME_SHIFT_STATUS_UNSUPPORTED = 1; // 0x1
+ field public static final long TV_MESSAGE_GROUP_ID_NONE = -1L; // 0xffffffffffffffffL
+ field public static final String TV_MESSAGE_KEY_GROUP_ID = "android.media.tv.TvInputManager.group_id";
field public static final String TV_MESSAGE_KEY_RAW_DATA = "android.media.tv.TvInputManager.raw_data";
field public static final String TV_MESSAGE_KEY_STREAM_ID = "android.media.tv.TvInputManager.stream_id";
field public static final String TV_MESSAGE_KEY_SUBTYPE = "android.media.tv.TvInputManager.subtype";
+ field public static final String TV_MESSAGE_SUBTYPE_CC_608E = "CTA 608-E";
+ field public static final String TV_MESSAGE_SUBTYPE_WATERMARKING_A335 = "ATSC A/335";
field public static final int TV_MESSAGE_TYPE_CLOSED_CAPTION = 2; // 0x2
field public static final int TV_MESSAGE_TYPE_OTHER = 1000; // 0x3e8
field public static final int TV_MESSAGE_TYPE_WATERMARK = 1; // 0x1
@@ -27468,7 +27498,7 @@
method public boolean onTrackballEvent(android.view.MotionEvent);
method public abstract boolean onTune(android.net.Uri);
method public boolean onTune(android.net.Uri, android.os.Bundle);
- method public void onTvMessage(@NonNull String, @NonNull android.os.Bundle);
+ method public void onTvMessage(int, @NonNull android.os.Bundle);
method public void onUnblockContent(android.media.tv.TvContentRating);
method public void setOverlayViewEnabled(boolean);
}
@@ -37071,6 +37101,7 @@
field public static final String ACTION_CAST_SETTINGS = "android.settings.CAST_SETTINGS";
field public static final String ACTION_CHANNEL_NOTIFICATION_SETTINGS = "android.settings.CHANNEL_NOTIFICATION_SETTINGS";
field public static final String ACTION_CONDITION_PROVIDER_SETTINGS = "android.settings.ACTION_CONDITION_PROVIDER_SETTINGS";
+ field public static final String ACTION_CREDENTIAL_PROVIDER = "android.settings.CREDENTIAL_PROVIDER";
field public static final String ACTION_DATA_ROAMING_SETTINGS = "android.settings.DATA_ROAMING_SETTINGS";
field public static final String ACTION_DATA_USAGE_SETTINGS = "android.settings.DATA_USAGE_SETTINGS";
field public static final String ACTION_DATE_SETTINGS = "android.settings.DATE_SETTINGS";
@@ -50876,6 +50907,10 @@
field public static final int KEYCODE_LAST_CHANNEL = 229; // 0xe5
field public static final int KEYCODE_LEFT_BRACKET = 71; // 0x47
field public static final int KEYCODE_M = 41; // 0x29
+ field public static final int KEYCODE_MACRO_1 = 313; // 0x139
+ field public static final int KEYCODE_MACRO_2 = 314; // 0x13a
+ field public static final int KEYCODE_MACRO_3 = 315; // 0x13b
+ field public static final int KEYCODE_MACRO_4 = 316; // 0x13c
field public static final int KEYCODE_MANNER_MODE = 205; // 0xcd
field public static final int KEYCODE_MEDIA_AUDIO_TRACK = 222; // 0xde
field public static final int KEYCODE_MEDIA_CLOSE = 128; // 0x80
@@ -51278,10 +51313,12 @@
method public long getDownTime();
method public int getEdgeFlags();
method public long getEventTime();
+ method public long getEventTimeNanos();
method public int getFlags();
method public float getHistoricalAxisValue(int, int);
method public float getHistoricalAxisValue(int, int, int);
method public long getHistoricalEventTime(int);
+ method public long getHistoricalEventTimeNanos(int);
method public float getHistoricalOrientation(int);
method public float getHistoricalOrientation(int, int);
method public void getHistoricalPointerCoords(int, int, android.view.MotionEvent.PointerCoords);
@@ -53899,6 +53936,14 @@
method public void removeViewImmediate(android.view.View);
field public static final String PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE = "android.window.PROPERTY_ACTIVITY_EMBEDDING_ALLOW_SYSTEM_OVERRIDE";
field public static final String PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED = "android.window.PROPERTY_ACTIVITY_EMBEDDING_SPLITS_ENABLED";
+ field public static final String PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION = "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION";
+ field public static final String PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH = "android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH";
+ field public static final String PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE = "android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE";
+ field public static final String PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE = "android.window.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE";
+ field public static final String PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE = "android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE";
+ field public static final String PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS = "android.window.PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS";
+ field public static final String PROPERTY_COMPAT_ENABLE_FAKE_FOCUS = "android.window.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS";
+ field public static final String PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION = "android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION";
}
public static class WindowManager.BadTokenException extends java.lang.RuntimeException {
@@ -55054,7 +55099,7 @@
method public void registerCallback(@Nullable android.view.autofill.AutofillManager.AutofillCallback);
method public void requestAutofill(@NonNull android.view.View);
method public void requestAutofill(@NonNull android.view.View, int, @NonNull android.graphics.Rect);
- method public void setAutofillRequestCallback(@NonNull java.util.concurrent.Executor, @NonNull android.view.autofill.AutofillRequestCallback);
+ method @RequiresPermission(android.Manifest.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS) public void setAutofillRequestCallback(@NonNull java.util.concurrent.Executor, @NonNull android.view.autofill.AutofillRequestCallback);
method public void setUserData(@Nullable android.service.autofill.UserData);
method public boolean showAutofillDialog(@NonNull android.view.View);
method public boolean showAutofillDialog(@NonNull android.view.View, int);
diff --git a/core/api/module-lib-current.txt b/core/api/module-lib-current.txt
index 1e21c776..58f78aa 100644
--- a/core/api/module-lib-current.txt
+++ b/core/api/module-lib-current.txt
@@ -18,10 +18,18 @@
public class ActivityManager {
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void addHomeVisibilityListener(@NonNull java.util.concurrent.Executor, @NonNull android.app.HomeVisibilityListener);
+ method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void registerUidFrozenStateChangedCallback(@NonNull java.util.concurrent.Executor, @NonNull android.app.ActivityManager.UidFrozenStateChangedCallback);
method @RequiresPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER) public void removeHomeVisibilityListener(@NonNull android.app.HomeVisibilityListener);
+ method @RequiresPermission(android.Manifest.permission.PACKAGE_USAGE_STATS) public void unregisterUidFrozenStateChangedCallback(@NonNull android.app.ActivityManager.UidFrozenStateChangedCallback);
method @RequiresPermission(android.Manifest.permission.CHANGE_CONFIGURATION) public boolean updateMccMncConfiguration(@NonNull String, @NonNull String);
}
+ public static interface ActivityManager.UidFrozenStateChangedCallback {
+ method public void onUidFrozenStateChanged(@NonNull int[], @NonNull int[]);
+ field public static final int UID_FROZEN_STATE_FROZEN = 1; // 0x1
+ field public static final int UID_FROZEN_STATE_UNFROZEN = 2; // 0x2
+ }
+
public class AppOpsManager {
field public static final String OPSTR_NO_ISOLATED_STORAGE = "android:no_isolated_storage";
}
diff --git a/core/api/system-current.txt b/core/api/system-current.txt
index 41da5ea..70be31b 100644
--- a/core/api/system-current.txt
+++ b/core/api/system-current.txt
@@ -272,6 +272,7 @@
field public static final String READ_DEVICE_CONFIG = "android.permission.READ_DEVICE_CONFIG";
field public static final String READ_DREAM_STATE = "android.permission.READ_DREAM_STATE";
field public static final String READ_GLOBAL_APP_SEARCH_DATA = "android.permission.READ_GLOBAL_APP_SEARCH_DATA";
+ field public static final String READ_INSTALLED_SESSION_PATHS = "android.permission.READ_INSTALLED_SESSION_PATHS";
field public static final String READ_INSTALL_SESSIONS = "android.permission.READ_INSTALL_SESSIONS";
field public static final String READ_NETWORK_USAGE_HISTORY = "android.permission.READ_NETWORK_USAGE_HISTORY";
field public static final String READ_OEM_UNLOCK_STATE = "android.permission.READ_OEM_UNLOCK_STATE";
@@ -968,24 +969,9 @@
field public static final int SEMANTIC_ACTION_MARK_CONVERSATION_AS_PRIORITY = 11; // 0xb
}
- public static class Notification.MediaStyle extends android.app.Notification.Style {
- method @NonNull @RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL) public android.app.Notification.MediaStyle setRemotePlaybackInfo(@NonNull CharSequence, @DrawableRes int, @Nullable android.app.PendingIntent);
- }
-
public static final class Notification.TvExtender implements android.app.Notification.Extender {
- ctor public Notification.TvExtender();
- ctor public Notification.TvExtender(android.app.Notification);
- method public android.app.Notification.Builder extend(android.app.Notification.Builder);
- method public String getChannelId();
- method public android.app.PendingIntent getContentIntent();
- method public android.app.PendingIntent getDeleteIntent();
method public boolean getSuppressShowOverApps();
- method public boolean isAvailableOnTv();
method public android.app.Notification.TvExtender setChannel(String);
- method public android.app.Notification.TvExtender setChannelId(String);
- method public android.app.Notification.TvExtender setContentIntent(android.app.PendingIntent);
- method public android.app.Notification.TvExtender setDeleteIntent(android.app.PendingIntent);
- method public android.app.Notification.TvExtender setSuppressShowOverApps(boolean);
}
public final class NotificationChannel implements android.os.Parcelable {
@@ -1278,6 +1264,7 @@
method @Nullable public CharSequence getDeviceOwnerOrganizationName();
method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_USERS) public android.os.UserHandle getDeviceOwnerUser();
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public android.app.admin.DevicePolicyState getDevicePolicyState();
+ method @Nullable @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public String getFinancedDeviceKioskRoleHolder();
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_ADMIN_POLICY}) public java.util.List<java.lang.String> getPermittedAccessibilityServices(int);
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.QUERY_ADMIN_POLICY}) public java.util.List<java.lang.String> getPermittedInputMethodsForCurrentUser();
method @NonNull @RequiresPermission(android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS) public java.util.List<android.os.UserHandle> getPolicyManagedProfiles(@NonNull android.os.UserHandle);
@@ -3802,7 +3789,6 @@
field public static final String EXTRA_CALLBACK = "android.content.pm.extra.CALLBACK";
field public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
field public static final String EXTRA_LEGACY_STATUS = "android.content.pm.extra.LEGACY_STATUS";
- field public static final String EXTRA_RESOLVED_BASE_PATH = "android.content.pm.extra.RESOLVED_BASE_PATH";
field public static final int LOCATION_DATA_APP = 0; // 0x0
field public static final int LOCATION_MEDIA_DATA = 2; // 0x2
field public static final int LOCATION_MEDIA_OBB = 1; // 0x1
@@ -3839,6 +3825,7 @@
method public boolean getInstallAsVirtualPreload();
method public int getPendingUserActionReason();
method public boolean getRequestDowngrade();
+ method @Nullable @RequiresPermission(android.Manifest.permission.READ_INSTALLED_SESSION_PATHS) public String getResolvedBaseApkPath();
method public int getRollbackDataPolicy();
method @NonNull public java.util.Set<java.lang.String> getWhitelistedRestrictedPermissions();
}
@@ -10002,6 +9989,7 @@
public final class HotspotNetwork implements android.os.Parcelable {
method public int describeContents();
method public long getDeviceId();
+ method @NonNull public android.os.Bundle getExtras();
method public int getHostNetworkType();
method @Nullable public String getHotspotBssid();
method @NonNull public java.util.Set<java.lang.Integer> getHotspotSecurityTypes();
@@ -10021,6 +10009,7 @@
method @NonNull public android.net.wifi.sharedconnectivity.app.HotspotNetwork.Builder addHotspotSecurityType(int);
method @NonNull public android.net.wifi.sharedconnectivity.app.HotspotNetwork build();
method @NonNull public android.net.wifi.sharedconnectivity.app.HotspotNetwork.Builder setDeviceId(long);
+ method @NonNull public android.net.wifi.sharedconnectivity.app.HotspotNetwork.Builder setExtras(@NonNull android.os.Bundle);
method @NonNull public android.net.wifi.sharedconnectivity.app.HotspotNetwork.Builder setHostNetworkType(int);
method @NonNull public android.net.wifi.sharedconnectivity.app.HotspotNetwork.Builder setHotspotBssid(@NonNull String);
method @NonNull public android.net.wifi.sharedconnectivity.app.HotspotNetwork.Builder setHotspotSsid(@NonNull String);
@@ -10057,6 +10046,7 @@
public final class KnownNetwork implements android.os.Parcelable {
method public int describeContents();
+ method @NonNull public android.os.Bundle getExtras();
method @Nullable public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo getNetworkProviderInfo();
method public int getNetworkSource();
method @NonNull public java.util.Set<java.lang.Integer> getSecurityTypes();
@@ -10072,6 +10062,7 @@
ctor public KnownNetwork.Builder();
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder addSecurityType(int);
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork build();
+ method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setExtras(@NonNull android.os.Bundle);
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setNetworkProviderInfo(@Nullable android.net.wifi.sharedconnectivity.app.NetworkProviderInfo);
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setNetworkSource(int);
method @NonNull public android.net.wifi.sharedconnectivity.app.KnownNetwork.Builder setSsid(@NonNull String);
@@ -10103,6 +10094,7 @@
method @IntRange(from=0, to=3) public int getConnectionStrength();
method @NonNull public String getDeviceName();
method public int getDeviceType();
+ method @NonNull public android.os.Bundle getExtras();
method @NonNull public String getModelName();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.NetworkProviderInfo> CREATOR;
@@ -10121,6 +10113,7 @@
method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setConnectionStrength(@IntRange(from=0, to=3) int);
method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setDeviceName(@NonNull String);
method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setDeviceType(int);
+ method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setExtras(@NonNull android.os.Bundle);
method @NonNull public android.net.wifi.sharedconnectivity.app.NetworkProviderInfo.Builder setModelName(@NonNull String);
}
@@ -10152,16 +10145,18 @@
public final class SharedConnectivitySettingsState implements android.os.Parcelable {
method public int describeContents();
method @NonNull public android.os.Bundle getExtras();
+ method @Nullable public android.app.PendingIntent getInstantTetherSettingsPendingIntent();
method public boolean isInstantTetherEnabled();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState> CREATOR;
}
public static final class SharedConnectivitySettingsState.Builder {
- ctor public SharedConnectivitySettingsState.Builder();
+ ctor public SharedConnectivitySettingsState.Builder(@NonNull android.content.Context);
method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState build();
method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.Builder setExtras(@NonNull android.os.Bundle);
method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.Builder setInstantTetherEnabled(boolean);
+ method @NonNull public android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState.Builder setInstantTetherSettingsPendingIntent(@NonNull android.content.Intent);
}
}
@@ -13011,20 +13006,20 @@
package android.service.voice {
public class AlwaysOnHotwordDetector implements android.service.voice.HotwordDetector {
- method @Nullable public android.content.Intent createEnrollIntent() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @Nullable public android.content.Intent createReEnrollIntent() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @Nullable public android.content.Intent createUnEnrollIntent() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int getParameter(int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+ method @Nullable public android.content.Intent createEnrollIntent();
+ method @Nullable public android.content.Intent createReEnrollIntent();
+ method @Nullable public android.content.Intent createUnEnrollIntent();
+ method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int getParameter(int);
method public int getSupportedAudioCapabilities();
- method public int getSupportedRecognitionModes() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @Nullable @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public android.service.voice.AlwaysOnHotwordDetector.ModelParamRange queryParameter(int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int setParameter(int, int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int, @NonNull byte[]) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean stopRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method public final void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+ method public int getSupportedRecognitionModes();
+ method @Nullable @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public android.service.voice.AlwaysOnHotwordDetector.ModelParamRange queryParameter(int);
+ method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public int setParameter(int, int);
+ method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int, @NonNull byte[]);
+ method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition(int);
+ method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition();
+ method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle);
+ method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean stopRecognition();
+ method public final void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory);
field public static final int AUDIO_CAPABILITY_ECHO_CANCELLATION = 1; // 0x1
field public static final int AUDIO_CAPABILITY_NOISE_SUPPRESSION = 2; // 0x2
field public static final int MODEL_PARAM_THRESHOLD_FACTOR = 0; // 0x0
@@ -13045,6 +13040,7 @@
public abstract static class AlwaysOnHotwordDetector.Callback implements android.service.voice.HotwordDetector.Callback {
ctor public AlwaysOnHotwordDetector.Callback();
method public abstract void onAvailabilityChanged(int);
+ method public void onFailure(@NonNull android.service.voice.SoundTriggerFailure);
method public void onHotwordDetectionServiceInitialized(int);
method public void onHotwordDetectionServiceRestarted();
method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
@@ -13068,32 +13064,12 @@
method public int getStart();
}
- public final class DetectedPhrase implements android.os.Parcelable {
- method public int describeContents();
- method public int getId();
- method @Nullable public String getPhrase();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.DetectedPhrase> CREATOR;
- }
-
- public static final class DetectedPhrase.Builder {
- ctor public DetectedPhrase.Builder();
- method @NonNull public android.service.voice.DetectedPhrase build();
- method @NonNull public android.service.voice.DetectedPhrase.Builder setId(int);
- method @NonNull public android.service.voice.DetectedPhrase.Builder setPhrase(@NonNull String);
- }
-
- public abstract class DetectorFailure implements android.os.Parcelable {
- method public int describeContents();
- method @NonNull public String getErrorMessage();
- method public abstract int getSuggestedAction();
- method public void writeToParcel(@NonNull android.os.Parcel, int);
- field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.DetectorFailure> CREATOR;
- field public static final int SUGGESTED_ACTION_DISABLE_DETECTION = 2; // 0x2
- field public static final int SUGGESTED_ACTION_NONE = 1; // 0x1
- field public static final int SUGGESTED_ACTION_RECREATE_DETECTOR = 3; // 0x3
- field public static final int SUGGESTED_ACTION_RESTART_RECOGNITION = 4; // 0x4
- field public static final int SUGGESTED_ACTION_UNKNOWN = 0; // 0x0
+ public final class FailureSuggestedAction {
+ field public static final int DISABLE_DETECTION = 2; // 0x2
+ field public static final int NONE = 1; // 0x1
+ field public static final int RECREATE_DETECTOR = 3; // 0x3
+ field public static final int RESTART_RECOGNITION = 4; // 0x4
+ field public static final int UNKNOWN = 0; // 0x0
}
public final class HotwordAudioStream implements android.os.Parcelable {
@@ -13122,14 +13098,15 @@
method public int describeContents();
method public int getAudioChannel();
method @NonNull public java.util.List<android.service.voice.HotwordAudioStream> getAudioStreams();
+ method public int getBackgroundAudioPower();
method public int getConfidenceLevel();
- method @NonNull public android.service.voice.DetectedPhrase getDetectedPhrase();
method @NonNull public android.os.PersistableBundle getExtras();
method public int getHotwordDurationMillis();
method public int getHotwordOffsetMillis();
- method @Deprecated public int getHotwordPhraseId();
+ method public int getHotwordPhraseId();
+ method public static int getMaxBackgroundAudioPower();
method public static int getMaxBundleSize();
- method @Deprecated public static int getMaxHotwordPhraseId();
+ method public static int getMaxHotwordPhraseId();
method public static int getMaxScore();
method @Nullable public android.media.MediaSyncEvent getMediaSyncEvent();
method public int getPersonalizedScore();
@@ -13138,6 +13115,7 @@
method public boolean isHotwordDetectionPersonalized();
method public void writeToParcel(@NonNull android.os.Parcel, int);
field public static final int AUDIO_CHANNEL_UNSET = -1; // 0xffffffff
+ field public static final int BACKGROUND_AUDIO_POWER_UNSET = -1; // 0xffffffff
field public static final int CONFIDENCE_LEVEL_HIGH = 5; // 0x5
field public static final int CONFIDENCE_LEVEL_LOW = 1; // 0x1
field public static final int CONFIDENCE_LEVEL_LOW_MEDIUM = 2; // 0x2
@@ -13157,13 +13135,13 @@
method @NonNull public android.service.voice.HotwordDetectedResult build();
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setAudioChannel(int);
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setAudioStreams(@NonNull java.util.List<android.service.voice.HotwordAudioStream>);
+ method @NonNull public android.service.voice.HotwordDetectedResult.Builder setBackgroundAudioPower(int);
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setConfidenceLevel(int);
- method @NonNull public android.service.voice.HotwordDetectedResult.Builder setDetectedPhrase(@NonNull android.service.voice.DetectedPhrase);
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setExtras(@NonNull android.os.PersistableBundle);
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setHotwordDetectionPersonalized(boolean);
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setHotwordDurationMillis(int);
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setHotwordOffsetMillis(int);
- method @Deprecated @NonNull public android.service.voice.HotwordDetectedResult.Builder setHotwordPhraseId(int);
+ method @NonNull public android.service.voice.HotwordDetectedResult.Builder setHotwordPhraseId(int);
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setMediaSyncEvent(@NonNull android.media.MediaSyncEvent);
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setPersonalizedScore(int);
method @NonNull public android.service.voice.HotwordDetectedResult.Builder setScore(int);
@@ -13188,9 +13166,12 @@
method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
}
- public final class HotwordDetectionServiceFailure extends android.service.voice.DetectorFailure {
+ public final class HotwordDetectionServiceFailure implements android.os.Parcelable {
+ method public int describeContents();
method public int getErrorCode();
+ method @NonNull public String getErrorMessage();
method public int getSuggestedAction();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.HotwordDetectionServiceFailure> CREATOR;
field public static final int ERROR_CODE_BINDING_DIED = 2; // 0x2
field public static final int ERROR_CODE_BIND_FAILURE = 1; // 0x1
@@ -13204,24 +13185,22 @@
public interface HotwordDetector {
method public default void destroy();
- method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method public boolean stopRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+ method @RequiresPermission(allOf={android.Manifest.permission.RECORD_AUDIO, android.Manifest.permission.CAPTURE_AUDIO_HOTWORD}) public boolean startRecognition();
+ method public boolean startRecognition(@NonNull android.os.ParcelFileDescriptor, @NonNull android.media.AudioFormat, @Nullable android.os.PersistableBundle);
+ method public boolean stopRecognition();
+ method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory);
}
public static interface HotwordDetector.Callback {
method public void onDetected(@NonNull android.service.voice.AlwaysOnHotwordDetector.EventPayload);
method @Deprecated public void onError();
- method public default void onFailure(@NonNull android.service.voice.DetectorFailure);
+ method public default void onFailure(@NonNull android.service.voice.HotwordDetectionServiceFailure);
method public void onHotwordDetectionServiceInitialized(int);
method public void onHotwordDetectionServiceRestarted();
method public void onRecognitionPaused();
method public void onRecognitionResumed();
method public void onRejected(@NonNull android.service.voice.HotwordRejectedResult);
- }
-
- public static class HotwordDetector.IllegalDetectorStateException extends android.util.AndroidException {
+ method public default void onUnknownFailure(@NonNull String);
}
public final class HotwordRejectedResult implements android.os.Parcelable {
@@ -13248,9 +13227,12 @@
field public static final int INITIALIZATION_STATUS_UNKNOWN = 100; // 0x64
}
- public final class SoundTriggerFailure extends android.service.voice.DetectorFailure {
+ public final class SoundTriggerFailure implements android.os.Parcelable {
+ method public int describeContents();
method public int getErrorCode();
+ method @NonNull public String getErrorMessage();
method public int getSuggestedAction();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.SoundTriggerFailure> CREATOR;
field public static final int ERROR_CODE_MODULE_DIED = 1; // 0x1
field public static final int ERROR_CODE_RECOGNITION_RESUME_FAILED = 2; // 0x2
@@ -13258,11 +13240,6 @@
field public static final int ERROR_CODE_UNKNOWN = 0; // 0x0
}
- public final class UnknownFailure extends android.service.voice.DetectorFailure {
- method public int getSuggestedAction();
- field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.UnknownFailure> CREATOR;
- }
-
public abstract class VisualQueryDetectionService extends android.app.Service implements android.service.voice.SandboxedDetectionInitializer {
ctor public VisualQueryDetectionService();
method public final void finishQuery() throws java.lang.IllegalStateException;
@@ -13277,9 +13254,12 @@
field public static final String SERVICE_INTERFACE = "android.service.voice.VisualQueryDetectionService";
}
- public final class VisualQueryDetectionServiceFailure extends android.service.voice.DetectorFailure {
+ public final class VisualQueryDetectionServiceFailure implements android.os.Parcelable {
+ method public int describeContents();
method public int getErrorCode();
+ method @NonNull public String getErrorMessage();
method public int getSuggestedAction();
+ method public void writeToParcel(@NonNull android.os.Parcel, int);
field @NonNull public static final android.os.Parcelable.Creator<android.service.voice.VisualQueryDetectionServiceFailure> CREATOR;
field public static final int ERROR_CODE_BINDING_DIED = 2; // 0x2
field public static final int ERROR_CODE_BIND_FAILURE = 1; // 0x1
@@ -13291,16 +13271,17 @@
public class VisualQueryDetector {
method public void destroy();
- method @RequiresPermission(allOf={android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}) public boolean startRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method @RequiresPermission(allOf={android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}) public boolean stopRecognition() throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
- method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory) throws android.service.voice.HotwordDetector.IllegalDetectorStateException;
+ method @RequiresPermission(allOf={android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}) public boolean startRecognition();
+ method @RequiresPermission(allOf={android.Manifest.permission.CAMERA, android.Manifest.permission.RECORD_AUDIO}) public boolean stopRecognition();
+ method public void updateState(@Nullable android.os.PersistableBundle, @Nullable android.os.SharedMemory);
}
public static interface VisualQueryDetector.Callback {
- method public void onFailure(@NonNull android.service.voice.DetectorFailure);
+ method public void onFailure(@NonNull android.service.voice.VisualQueryDetectionServiceFailure);
method public void onQueryDetected(@NonNull String);
method public void onQueryFinished();
method public void onQueryRejected();
+ method public void onUnknownFailure(@NonNull String);
method public void onVisualQueryDetectionServiceInitialized(int);
method public void onVisualQueryDetectionServiceRestarted();
}
diff --git a/core/api/test-current.txt b/core/api/test-current.txt
index 02ff87a..ba2f807 100644
--- a/core/api/test-current.txt
+++ b/core/api/test-current.txt
@@ -476,7 +476,7 @@
method @Nullable public android.graphics.Rect peekBitmapDimensions(int);
method public void setWallpaperZoomOut(@NonNull android.os.IBinder, float);
method public boolean shouldEnableWideColorGamut();
- method @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE) public boolean wallpaperSupportsWcg(int);
+ method public boolean wallpaperSupportsWcg(int);
}
public class WindowConfiguration implements java.lang.Comparable<android.app.WindowConfiguration> android.os.Parcelable {
@@ -516,6 +516,10 @@
package android.app.admin {
+ public final class AccountTypePolicyKey extends android.app.admin.PolicyKey {
+ ctor public AccountTypePolicyKey(@NonNull String, @NonNull String);
+ }
+
public final class DeviceAdminAuthority extends android.app.admin.Authority {
field @NonNull public static final android.app.admin.DeviceAdminAuthority DEVICE_ADMIN_AUTHORITY;
}
@@ -612,6 +616,10 @@
field @NonNull public static final android.app.admin.FlagUnion FLAG_UNION;
}
+ public final class IntentFilterPolicyKey extends android.app.admin.PolicyKey {
+ ctor public IntentFilterPolicyKey(@NonNull String, @NonNull android.content.IntentFilter);
+ }
+
public final class MostRecent<V> extends android.app.admin.ResolutionMechanism<V> {
ctor public MostRecent();
method public int describeContents();
@@ -627,6 +635,14 @@
field @NonNull public static final android.os.Parcelable.Creator<android.app.admin.MostRestrictive<?>> CREATOR;
}
+ public final class PackagePermissionPolicyKey extends android.app.admin.PolicyKey {
+ ctor public PackagePermissionPolicyKey(@NonNull String, @NonNull String, @NonNull String);
+ }
+
+ public final class PackagePolicyKey extends android.app.admin.PolicyKey {
+ ctor public PackagePolicyKey(@NonNull String, @NonNull String);
+ }
+
public final class PolicyState<V> implements android.os.Parcelable {
method @NonNull public android.app.admin.ResolutionMechanism<V> getResolutionMechanism();
}
@@ -676,6 +692,10 @@
method public int getOperation();
}
+ public final class UserRestrictionPolicyKey extends android.app.admin.PolicyKey {
+ ctor public UserRestrictionPolicyKey(@NonNull String, @NonNull String);
+ }
+
}
package android.app.assist {
@@ -1393,8 +1413,12 @@
package android.hardware.camera2 {
public final class CameraManager {
+ method @NonNull public android.hardware.camera2.CameraCharacteristics getCameraCharacteristics(@NonNull String, boolean) throws android.hardware.camera2.CameraAccessException;
method public String[] getCameraIdListNoLazy() throws android.hardware.camera2.CameraAccessException;
+ method @RequiresPermission(android.Manifest.permission.CAMERA) public void openCamera(@NonNull String, boolean, @Nullable android.os.Handler, @NonNull android.hardware.camera2.CameraDevice.StateCallback) throws android.hardware.camera2.CameraAccessException;
method @RequiresPermission(allOf={android.Manifest.permission.SYSTEM_CAMERA, android.Manifest.permission.CAMERA}) public void openCamera(@NonNull String, int, @NonNull java.util.concurrent.Executor, @NonNull android.hardware.camera2.CameraDevice.StateCallback) throws android.hardware.camera2.CameraAccessException;
+ method public static boolean shouldOverrideToPortrait(@Nullable android.content.pm.PackageManager, @Nullable String);
+ field public static final String LANDSCAPE_TO_PORTRAIT_PROP = "camera.enable_landscape_to_portrait";
field public static final long OVERRIDE_CAMERA_LANDSCAPE_TO_PORTRAIT = 250678880L; // 0xef10e60L
}
@@ -2011,6 +2035,7 @@
public abstract class SharedConnectivityService extends android.app.Service {
method public void onBind();
+ method public final void setCountdownLatch(@Nullable java.util.concurrent.CountDownLatch);
}
}
@@ -2226,7 +2251,7 @@
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createRestrictedProfile(@Nullable String);
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.content.pm.UserInfo createUser(@Nullable String, @NonNull String, int);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public android.os.UserHandle getBootUser();
- method public int getDisplayIdAssignedToUser();
+ method public int getMainDisplayIdAssignedToUser();
method @Nullable @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.Set<java.lang.String> getPreInstallableSystemPackages(@NonNull String);
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS, android.Manifest.permission.QUERY_USERS}) public String getUserType();
method @NonNull @RequiresPermission(anyOf={android.Manifest.permission.MANAGE_USERS, android.Manifest.permission.CREATE_USERS}) public java.util.List<android.content.pm.UserInfo> getUsers(boolean, boolean, boolean);
@@ -2874,23 +2899,19 @@
field public static final boolean ENABLE_PROXIMITY_RESULT = true;
}
- public final class HotwordDetectionServiceFailure extends android.service.voice.DetectorFailure {
+ public final class HotwordDetectionServiceFailure implements android.os.Parcelable {
ctor public HotwordDetectionServiceFailure(int, @NonNull String);
}
- public final class SoundTriggerFailure extends android.service.voice.DetectorFailure {
+ public final class SoundTriggerFailure implements android.os.Parcelable {
ctor public SoundTriggerFailure(int, @NonNull String);
}
- public final class UnknownFailure extends android.service.voice.DetectorFailure {
- ctor public UnknownFailure(@NonNull String);
- }
-
public final class VisibleActivityInfo implements android.os.Parcelable {
ctor public VisibleActivityInfo(int, @NonNull android.os.IBinder);
}
- public final class VisualQueryDetectionServiceFailure extends android.service.voice.DetectorFailure {
+ public final class VisualQueryDetectionServiceFailure implements android.os.Parcelable {
ctor public VisualQueryDetectionServiceFailure(int, @NonNull String);
}
@@ -3310,7 +3331,7 @@
method public static String actionToString(int);
method public final void setDisplayId(int);
field public static final int FLAG_IS_ACCESSIBILITY_EVENT = 2048; // 0x800
- field public static final int LAST_KEYCODE = 312; // 0x138
+ field public static final int LAST_KEYCODE = 316; // 0x13c
}
public final class KeyboardShortcutGroup implements android.os.Parcelable {
@@ -3580,6 +3601,11 @@
package android.view.inputmethod {
+ public abstract class CancellableHandwritingGesture extends android.view.inputmethod.HandwritingGesture {
+ ctor public CancellableHandwritingGesture();
+ method public void setCancellationSignal(@NonNull android.os.CancellationSignal);
+ }
+
public abstract class HandwritingGesture {
method @NonNull public static android.view.inputmethod.HandwritingGesture fromByteArray(@NonNull byte[]);
method public final int getGestureType();
diff --git a/core/java/android/animation/Animator.java b/core/java/android/animation/Animator.java
index 322d23b..12026aa 100644
--- a/core/java/android/animation/Animator.java
+++ b/core/java/android/animation/Animator.java
@@ -69,7 +69,7 @@
* backing field for backgroundPauseDelay property. This could be simply a hardcoded
* value in AnimationHandler, but it is useful to be able to change the value in tests.
*/
- private static long sBackgroundPauseDelay = 10000;
+ private static long sBackgroundPauseDelay = 1000;
/**
* A cache of the values in a list. Used so that when calling the list, we have a copy
@@ -79,6 +79,13 @@
private Object[] mCachedList;
/**
+ * Tracks whether we've notified listeners of the onAnimationStart() event. This can be
+ * complex to keep track of since we notify listeners at different times depending on
+ * startDelay and whether start() was called before end().
+ */
+ boolean mStartListenersCalled = false;
+
+ /**
* Sets the duration for delaying pausing animators when apps go into the background.
* Used by AnimationHandler when requested to pause animators.
*
@@ -165,7 +172,9 @@
* @see AnimatorPauseListener
*/
public void pause() {
- if (isStarted() && !mPaused) {
+ // We only want to pause started Animators or animators that setCurrentPlayTime()
+ // have been called on. mStartListenerCalled will be true if seek has happened.
+ if ((isStarted() || mStartListenersCalled) && !mPaused) {
mPaused = true;
notifyPauseListeners(AnimatorCaller.ON_PAUSE);
}
@@ -444,6 +453,7 @@
anim.mPauseListeners = new ArrayList<AnimatorPauseListener>(mPauseListeners);
}
anim.mCachedList = null;
+ anim.mStartListenersCalled = false;
return anim;
} catch (CloneNotSupportedException e) {
throw new AssertionError();
@@ -608,6 +618,22 @@
callOnList(mPauseListeners, notification, this, false);
}
+ void notifyStartListeners(boolean isReversing) {
+ boolean startListenersCalled = mStartListenersCalled;
+ mStartListenersCalled = true;
+ if (mListeners != null && !startListenersCalled) {
+ notifyListeners(AnimatorCaller.ON_START, isReversing);
+ }
+ }
+
+ void notifyEndListeners(boolean isReversing) {
+ boolean startListenersCalled = mStartListenersCalled;
+ mStartListenersCalled = false;
+ if (mListeners != null && startListenersCalled) {
+ notifyListeners(AnimatorCaller.ON_END, isReversing);
+ }
+ }
+
/**
* Calls <code>call</code> for every item in <code>list</code> with <code>animator</code> and
* <code>isReverse</code> as parameters.
diff --git a/core/java/android/animation/AnimatorSet.java b/core/java/android/animation/AnimatorSet.java
index 09eec9d..60659dc 100644
--- a/core/java/android/animation/AnimatorSet.java
+++ b/core/java/android/animation/AnimatorSet.java
@@ -189,11 +189,6 @@
*/
private long[] mChildStartAndStopTimes;
- /**
- * Tracks whether we've notified listeners of the onAnimationStart() event.
- */
- private boolean mStartListenersCalled;
-
// This is to work around a bug in b/34736819. This needs to be removed once app team
// fixes their side.
private AnimatorListenerAdapter mAnimationEndListener = new AnimatorListenerAdapter() {
@@ -424,7 +419,7 @@
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
- if (isStarted()) {
+ if (isStarted() || mStartListenersCalled) {
notifyListeners(AnimatorCaller.ON_CANCEL, false);
callOnPlayingSet(Animator::cancel);
mPlayingSet.clear();
@@ -486,13 +481,13 @@
return;
}
if (isStarted()) {
+ mStarted = false; // don't allow reentrancy
// Iterate the animations that haven't finished or haven't started, and end them.
if (mReversing) {
// Between start() and first frame, mLastEventId would be unset (i.e. -1)
mLastEventId = mLastEventId == -1 ? mEvents.size() : mLastEventId;
- while (mLastEventId > 0) {
- mLastEventId = mLastEventId - 1;
- AnimationEvent event = mEvents.get(mLastEventId);
+ for (int eventId = mLastEventId - 1; eventId >= 0; eventId--) {
+ AnimationEvent event = mEvents.get(eventId);
Animator anim = event.mNode.mAnimation;
if (mNodeMap.get(anim).mEnded) {
continue;
@@ -508,11 +503,10 @@
}
}
} else {
- while (mLastEventId < mEvents.size() - 1) {
+ for (int eventId = mLastEventId + 1; eventId < mEvents.size(); eventId++) {
// Avoid potential reentrant loop caused by child animators manipulating
// AnimatorSet's lifecycle (i.e. not a recommended approach).
- mLastEventId = mLastEventId + 1;
- AnimationEvent event = mEvents.get(mLastEventId);
+ AnimationEvent event = mEvents.get(eventId);
Animator anim = event.mNode.mAnimation;
if (mNodeMap.get(anim).mEnded) {
continue;
@@ -527,7 +521,6 @@
}
}
}
- mPlayingSet.clear();
}
endAnimation();
}
@@ -723,6 +716,10 @@
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
+ if (inReverse == mReversing && selfPulse == mSelfPulse && mStarted) {
+ // It is already started
+ return;
+ }
mStarted = true;
mSelfPulse = selfPulse;
mPaused = false;
@@ -756,20 +753,6 @@
}
}
- private void notifyStartListeners(boolean inReverse) {
- if (mListeners != null && !mStartListenersCalled) {
- notifyListeners(AnimatorCaller.ON_START, inReverse);
- }
- mStartListenersCalled = true;
- }
-
- private void notifyEndListeners(boolean inReverse) {
- if (mListeners != null && mStartListenersCalled) {
- notifyListeners(AnimatorCaller.ON_END, inReverse);
- }
- mStartListenersCalled = false;
- }
-
// Returns true if set is empty or contains nothing but animator sets with no start delay.
private static boolean isEmptySet(AnimatorSet set) {
if (set.getStartDelay() > 0) {
@@ -936,12 +919,18 @@
lastPlayTime - node.mStartTime,
notify
);
+ if (notify) {
+ mPlayingSet.remove(node);
+ }
} else if (start <= currentPlayTime && currentPlayTime <= end) {
animator.animateSkipToEnds(
currentPlayTime - node.mStartTime,
lastPlayTime - node.mStartTime,
notify
);
+ if (notify && !mPlayingSet.contains(node)) {
+ mPlayingSet.add(node);
+ }
}
}
}
@@ -969,12 +958,18 @@
lastPlayTime - node.mStartTime,
notify
);
+ if (notify) {
+ mPlayingSet.remove(node);
+ }
} else if (start <= currentPlayTime && currentPlayTime <= end) {
animator.animateSkipToEnds(
currentPlayTime - node.mStartTime,
lastPlayTime - node.mStartTime,
notify
);
+ if (notify && !mPlayingSet.contains(node)) {
+ mPlayingSet.add(node);
+ }
}
}
}
@@ -1115,8 +1110,8 @@
mSeekState.setPlayTime(0, mReversing);
}
}
- animateBasedOnPlayTime(playTime, lastPlayTime, mReversing, true);
mSeekState.setPlayTime(playTime, mReversing);
+ animateBasedOnPlayTime(playTime, lastPlayTime, mReversing, true);
}
/**
@@ -1498,7 +1493,6 @@
anim.mNodeMap = new ArrayMap<Animator, Node>();
anim.mNodes = new ArrayList<Node>(nodeCount);
anim.mEvents = new ArrayList<AnimationEvent>();
- anim.mStartListenersCalled = false;
anim.mAnimationEndListener = new AnimatorListenerAdapter() {
@Override
public void onAnimationEnd(Animator animation) {
diff --git a/core/java/android/animation/ValueAnimator.java b/core/java/android/animation/ValueAnimator.java
index 719f596..5d69f8b 100644
--- a/core/java/android/animation/ValueAnimator.java
+++ b/core/java/android/animation/ValueAnimator.java
@@ -199,13 +199,6 @@
private boolean mStarted = false;
/**
- * Tracks whether we've notified listeners of the onAnimationStart() event. This can be
- * complex to keep track of since we notify listeners at different times depending on
- * startDelay and whether start() was called before end().
- */
- private boolean mStartListenersCalled = false;
-
- /**
* Flag that denotes whether the animation is set up and ready to go. Used to
* set up animation that has not yet been started.
*/
@@ -1108,20 +1101,6 @@
}
}
- private void notifyStartListeners(boolean isReversing) {
- if (mListeners != null && !mStartListenersCalled) {
- notifyListeners(AnimatorCaller.ON_START, isReversing);
- }
- mStartListenersCalled = true;
- }
-
- private void notifyEndListeners(boolean isReversing) {
- if (mListeners != null && mStartListenersCalled) {
- notifyListeners(AnimatorCaller.ON_END, isReversing);
- }
- mStartListenersCalled = false;
- }
-
/**
* Start the animation playing. This version of start() takes a boolean flag that indicates
* whether the animation should play in reverse. The flag is usually false, but may be set
@@ -1139,6 +1118,10 @@
if (Looper.myLooper() == null) {
throw new AndroidRuntimeException("Animators may only be run on Looper threads");
}
+ if (playBackwards == mResumed && mSelfPulse == !mSuppressSelfPulseRequested && mStarted) {
+ // already started
+ return;
+ }
mReversing = playBackwards;
mSelfPulse = !mSuppressSelfPulseRequested;
// Special case: reversing from seek-to-0 should act as if not seeked at all.
@@ -1209,7 +1192,7 @@
// Only cancel if the animation is actually running or has been started and is about
// to run
// Only notify listeners if the animator has actually started
- if ((mStarted || mRunning) && mListeners != null) {
+ if ((mStarted || mRunning || mStartListenersCalled) && mListeners != null) {
if (!mRunning) {
// If it's not yet running, then start listeners weren't called. Call them now.
notifyStartListeners(mReversing);
@@ -1217,7 +1200,6 @@
notifyListeners(AnimatorCaller.ON_CANCEL, false);
}
endAnimation();
-
}
@Override
@@ -1320,11 +1302,11 @@
// If it's not yet running, then start listeners weren't called. Call them now.
notifyStartListeners(mReversing);
}
- mRunning = false;
- mStarted = false;
mLastFrameTime = -1;
mFirstFrameTime = -1;
mStartTime = -1;
+ mRunning = false;
+ mStarted = false;
notifyEndListeners(mReversing);
// mReversing needs to be reset *after* notifying the listeners for the end callbacks.
mReversing = false;
@@ -1687,7 +1669,6 @@
anim.mRunning = false;
anim.mPaused = false;
anim.mResumed = false;
- anim.mStartListenersCalled = false;
anim.mStartTime = -1;
anim.mStartTimeCommitted = false;
anim.mAnimationEndRequested = false;
diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java
index 35b26f5..bc108c3 100644
--- a/core/java/android/app/ActivityManager.java
+++ b/core/java/android/app/ActivityManager.java
@@ -236,6 +236,133 @@
final ArrayMap<OnUidImportanceListener, UidObserver> mImportanceListeners = new ArrayMap<>();
/**
+ * Map of callbacks that have registered for {@link UidFrozenStateChanged} events.
+ * Will be called when a Uid has become frozen or unfrozen.
+ */
+ final ArrayMap<UidFrozenStateChangedCallback, Executor> mFrozenStateChangedCallbacks =
+ new ArrayMap<>();
+
+ private final IUidFrozenStateChangedCallback mFrozenStateChangedCallback =
+ new IUidFrozenStateChangedCallback.Stub() {
+ @Override
+ public void onUidFrozenStateChanged(int[] uids, int[] frozenStates) {
+ synchronized (mFrozenStateChangedCallbacks) {
+ mFrozenStateChangedCallbacks.forEach((callback, executor) -> {
+ executor.execute(
+ () -> callback.onUidFrozenStateChanged(uids, frozenStates));
+ });
+ }
+ }
+ };
+
+ /**
+ * Callback object for {@link #registerUidFrozenStateChangedCallback}
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public interface UidFrozenStateChangedCallback {
+ /**
+ * Indicates that the UID was frozen.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ int UID_FROZEN_STATE_FROZEN = 1;
+
+ /**
+ * Indicates that the UID was unfrozen.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ int UID_FROZEN_STATE_UNFROZEN = 2;
+
+ /**
+ * @hide
+ */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(flag = false, prefix = {"UID_FROZEN_STATE_"}, value = {
+ UID_FROZEN_STATE_FROZEN,
+ UID_FROZEN_STATE_UNFROZEN,
+ })
+ public @interface UidFrozenState {}
+
+ /**
+ * @param uids The UIDs for which the frozen state has changed
+ * @param frozenStates Frozen state for each UID index, Will be set to
+ * {@link UidFrozenStateChangedCallback#UID_FROZEN_STATE_FROZEN}
+ * when the UID is frozen. When the UID is unfrozen,
+ * {@link UidFrozenStateChangedCallback#UID_FROZEN_STATE_UNFROZEN}
+ * will be set.
+ *
+ * @hide
+ */
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ void onUidFrozenStateChanged(@NonNull int[] uids,
+ @NonNull @UidFrozenState int[] frozenStates);
+ }
+
+ /**
+ * Register a {@link UidFrozenStateChangedCallback} object to receive notification
+ * when a UID is frozen or unfrozen. Will throw an exception if the same
+ * callback object is registered more than once.
+ *
+ * @param executor The executor that the callback will be run from.
+ * @param callback The callback to be registered. Callbacks for previous frozen/unfrozen
+ * UID changes will not be delivered. Only changes in state from the point of
+ * registration onward will be reported.
+ * @throws IllegalStateException if the {@code callback} is already registered.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public void registerUidFrozenStateChangedCallback(
+ @NonNull Executor executor,
+ @NonNull UidFrozenStateChangedCallback callback) {
+ synchronized (mFrozenStateChangedCallbacks) {
+ if (mFrozenStateChangedCallbacks.containsKey(callback)) {
+ throw new IllegalArgumentException("Callback already registered: " + callback);
+ }
+ mFrozenStateChangedCallbacks.put(callback, executor);
+ if (mFrozenStateChangedCallbacks.size() > 1) {
+ /* There's no need to register more than one binder interface */
+ return;
+ }
+
+ try {
+ getService().registerUidFrozenStateChangedCallback(mFrozenStateChangedCallback);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+
+ /**
+ * Unregister a {@link UidFrozenStateChangedCallback} callback.
+ * @param callback The callback to be unregistered.
+ *
+ * @hide
+ */
+ @RequiresPermission(Manifest.permission.PACKAGE_USAGE_STATS)
+ @SystemApi(client = SystemApi.Client.MODULE_LIBRARIES)
+ public void unregisterUidFrozenStateChangedCallback(
+ @NonNull UidFrozenStateChangedCallback callback) {
+ synchronized (mFrozenStateChangedCallbacks) {
+ mFrozenStateChangedCallbacks.remove(callback);
+ if (mFrozenStateChangedCallbacks.isEmpty()) {
+ try {
+ getService().unregisterUidFrozenStateChangedCallback(
+ mFrozenStateChangedCallback);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ }
+ }
+
+ /**
* <a href="{@docRoot}guide/topics/manifest/meta-data-element.html">{@code
* <meta-data>}</a> name for a 'home' Activity that declares a package that is to be
* uninstalled in lieu of the declaring one. The package named here must be
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java
index 90427cb..0293bb5 100644
--- a/core/java/android/app/ActivityManagerInternal.java
+++ b/core/java/android/app/ActivityManagerInternal.java
@@ -474,6 +474,12 @@
public abstract BackgroundStartPrivileges getBackgroundStartPrivileges(int uid);
public abstract void reportCurKeyguardUsageEvent(boolean keyguardShowing);
+ /**
+ * Returns whether the app is in a state where it is allowed to schedule a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}.
+ */
+ public abstract boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName);
+
/** @see com.android.server.am.ActivityManagerService#monitor */
public abstract void monitor();
@@ -994,6 +1000,16 @@
*/
public abstract void logFgsApiEnd(int apiType, int uid, int pid);
+ /**
+ * Temporarily allow foreground service started by an uid to have while-in-use permission
+ * for durationMs.
+ *
+ * @param uid The UID of the app that starts the foreground service.
+ * @param durationMs elapsedRealTime duration in milliseconds.
+ * @hide
+ */
+ public abstract void tempAllowWhileInUsePermissionInFgs(int uid, long durationMs);
+
/**
* The list of the events about the {@link android.media.projection.IMediaProjection} itself.
*
diff --git a/core/java/android/app/ActivityThread.java b/core/java/android/app/ActivityThread.java
index 2751b54..4306d78 100644
--- a/core/java/android/app/ActivityThread.java
+++ b/core/java/android/app/ActivityThread.java
@@ -119,6 +119,8 @@
import android.os.Build;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.DdmSyncStageUpdater;
+import android.os.DdmSyncState.Stage;
import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
@@ -264,6 +266,9 @@
*/
public final class ActivityThread extends ClientTransactionHandler
implements ActivityThreadInternal {
+
+ private final DdmSyncStageUpdater mDdmSyncStageUpdater = new DdmSyncStageUpdater();
+
/** @hide */
public static final String TAG = "ActivityThread";
private static final android.graphics.Bitmap.Config THUMBNAIL_FORMAT = Bitmap.Config.RGB_565;
@@ -5840,26 +5845,6 @@
r.activity.mChangingConfigurations = true;
- // If we are preserving the main window across relaunches we would also like to preserve
- // the children. However the client side view system does not support preserving
- // the child views so we notify the window manager to expect these windows to
- // be replaced and defer requests to destroy or hide them. This way we can achieve
- // visual continuity. It's important that we do this here prior to pause and destroy
- // as that is when we may hide or remove the child views.
- //
- // There is another scenario, if we have decided locally to relaunch the app from a
- // call to recreate, then none of the windows will be prepared for replacement or
- // preserved by the server, so we want to notify it that we are preparing to replace
- // everything
- try {
- if (r.mPreserveWindow) {
- WindowManagerGlobal.getWindowSession().prepareToReplaceWindows(
- r.token, true /* childrenOnly */);
- }
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
-
handleRelaunchActivityInner(r, configChanges, tmp.pendingResults, tmp.pendingIntents,
pendingActions, tmp.startsNotResumed, tmp.overrideConfig, "handleRelaunchActivity");
}
@@ -6709,6 +6694,8 @@
@UnsupportedAppUsage
private void handleBindApplication(AppBindData data) {
+ mDdmSyncStageUpdater.next(Stage.Bind);
+
// Register the UI Thread as a sensitive thread to the runtime.
VMRuntime.registerSensitiveThread();
// In the case the stack depth property exists, pass it down to the runtime.
@@ -6758,6 +6745,7 @@
data.appInfo.packageName,
UserHandle.myUserId());
VMRuntime.setProcessPackageName(data.appInfo.packageName);
+ mDdmSyncStageUpdater.next(Stage.Named);
// Pass data directory path to ART. This is used for caching information and
// should be set before any application code is loaded.
@@ -6962,6 +6950,7 @@
final StrictMode.ThreadPolicy writesAllowedPolicy = StrictMode.getThreadPolicy();
if (data.debugMode != ApplicationThreadConstants.DEBUG_OFF) {
+ mDdmSyncStageUpdater.next(Stage.Debugger);
if (data.debugMode == ApplicationThreadConstants.DEBUG_WAIT) {
waitForDebugger(data);
} else if (data.debugMode == ApplicationThreadConstants.DEBUG_SUSPEND) {
@@ -6969,6 +6958,7 @@
}
// Nothing special to do in case of DEBUG_ON.
}
+ mDdmSyncStageUpdater.next(Stage.Running);
try {
// If the app is being launched for full backup or restore, bring it up in
@@ -7872,6 +7862,7 @@
mConfigurationController = new ConfigurationController(this);
mSystemThread = system;
mStartSeq = startSeq;
+ mDdmSyncStageUpdater.next(Stage.Attach);
if (!system) {
android.ddm.DdmHandleAppName.setAppName("<pre-initialized>",
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index 6301ad7..999075d 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -2561,7 +2561,7 @@
public InstallSourceInfo getInstallSourceInfo(String packageName) throws NameNotFoundException {
final InstallSourceInfo installSourceInfo;
try {
- installSourceInfo = mPM.getInstallSourceInfo(packageName);
+ installSourceInfo = mPM.getInstallSourceInfo(packageName, getUserId());
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/android/app/BroadcastOptions.java b/core/java/android/app/BroadcastOptions.java
index a5095b2..d23d3cd 100644
--- a/core/java/android/app/BroadcastOptions.java
+++ b/core/java/android/app/BroadcastOptions.java
@@ -889,6 +889,8 @@
* <p> If neither matching key using {@link #setDeliveryGroupMatchingKey(String, String)} nor
* matching filter using this API is specified, then by default
* {@link Intent#filterEquals(Intent)} will be used to identify the delivery group.
+ *
+ * @hide
*/
@NonNull
public BroadcastOptions setDeliveryGroupMatchingFilter(@NonNull IntentFilter matchingFilter) {
@@ -902,6 +904,7 @@
*
* @return the {@link IntentFilter} object that was previously set using
* {@link #setDeliveryGroupMatchingFilter(IntentFilter)}.
+ * @hide
*/
@Nullable
public IntentFilter getDeliveryGroupMatchingFilter() {
@@ -911,6 +914,8 @@
/**
* Clears the {@link IntentFilter} object that was previously set using
* {@link #setDeliveryGroupMatchingFilter(IntentFilter)}.
+ *
+ * @hide
*/
public void clearDeliveryGroupMatchingFilter() {
mDeliveryGroupMatchingFilter = null;
diff --git a/core/java/android/app/IActivityManager.aidl b/core/java/android/app/IActivityManager.aidl
index 62298a5..2879062 100644
--- a/core/java/android/app/IActivityManager.aidl
+++ b/core/java/android/app/IActivityManager.aidl
@@ -35,6 +35,7 @@
import android.app.IStopUserCallback;
import android.app.ITaskStackListener;
import android.app.IUiAutomationConnection;
+import android.app.IUidFrozenStateChangedCallback;
import android.app.IUidObserver;
import android.app.IUserSwitchObserver;
import android.app.Notification;
@@ -877,4 +878,7 @@
/** Logs API state change to associate with an FGS, used for FGS Type Metrics */
void logFgsApiStateChanged(int apiType, int state, int appUid, int appPid);
+
+ void registerUidFrozenStateChangedCallback(in IUidFrozenStateChangedCallback callback);
+ void unregisterUidFrozenStateChangedCallback(in IUidFrozenStateChangedCallback callback);
}
diff --git a/core/java/android/app/INotificationManager.aidl b/core/java/android/app/INotificationManager.aidl
index ef9de18..5ba9e1d 100644
--- a/core/java/android/app/INotificationManager.aidl
+++ b/core/java/android/app/INotificationManager.aidl
@@ -127,13 +127,16 @@
// INotificationListener method.
@UnsupportedAppUsage
StatusBarNotification[] getActiveNotifications(String callingPkg);
+ @EnforcePermission("ACCESS_NOTIFICATIONS")
StatusBarNotification[] getActiveNotificationsWithAttribution(String callingPkg,
String callingAttributionTag);
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
StatusBarNotification[] getHistoricalNotifications(String callingPkg, int count, boolean includeSnoozed);
+ @EnforcePermission("ACCESS_NOTIFICATIONS")
StatusBarNotification[] getHistoricalNotificationsWithAttribution(String callingPkg,
String callingAttributionTag, int count, boolean includeSnoozed);
+ @EnforcePermission("ACCESS_NOTIFICATIONS")
NotificationHistory getNotificationHistory(String callingPkg, String callingAttributionTag);
void registerListener(in INotificationListener listener, in ComponentName component, int userid);
diff --git a/core/java/android/service/voice/DetectorFailure.aidl b/core/java/android/app/IUidFrozenStateChangedCallback.aidl
similarity index 72%
rename from core/java/android/service/voice/DetectorFailure.aidl
rename to core/java/android/app/IUidFrozenStateChangedCallback.aidl
index 3591329..d6d94da 100644
--- a/core/java/android/service/voice/DetectorFailure.aidl
+++ b/core/java/android/app/IUidFrozenStateChangedCallback.aidl
@@ -14,6 +14,12 @@
* limitations under the License.
*/
-package android.service.voice;
+package android.app;
-parcelable DetectorFailure;
+/** {@hide} */
+oneway interface IUidFrozenStateChangedCallback {
+ /**
+ * Report a new frozen state for the Uid list.
+ */
+ void onUidFrozenStateChanged(in int[] uids, in int[] frozenStates);
+}
diff --git a/core/java/android/app/Instrumentation.java b/core/java/android/app/Instrumentation.java
index ac92811..4dc7253 100644
--- a/core/java/android/app/Instrumentation.java
+++ b/core/java/android/app/Instrumentation.java
@@ -1151,7 +1151,7 @@
}
UserManager userManager = mInstrContext.getSystemService(UserManager.class);
- int userDisplayId = userManager.getDisplayIdAssignedToUser();
+ int userDisplayId = userManager.getMainDisplayIdAssignedToUser();
if (VERBOSE) {
Log.v(TAG, "setDisplayIfNeeded(" + event + "): eventDisplayId=" + eventDisplayId
+ ", user=" + mInstrContext.getUser() + ", userDisplayId=" + userDisplayId);
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e78fb17..4396503 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -3269,6 +3269,43 @@
/**
* @hide
*/
+ public static boolean areIconsDifferent(Notification first, Notification second) {
+ return areIconsMaybeDifferent(first.getSmallIcon(), second.getSmallIcon())
+ || areIconsMaybeDifferent(first.getLargeIcon(), second.getLargeIcon());
+ }
+
+ /**
+ * Note that we aren't actually comparing the contents of the bitmaps here; this is only a
+ * cursory inspection. We will not return false negatives, but false positives are likely.
+ */
+ private static boolean areIconsMaybeDifferent(Icon a, Icon b) {
+ if (a == b) {
+ return false;
+ }
+ if (a == null || b == null) {
+ return true;
+ }
+ if (a.sameAs(b)) {
+ return false;
+ }
+ final int aType = a.getType();
+ if (aType != b.getType()) {
+ return true;
+ }
+ if (aType == Icon.TYPE_BITMAP || aType == Icon.TYPE_ADAPTIVE_BITMAP) {
+ final Bitmap aBitmap = a.getBitmap();
+ final Bitmap bBitmap = b.getBitmap();
+ return aBitmap.getWidth() != bBitmap.getWidth()
+ || aBitmap.getHeight() != bBitmap.getHeight()
+ || aBitmap.getConfig() != bBitmap.getConfig()
+ || aBitmap.getGenerationId() != bBitmap.getGenerationId();
+ }
+ return true;
+ }
+
+ /**
+ * @hide
+ */
public static boolean areStyledNotificationsVisiblyDifferent(Builder first, Builder second) {
if (first.getStyle() == null) {
return second.getStyle() != null;
@@ -4634,9 +4671,9 @@
* Set whether this is an "ongoing" notification.
*
* Ongoing notifications cannot be dismissed by the user on locked devices, or by
- * notification listeners, and some notifications (device management, media) cannot be
- * dismissed on unlocked devices, so your application or service must take
- * care of canceling them.
+ * notification listeners, and some notifications (call, device management, media) cannot
+ * be dismissed on unlocked devices, so your application or service must take care of
+ * canceling them.
*
* They are typically used to indicate a background task that the user is actively engaged
* with (e.g., playing music) or is pending in some way and therefore occupying the device
@@ -7643,8 +7680,6 @@
/**
* @hide
- * Note that we aren't actually comparing the contents of the bitmaps here, so this
- * is only doing a cursory inspection. Bitmaps of equal size will appear the same.
*/
@Override
public boolean areNotificationsVisiblyDifferent(Style other) {
@@ -7652,32 +7687,7 @@
return true;
}
BigPictureStyle otherS = (BigPictureStyle) other;
- return areIconsObviouslyDifferent(getBigPicture(), otherS.getBigPicture());
- }
-
- private static boolean areIconsObviouslyDifferent(Icon a, Icon b) {
- if (a == b) {
- return false;
- }
- if (a == null || b == null) {
- return true;
- }
- if (a.sameAs(b)) {
- return false;
- }
- final int aType = a.getType();
- if (aType != b.getType()) {
- return true;
- }
- if (aType == Icon.TYPE_BITMAP || aType == Icon.TYPE_ADAPTIVE_BITMAP) {
- final Bitmap aBitmap = a.getBitmap();
- final Bitmap bBitmap = b.getBitmap();
- return aBitmap.getWidth() != bBitmap.getWidth()
- || aBitmap.getHeight() != bBitmap.getHeight()
- || aBitmap.getConfig() != bBitmap.getConfig()
- || aBitmap.getGenerationId() != bBitmap.getGenerationId();
- }
- return true;
+ return areIconsMaybeDifferent(getBigPicture(), otherS.getBigPicture());
}
}
@@ -9163,10 +9173,7 @@
* {@code null}, in which case the output switcher will be disabled.
* This intent should open an Activity or it will be ignored.
* @return MediaStyle
- *
- * @hide
*/
- @SystemApi
@RequiresPermission(android.Manifest.permission.MEDIA_CONTENT_CONTROL)
@NonNull
public MediaStyle setRemotePlaybackInfo(@NonNull CharSequence deviceName,
@@ -12093,10 +12100,7 @@
* <p>TV extensions can be accessed on an existing notification by using the
* {@code TvExtender(Notification)} constructor, and then using the {@code get} methods
* to access values.
- *
- * @hide
*/
- @SystemApi
public static final class TvExtender implements Extender {
private static final String TAG = "TvExtender";
@@ -12128,7 +12132,7 @@
*
* @param notif The notification from which to copy options.
*/
- public TvExtender(Notification notif) {
+ public TvExtender(@NonNull Notification notif) {
Bundle bundle = notif.extras == null ?
null : notif.extras.getBundle(EXTRA_TV_EXTENDER);
if (bundle != null) {
@@ -12146,7 +12150,8 @@
* method of {@link Notification.Builder}.
*/
@Override
- public Notification.Builder extend(Notification.Builder builder) {
+ @NonNull
+ public Notification.Builder extend(@NonNull Notification.Builder builder) {
Bundle bundle = new Bundle();
bundle.putInt(EXTRA_FLAGS, mFlags);
@@ -12165,7 +12170,7 @@
}
/**
- * Returns true if this notification should be shown on TV. This method return true
+ * Returns true if this notification should be shown on TV. This method returns true
* if the notification was extended with a TvExtender.
*/
public boolean isAvailableOnTv() {
@@ -12175,8 +12180,11 @@
/**
* Specifies the channel the notification should be delivered on when shown on TV.
* It can be different from the channel that the notification is delivered to when
- * posting on a non-TV device.
+ * posting on a non-TV device. Prefer to use {@link setChannelId(String)}.
+ *
+ * @hide
*/
+ @SystemApi
public TvExtender setChannel(String channelId) {
mChannelId = channelId;
return this;
@@ -12186,14 +12194,21 @@
* Specifies the channel the notification should be delivered on when shown on TV.
* It can be different from the channel that the notification is delivered to when
* posting on a non-TV device.
+ *
+ * @return this object for method chaining
*/
- public TvExtender setChannelId(String channelId) {
+ @NonNull
+ public TvExtender setChannelId(@Nullable String channelId) {
mChannelId = channelId;
return this;
}
- /** @removed */
+ /**
+ * @removed
+ * @hide
+ */
@Deprecated
+ @SystemApi
public String getChannel() {
return mChannelId;
}
@@ -12201,6 +12216,7 @@
/**
* Returns the id of the channel this notification posts to on TV.
*/
+ @Nullable
public String getChannelId() {
return mChannelId;
}
@@ -12209,8 +12225,12 @@
* Supplies a {@link PendingIntent} to be sent when the notification is selected on TV.
* If provided, it is used instead of the content intent specified
* at the level of Notification.
+ *
+ * @param intent the {@link PendingIntent} for the associated notification content
+ * @return this object for method chaining
*/
- public TvExtender setContentIntent(PendingIntent intent) {
+ @NonNull
+ public TvExtender setContentIntent(@Nullable PendingIntent intent) {
mContentIntent = intent;
return this;
}
@@ -12219,8 +12239,9 @@
* Returns the TV-specific content intent. If this method returns null, the
* main content intent on the notification should be used.
*
- * @see {@link Notification#contentIntent}
+ * @see Notification#contentIntent
*/
+ @Nullable
public PendingIntent getContentIntent() {
return mContentIntent;
}
@@ -12229,8 +12250,12 @@
* Supplies a {@link PendingIntent} to send when the notification is cleared explicitly
* by the user on TV. If provided, it is used instead of the delete intent specified
* at the level of Notification.
+ *
+ * @param intent the {@link PendingIntent} for the associated notification deletion
+ * @return this object for method chaining
*/
- public TvExtender setDeleteIntent(PendingIntent intent) {
+ @NonNull
+ public TvExtender setDeleteIntent(@Nullable PendingIntent intent) {
mDeleteIntent = intent;
return this;
}
@@ -12239,8 +12264,9 @@
* Returns the TV-specific delete intent. If this method returns null, the
* main delete intent on the notification should be used.
*
- * @see {@link Notification#deleteIntent}
+ * @see Notification#deleteIntent
*/
+ @Nullable
public PendingIntent getDeleteIntent() {
return mDeleteIntent;
}
@@ -12248,7 +12274,11 @@
/**
* Specifies whether this notification should suppress showing a message over top of apps
* outside of the launcher.
+ *
+ * @param suppress whether the notification should suppress showing over apps.
+ * @return this object for method chaining
*/
+ @NonNull
public TvExtender setSuppressShowOverApps(boolean suppress) {
mSuppressShowOverApps = suppress;
return this;
@@ -12257,10 +12287,21 @@
/**
* Returns true if this notification should not show messages over top of apps
* outside of the launcher.
+ *
+ * @hide
*/
+ @SystemApi
public boolean getSuppressShowOverApps() {
return mSuppressShowOverApps;
}
+
+ /**
+ * Returns true if this notification should not show messages over top of apps
+ * outside of the launcher.
+ */
+ public boolean isSuppressShowOverApps() {
+ return mSuppressShowOverApps;
+ }
}
/**
diff --git a/core/java/android/app/OWNERS b/core/java/android/app/OWNERS
index e72b141..f7d2afb 100644
--- a/core/java/android/app/OWNERS
+++ b/core/java/android/app/OWNERS
@@ -54,6 +54,9 @@
per-file Broadcast* = file:/BROADCASTS_OWNERS
per-file ReceiverInfo* = file:/BROADCASTS_OWNERS
+# KeyguardManager
+per-file KeyguardManager.java = file:/services/core/java/com/android/server/locksettings/OWNERS
+
# LocaleManager
per-file *Locale* = file:/services/core/java/com/android/server/locales/OWNERS
@@ -94,7 +97,5 @@
per-file ConfigurationController.java = file:/services/core/java/com/android/server/wm/OWNERS
per-file *ScreenCapture* = file:/services/core/java/com/android/server/wm/OWNERS
-# TODO(b/174932174): determine the ownership of KeyguardManager.java
-
# Zygote
per-file *Zygote* = file:/ZYGOTE_OWNERS
diff --git a/core/java/android/app/PendingIntent.java b/core/java/android/app/PendingIntent.java
index e0f5fb4..9bf56b3 100644
--- a/core/java/android/app/PendingIntent.java
+++ b/core/java/android/app/PendingIntent.java
@@ -892,10 +892,8 @@
* @param options Additional options the caller would like to provide to modify the
* sending behavior. May be built from an {@link ActivityOptions} to apply to an
* activity start.
- *
- * @hide
*/
- public void send(Bundle options) throws CanceledException {
+ public void send(@Nullable Bundle options) throws CanceledException {
send(null, 0, null, null, null, null, options);
}
diff --git a/core/java/android/app/TEST_MAPPING b/core/java/android/app/TEST_MAPPING
index 0bdc222..1df8602 100644
--- a/core/java/android/app/TEST_MAPPING
+++ b/core/java/android/app/TEST_MAPPING
@@ -42,10 +42,10 @@
},
{
"file_patterns": ["(/|^)AppOpsManager.java"],
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.RuntimePermissionProperties"
+ "include-filter": "android.permissionpolicy.cts.RuntimePermissionProperties"
}
]
},
diff --git a/core/java/android/app/TaskInfo.java b/core/java/android/app/TaskInfo.java
index 303ada0..404f94a 100644
--- a/core/java/android/app/TaskInfo.java
+++ b/core/java/android/app/TaskInfo.java
@@ -188,6 +188,14 @@
public int launchIntoPipHostTaskId;
/**
+ * The task id of the parent Task of the launch-into-pip Activity, i.e., if task have more than
+ * one activity it will create new task for this activity, this id is the origin task id and
+ * the pip activity will be reparent to origin task when it exit pip mode.
+ * @hide
+ */
+ public int lastParentTaskIdBeforePip;
+
+ /**
* The {@link Rect} copied from {@link DisplayCutout#getSafeInsets()} if the cutout is not of
* (LAYOUT_IN_DISPLAY_CUTOUT_MODE_SHORT_EDGES, LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS),
* {@code null} otherwise.
@@ -512,6 +520,7 @@
pictureInPictureParams = source.readTypedObject(PictureInPictureParams.CREATOR);
shouldDockBigOverlays = source.readBoolean();
launchIntoPipHostTaskId = source.readInt();
+ lastParentTaskIdBeforePip = source.readInt();
displayCutoutInsets = source.readTypedObject(Rect.CREATOR);
topActivityInfo = source.readTypedObject(ActivityInfo.CREATOR);
isResizeable = source.readBoolean();
@@ -558,6 +567,7 @@
dest.writeTypedObject(pictureInPictureParams, flags);
dest.writeBoolean(shouldDockBigOverlays);
dest.writeInt(launchIntoPipHostTaskId);
+ dest.writeInt(lastParentTaskIdBeforePip);
dest.writeTypedObject(displayCutoutInsets, flags);
dest.writeTypedObject(topActivityInfo, flags);
dest.writeBoolean(isResizeable);
@@ -598,6 +608,7 @@
+ " pictureInPictureParams=" + pictureInPictureParams
+ " shouldDockBigOverlays=" + shouldDockBigOverlays
+ " launchIntoPipHostTaskId=" + launchIntoPipHostTaskId
+ + " lastParentTaskIdBeforePip=" + lastParentTaskIdBeforePip
+ " displayCutoutSafeInsets=" + displayCutoutInsets
+ " topActivityInfo=" + topActivityInfo
+ " launchCookies=" + launchCookies
diff --git a/core/java/android/app/WallpaperManager.java b/core/java/android/app/WallpaperManager.java
index ff17824..540342b 100644
--- a/core/java/android/app/WallpaperManager.java
+++ b/core/java/android/app/WallpaperManager.java
@@ -16,6 +16,11 @@
package android.app;
+import static android.Manifest.permission.MANAGE_EXTERNAL_STORAGE;
+import static android.Manifest.permission.READ_WALLPAPER_INTERNAL;
+import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.os.ParcelFileDescriptor.MODE_READ_ONLY;
+
import android.annotation.FloatRange;
import android.annotation.IntDef;
import android.annotation.NonNull;
@@ -28,6 +33,9 @@
import android.annotation.SystemService;
import android.annotation.TestApi;
import android.annotation.UiContext;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -84,6 +92,7 @@
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
+import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
@@ -108,8 +117,26 @@
*/
@SystemService(Context.WALLPAPER_SERVICE)
public class WallpaperManager {
+
private static String TAG = "WallpaperManager";
private static final boolean DEBUG = false;
+
+ /**
+ * Trying to read the wallpaper file or bitmap in T will return
+ * the default wallpaper bitmap/file instead of throwing a SecurityException.
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
+ static final long RETURN_DEFAULT_ON_SECURITY_EXCEPTION = 239784307L;
+
+ /**
+ * In U and later, attempting to read the wallpaper file or bitmap will throw an exception,
+ * (except with the READ_WALLPAPER_INTERNAL permission).
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ static final long THROW_ON_SECURITY_EXCEPTION = 237508058L;
+
private float mWallpaperXStep = -1;
private float mWallpaperYStep = -1;
private static final @NonNull RectF LOCAL_COLOR_BOUNDS =
@@ -585,7 +612,8 @@
}
}
synchronized (this) {
- if (mCachedWallpaper != null && mCachedWallpaper.isValid(userId, which)) {
+ if (mCachedWallpaper != null && mCachedWallpaper.isValid(userId, which) && context
+ .checkSelfPermission(READ_WALLPAPER_INTERNAL) == PERMISSION_GRANTED) {
return mCachedWallpaper.mCachedWallpaper;
}
mCachedWallpaper = null;
@@ -596,6 +624,19 @@
} catch (OutOfMemoryError e) {
Log.w(TAG, "Out of memory loading the current wallpaper: " + e);
} catch (SecurityException e) {
+ /*
+ * Apps with target SDK <= S can still access the wallpaper through
+ * READ_EXTERNAL_STORAGE. In T however, app that previously had access to the
+ * wallpaper via READ_EXTERNAL_STORAGE will get a SecurityException here.
+ * Thus, in T specifically, return the default wallpaper instead of crashing.
+ */
+ if (CompatChanges.isChangeEnabled(RETURN_DEFAULT_ON_SECURITY_EXCEPTION)
+ && !CompatChanges.isChangeEnabled(THROW_ON_SECURITY_EXCEPTION)) {
+ Log.w(TAG, "No permission to access wallpaper, returning default"
+ + " wallpaper to avoid crashing legacy app.");
+ return getDefaultWallpaper(context, FLAG_SYSTEM);
+ }
+
if (context.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O_MR1) {
Log.w(TAG, "No permission to access wallpaper, suppressing"
+ " exception to avoid crashing legacy app.");
@@ -808,6 +849,18 @@
}
/**
+ * <strong> Important note: </strong>
+ * <ul>
+ * <li>Up to version S, this method requires the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
+ * <li>Starting in T, directly accessing the wallpaper is not possible anymore,
+ * instead the default system wallpaper is returned
+ * (some versions of T may throw a {@code SecurityException}).</li>
+ * <li>From version U, this method should not be used
+ * and will always throw a @code SecurityException}.</li>
+ * </ul>
+ * <br>
+ *
* Retrieve the current system wallpaper; if
* no wallpaper is set, the system built-in static wallpaper is returned.
* This is returned as an
@@ -821,14 +874,28 @@
* @return Returns a Drawable object that will draw the system wallpaper,
* or {@code null} if no system wallpaper exists or if the calling application
* is not able to access the wallpaper.
+ *
+ * @throws SecurityException as described in the note
*/
- @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
@Nullable
+ @RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
public Drawable getDrawable() {
return getDrawable(FLAG_SYSTEM);
}
/**
+ * <strong> Important note: </strong>
+ * <ul>
+ * <li>Up to version S, this method requires the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
+ * <li>Starting in T, directly accessing the wallpaper is not possible anymore,
+ * instead the default system wallpaper is returned
+ * (some versions of T may throw a {@code SecurityException}).</li>
+ * <li>From version U, this method should not be used
+ * and will always throw a @code SecurityException}.</li>
+ * </ul>
+ * <br>
+ *
* Retrieve the requested wallpaper; if
* no wallpaper is set, the requested built-in static wallpaper is returned.
* This is returned as an
@@ -844,9 +911,11 @@
* @return Returns a Drawable object that will draw the requested wallpaper,
* or {@code null} if the requested wallpaper does not exist or if the calling application
* is not able to access the wallpaper.
+ *
+ * @throws SecurityException as described in the note
*/
- @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
@Nullable
+ @RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
public Drawable getDrawable(@SetWallpaperFlags int which) {
final ColorManagementProxy cmProxy = getColorManagementProxy();
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, which, cmProxy);
@@ -1069,6 +1138,18 @@
}
/**
+ * <strong> Important note: </strong>
+ * <ul>
+ * <li>Up to version S, this method requires the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
+ * <li>Starting in T, directly accessing the wallpaper is not possible anymore,
+ * instead the default system wallpaper is returned
+ * (some versions of T may throw a {@code SecurityException}).</li>
+ * <li>From version U, this method should not be used
+ * and will always throw a @code SecurityException}.</li>
+ * </ul>
+ * <br>
+ *
* Retrieve the current system wallpaper; if there is no wallpaper set,
* a null pointer is returned. This is returned as an
* abstract Drawable that you can install in a View to display whatever
@@ -1076,13 +1157,28 @@
*
* @return Returns a Drawable object that will draw the wallpaper or a
* null pointer if wallpaper is unset.
+ *
+ * @throws SecurityException as described in the note
*/
@Nullable
+ @RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
public Drawable peekDrawable() {
return peekDrawable(FLAG_SYSTEM);
}
/**
+ * <strong> Important note: </strong>
+ * <ul>
+ * <li>Up to version S, this method requires the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
+ * <li>Starting in T, directly accessing the wallpaper is not possible anymore,
+ * instead the default system wallpaper is returned
+ * (some versions of T may throw a {@code SecurityException}).</li>
+ * <li>From version U, this method should not be used
+ * and will always throw a @code SecurityException}.</li>
+ * </ul>
+ * <br>
+ *
* Retrieve the requested wallpaper; if there is no wallpaper set,
* a null pointer is returned. This is returned as an
* abstract Drawable that you can install in a View to display whatever
@@ -1092,11 +1188,14 @@
* IllegalArgumentException if an invalid wallpaper is requested.
* @return Returns a Drawable object that will draw the wallpaper or a null pointer if
* wallpaper is unset.
+ *
+ * @throws SecurityException as described in the note
*/
@Nullable
+ @RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
public Drawable peekDrawable(@SetWallpaperFlags int which) {
final ColorManagementProxy cmProxy = getColorManagementProxy();
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, which, cmProxy);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, which, cmProxy);
if (bm != null) {
Drawable dr = new BitmapDrawable(mContext.getResources(), bm);
dr.setDither(false);
@@ -1106,6 +1205,18 @@
}
/**
+ * <strong> Important note: </strong>
+ * <ul>
+ * <li>Up to version S, this method requires the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
+ * <li>Starting in T, directly accessing the wallpaper is not possible anymore,
+ * instead the default wallpaper is returned
+ * (some versions of T may throw a {@code SecurityException}).</li>
+ * <li>From version U, this method should not be used
+ * and will always throw a @code SecurityException}.</li>
+ * </ul>
+ * <br>
+ *
* Like {@link #getDrawable()}, but the returned Drawable has a number
* of limitations to reduce its overhead as much as possible. It will
* never scale the wallpaper (only centering it if the requested bounds
@@ -1117,14 +1228,28 @@
* the same density as the screen (not in density compatibility mode).
*
* @return Returns a Drawable object that will draw the wallpaper.
+ *
+ * @throws SecurityException as described in the note
*/
- @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
@Nullable
+ @RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
public Drawable getFastDrawable() {
return getFastDrawable(FLAG_SYSTEM);
}
/**
+ * <strong> Important note: </strong>
+ * <ul>
+ * <li>Up to version S, this method requires the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
+ * <li>Starting in T, directly accessing the wallpaper is not possible anymore,
+ * instead the default system wallpaper is returned
+ * (some versions of T may throw a {@code SecurityException}).</li>
+ * <li>From version U, this method should not be used
+ * and will always throw a @code SecurityException}.</li>
+ * </ul>
+ * <br>
+ *
* Like {@link #getDrawable(int)}, but the returned Drawable has a number
* of limitations to reduce its overhead as much as possible. It will
* never scale the wallpaper (only centering it if the requested bounds
@@ -1138,9 +1263,11 @@
* @param which The {@code FLAG_*} identifier of a valid wallpaper type. Throws
* IllegalArgumentException if an invalid wallpaper is requested.
* @return Returns a Drawable object that will draw the wallpaper.
+ *
+ * @throws SecurityException as described in the note
*/
- @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
@Nullable
+ @RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
public Drawable getFastDrawable(@SetWallpaperFlags int which) {
final ColorManagementProxy cmProxy = getColorManagementProxy();
Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, which, cmProxy);
@@ -1151,19 +1278,45 @@
}
/**
+ * <strong> Important note: </strong>
+ * <ul>
+ * <li>Up to version S, this method requires the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
+ * <li>Starting in T, directly accessing the wallpaper is not possible anymore,
+ * instead the default system wallpaper is returned
+ * (some versions of T may throw a {@code SecurityException}).</li>
+ * <li>From version U, this method should not be used
+ * and will always throw a @code SecurityException}.</li>
+ * </ul>
+ * <br>
+ *
* Like {@link #getFastDrawable()}, but if there is no wallpaper set,
* a null pointer is returned.
*
* @return Returns an optimized Drawable object that will draw the
* wallpaper or a null pointer if these is none.
+ *
+ * @throws SecurityException as described in the note
*/
- @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
@Nullable
+ @RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
public Drawable peekFastDrawable() {
return peekFastDrawable(FLAG_SYSTEM);
}
/**
+ * <strong> Important note: </strong>
+ * <ul>
+ * <li>Up to version S, this method requires the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
+ * <li>Starting in T, directly accessing the wallpaper is not possible anymore,
+ * instead the default system wallpaper is returned
+ * (some versions of T may throw a {@code SecurityException}).</li>
+ * <li>From version U, this method should not be used
+ * and will always throw a @code SecurityException}.</li>
+ * </ul>
+ * <br>
+ *
* Like {@link #getFastDrawable()}, but if there is no wallpaper set,
* a null pointer is returned.
*
@@ -1171,12 +1324,14 @@
* IllegalArgumentException if an invalid wallpaper is requested.
* @return Returns an optimized Drawable object that will draw the
* wallpaper or a null pointer if these is none.
+ *
+ * @throws SecurityException as described in the note
*/
- @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
@Nullable
+ @RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
public Drawable peekFastDrawable(@SetWallpaperFlags int which) {
final ColorManagementProxy cmProxy = getColorManagementProxy();
- Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, false, which, cmProxy);
+ Bitmap bm = sGlobals.peekWallpaperBitmap(mContext, true, which, cmProxy);
if (bm != null) {
return new FastBitmapDrawable(bm);
}
@@ -1194,7 +1349,6 @@
* @hide
*/
@TestApi
- @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
public boolean wallpaperSupportsWcg(int which) {
if (!shouldEnableWideColorGamut()) {
return false;
@@ -1295,6 +1449,18 @@
}
/**
+ * <strong> Important note: </strong>
+ * <ul>
+ * <li>Up to version S, this method requires the
+ * {@link android.Manifest.permission#READ_EXTERNAL_STORAGE} permission.</li>
+ * <li>Starting in T, directly accessing the wallpaper is not possible anymore,
+ * instead the default system wallpaper is returned
+ * (some versions of T may throw a {@code SecurityException}).</li>
+ * <li>From version U, this method should not be used
+ * and will always throw a @code SecurityException}.</li>
+ * </ul>
+ * <br>
+ *
* Get an open, readable file descriptor to the given wallpaper image file.
* The caller is responsible for closing the file descriptor when done ingesting the file.
*
@@ -1305,14 +1471,17 @@
* @param which The wallpaper whose image file is to be retrieved. Must be a single
* defined kind of wallpaper, either {@link #FLAG_SYSTEM} or
* {@link #FLAG_LOCK}.
- * @return An open, readable file desriptor to the requested wallpaper image file;
+ * @return An open, readable file descriptor to the requested wallpaper image file;
* or {@code null} if no such wallpaper is configured or if the calling app does
* not have permission to read the current wallpaper.
*
* @see #FLAG_LOCK
* @see #FLAG_SYSTEM
+ *
+ * @throws SecurityException as described in the note
*/
- @RequiresPermission(android.Manifest.permission.READ_EXTERNAL_STORAGE)
+ @Nullable
+ @RequiresPermission(anyOf = {MANAGE_EXTERNAL_STORAGE, READ_WALLPAPER_INTERNAL})
public ParcelFileDescriptor getWallpaperFile(@SetWallpaperFlags int which) {
return getWallpaperFile(which, mContext.getUserId());
}
@@ -1475,13 +1644,18 @@
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
} catch (SecurityException e) {
+ if (CompatChanges.isChangeEnabled(RETURN_DEFAULT_ON_SECURITY_EXCEPTION)
+ && !CompatChanges.isChangeEnabled(THROW_ON_SECURITY_EXCEPTION)) {
+ Log.w(TAG, "No permission to access wallpaper, returning default"
+ + " wallpaper file to avoid crashing legacy app.");
+ return getDefaultSystemWallpaperFile();
+ }
if (mContext.getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.O_MR1) {
Log.w(TAG, "No permission to access wallpaper, suppressing"
+ " exception to avoid crashing legacy app.");
return null;
- } else {
- throw e;
}
+ throw e;
}
}
}
@@ -2586,6 +2760,24 @@
return null;
}
+ /**
+ * util used in T to return a default system wallpaper file
+ * when third party apps attempt to read the wallpaper with {@link #getWallpaperFile}
+ */
+ private static ParcelFileDescriptor getDefaultSystemWallpaperFile() {
+ for (String path: getDefaultSystemWallpaperPaths()) {
+ File file = new File(path);
+ if (file.exists()) {
+ try {
+ return ParcelFileDescriptor.open(file, MODE_READ_ONLY);
+ } catch (FileNotFoundException e) {
+ // continue; default wallpaper file not found on this path
+ }
+ }
+ }
+ return null;
+ }
+
private static InputStream getWallpaperInputStream(String path) {
if (!TextUtils.isEmpty(path)) {
final File file = new File(path);
@@ -2600,6 +2792,14 @@
return null;
}
+ /**
+ * @return a list of paths to the system default wallpapers, in order of priority:
+ * if the file exists for the first path of this list, the first path should be used.
+ */
+ private static List<String> getDefaultSystemWallpaperPaths() {
+ return List.of(SystemProperties.get(PROP_WALLPAPER), getCmfWallpaperPath());
+ }
+
private static String getCmfWallpaperPath() {
return Environment.getProductDirectory() + WALLPAPER_CMF_PATH + "default_wallpaper_"
+ VALUE_CMF_COLOR;
diff --git a/core/java/android/app/admin/AccountTypePolicyKey.java b/core/java/android/app/admin/AccountTypePolicyKey.java
index 6417cd4..9e376a7 100644
--- a/core/java/android/app/admin/AccountTypePolicyKey.java
+++ b/core/java/android/app/admin/AccountTypePolicyKey.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Parcel;
@@ -49,6 +50,7 @@
/**
* @hide
*/
+ @TestApi
public AccountTypePolicyKey(@NonNull String key, @NonNull String accountType) {
super(key);
mAccountType = Objects.requireNonNull((accountType));
diff --git a/core/java/android/app/admin/DevicePolicyManager.java b/core/java/android/app/admin/DevicePolicyManager.java
index 443a5b5..bad6c77 100644
--- a/core/java/android/app/admin/DevicePolicyManager.java
+++ b/core/java/android/app/admin/DevicePolicyManager.java
@@ -57,6 +57,7 @@
import android.Manifest.permission;
import android.accounts.Account;
+import android.annotation.BroadcastBehavior;
import android.annotation.CallbackExecutor;
import android.annotation.ColorInt;
import android.annotation.IntDef;
@@ -3998,6 +3999,27 @@
public static final String EXTRA_RESOURCE_IDS =
"android.app.extra.RESOURCE_IDS";
+ /**
+ * Broadcast Action: Broadcast sent to indicate that the device financing state has changed.
+ *
+ * <p>This occurs when, for example, a financing kiosk app has been added or removed.
+ *
+ * <p>To query the current device financing state see {@link #isDeviceFinanced}.
+ *
+ * <p>This will be delivered to the following apps if they include a receiver for this action
+ * in their manifest:
+ * <ul>
+ * <li>Device owner admins.
+ * <li>Organization-owned profile owner admins
+ * <li>The supervision app
+ * <li>The device management role holder
+ * </ul>
+ */
+ @SdkConstant(SdkConstant.SdkConstantType.BROADCAST_INTENT_ACTION)
+ @BroadcastBehavior(explicitOnly = true, includeBackground = true)
+ public static final String ACTION_DEVICE_FINANCING_STATE_CHANGED =
+ "android.app.admin.action.DEVICE_FINANCING_STATE_CHANGED";
+
/** Allow the user to choose whether to enable MTE on the device. */
public static final int MTE_NOT_CONTROLLED_BY_POLICY = 0;
@@ -15818,9 +15840,8 @@
* Called by a device owner or a profile owner or holder of the permission
* {@link android.Manifest.permission#MANAGE_DEVICE_POLICY_APPS_CONTROL} to disable user
* control over apps. User will not be able to clear app data or force-stop packages. When
- * called by a device owner, applies to all users on the device. Starting from Android 13,
- * packages with user control disabled are exempted from being put in the "restricted" App
- * Standby Bucket.
+ * called by a device owner, applies to all users on the device. Packages with user control
+ * disabled are exempted from App Standby Buckets.
*
* @param admin Which {@link DeviceAdminReceiver} this request is associated with. Null if the
* caller is not a device admin.
@@ -16880,4 +16901,55 @@
}
return false;
}
+
+ /**
+ * Returns {@code true} if this device is marked as a financed device.
+ *
+ * <p>A financed device can be entered into lock task mode (see {@link #setLockTaskPackages})
+ * by the holder of the role {@link android.app.role.RoleManager#ROLE_FINANCED_DEVICE_KIOSK}.
+ * If this occurs, Device Owners and Profile Owners that have set lock task packages or
+ * features, or that attempt to set lock task packages or features, will receive a callback
+ * indicating that it could not be set. See {@link PolicyUpdateReceiver#onPolicyChanged} and
+ * {@link PolicyUpdateReceiver#onPolicySetResult}.
+ *
+ * <p>To be informed of changes to this status you can subscribe to the broadcast
+ * {@link ACTION_DEVICE_FINANCING_STATE_CHANGED}.
+ *
+ * @throws SecurityException if the caller is not a device owner, profile owner of an
+ * organization-owned managed profile, profile owner on the primary user or holder of one of the
+ * following roles: {@link android.app.role.RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT},
+ * android.app.role.RoleManager.ROLE_SYSTEM_SUPERVISION.
+ */
+ public boolean isDeviceFinanced() {
+ if (mService != null) {
+ try {
+ return mService.isDeviceFinanced(mContext.getPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Returns the package name of the application holding the role:
+ * {@link android.app.role.RoleManager#ROLE_FINANCED_DEVICE_KIOSK}.
+ *
+ * @return the package name of the application holding the role or {@code null} if the role is
+ * not held by any applications.
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+ @Nullable
+ public String getFinancedDeviceKioskRoleHolder() {
+ if (mService != null) {
+ try {
+ return mService.getFinancedDeviceKioskRoleHolder(mContext.getPackageName());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+ return null;
+ }
}
diff --git a/core/java/android/app/admin/IDevicePolicyManager.aidl b/core/java/android/app/admin/IDevicePolicyManager.aidl
index a2520df..8d508c0 100644
--- a/core/java/android/app/admin/IDevicePolicyManager.aidl
+++ b/core/java/android/app/admin/IDevicePolicyManager.aidl
@@ -605,4 +605,7 @@
void setOverrideKeepProfilesRunning(boolean enabled);
boolean triggerDevicePolicyEngineMigration(boolean forceMigration);
+
+ boolean isDeviceFinanced(String callerPackageName);
+ String getFinancedDeviceKioskRoleHolder(String callerPackageName);
}
diff --git a/core/java/android/app/admin/IntentFilterPolicyKey.java b/core/java/android/app/admin/IntentFilterPolicyKey.java
index b0af4cd..30aad96 100644
--- a/core/java/android/app/admin/IntentFilterPolicyKey.java
+++ b/core/java/android/app/admin/IntentFilterPolicyKey.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.content.IntentFilter;
import android.os.Bundle;
import android.os.Parcel;
@@ -49,6 +50,7 @@
/**
* @hide
*/
+ @TestApi
public IntentFilterPolicyKey(@NonNull String identifier, @NonNull IntentFilter filter) {
super(identifier);
mFilter = Objects.requireNonNull(filter);
diff --git a/core/java/android/app/admin/PackagePermissionPolicyKey.java b/core/java/android/app/admin/PackagePermissionPolicyKey.java
index 08c4224..7fd514c 100644
--- a/core/java/android/app/admin/PackagePermissionPolicyKey.java
+++ b/core/java/android/app/admin/PackagePermissionPolicyKey.java
@@ -24,6 +24,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -53,6 +54,7 @@
/**
* @hide
*/
+ @TestApi
public PackagePermissionPolicyKey(@NonNull String identifier, @NonNull String packageName,
@NonNull String permissionName) {
super(identifier);
diff --git a/core/java/android/app/admin/PackagePolicyKey.java b/core/java/android/app/admin/PackagePolicyKey.java
index b2a8d5d..2ab00bc 100644
--- a/core/java/android/app/admin/PackagePolicyKey.java
+++ b/core/java/android/app/admin/PackagePolicyKey.java
@@ -23,6 +23,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -50,6 +51,7 @@
/**
* @hide
*/
+ @TestApi
public PackagePolicyKey(@NonNull String key, @NonNull String packageName) {
super(key);
mPackageName = Objects.requireNonNull((packageName));
diff --git a/core/java/android/app/admin/UserRestrictionPolicyKey.java b/core/java/android/app/admin/UserRestrictionPolicyKey.java
index 880b58b..aeb2380 100644
--- a/core/java/android/app/admin/UserRestrictionPolicyKey.java
+++ b/core/java/android/app/admin/UserRestrictionPolicyKey.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
+import android.annotation.TestApi;
import android.os.Bundle;
import android.os.Parcel;
@@ -40,6 +41,7 @@
/**
* @hide
*/
+ @TestApi
public UserRestrictionPolicyKey(@NonNull String identifier, @NonNull String restriction) {
super(identifier);
mRestriction = Objects.requireNonNull(restriction);
diff --git a/core/java/android/app/ambientcontext/IAmbientContextManager.aidl b/core/java/android/app/ambientcontext/IAmbientContextManager.aidl
index 8f06e76..a06bdd3 100644
--- a/core/java/android/app/ambientcontext/IAmbientContextManager.aidl
+++ b/core/java/android/app/ambientcontext/IAmbientContextManager.aidl
@@ -35,6 +35,7 @@
void registerObserverWithCallback(in AmbientContextEventRequest request,
String packageName,
in IAmbientContextObserver observer);
+ @EnforcePermission("ACCESS_AMBIENT_CONTEXT_EVENT")
void unregisterObserver(in String callingPackage);
void queryServiceStatus(in int[] eventTypes, in String callingPackage,
in RemoteCallback statusCallback);
diff --git a/core/java/android/companion/virtual/VirtualDeviceManager.java b/core/java/android/companion/virtual/VirtualDeviceManager.java
index 90681cb..f0011ad 100644
--- a/core/java/android/companion/virtual/VirtualDeviceManager.java
+++ b/core/java/android/companion/virtual/VirtualDeviceManager.java
@@ -545,8 +545,13 @@
@VirtualDisplayFlag int flags,
@Nullable @CallbackExecutor Executor executor,
@Nullable VirtualDisplay.Callback callback) {
+ // Currently this just use the device ID, which means all of the virtual displays
+ // created using the same virtual device will have the same name if they use this
+ // deprecated API. The name should only be used for informational purposes, and not for
+ // identifying the display in code.
+ String virtualDisplayName = "VirtualDevice_" + getDeviceId();
VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
- getVirtualDisplayName(), width, height, densityDpi)
+ virtualDisplayName, width, height, densityDpi)
.setFlags(flags);
if (surface != null) {
builder.setSurface(surface);
@@ -603,6 +608,10 @@
mVirtualAudioDevice.close();
mVirtualAudioDevice = null;
}
+ if (mVirtualCameraDevice != null) {
+ mVirtualCameraDevice.close();
+ mVirtualCameraDevice = null;
+ }
}
/**
@@ -858,18 +867,6 @@
}
}
- private String getVirtualDisplayName() {
- try {
- // Currently this just use the device ID, which means all of the virtual displays
- // created using the same virtual device will have the same name. The name should
- // only be used for informational purposes, and not for identifying the display in
- // code.
- return "VirtualDevice_" + mVirtualDevice.getDeviceId();
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
/**
* Adds an activity listener to listen for events such as top activity change or virtual
* display task stack became empty.
diff --git a/core/java/android/content/ContentProvider.java b/core/java/android/content/ContentProvider.java
index aa302ad..2674985 100644
--- a/core/java/android/content/ContentProvider.java
+++ b/core/java/android/content/ContentProvider.java
@@ -309,14 +309,30 @@
try {
if (checkGetTypePermission(attributionSource, uri)
== PermissionChecker.PERMISSION_GRANTED) {
- final String type = mInterface.getType(uri);
+ String type;
+ if (checkPermission(Manifest.permission.GET_ANY_PROVIDER_TYPE,
+ attributionSource) == PermissionChecker.PERMISSION_GRANTED) {
+ /*
+ For calling packages having the special permission for any type,
+ the calling identity should be cleared before calling getType.
+ */
+ final CallingIdentity origId = getContentProvider().clearCallingIdentity();
+ try {
+ type = mInterface.getType(uri);
+ } finally {
+ getContentProvider().restoreCallingIdentity(origId);
+ }
+ } else {
+ type = mInterface.getType(uri);
+ }
+
if (type != null) {
logGetTypeData(Binder.getCallingUid(), uri, type, true);
}
return type;
} else {
final int callingUid = Binder.getCallingUid();
- final long origId = Binder.clearCallingIdentity();
+ final CallingIdentity origId = getContentProvider().clearCallingIdentity();
try {
final String type = getTypeAnonymous(uri);
if (type != null) {
@@ -324,7 +340,7 @@
}
return type;
} finally {
- Binder.restoreCallingIdentity(origId);
+ getContentProvider().restoreCallingIdentity(origId);
}
}
} catch (RemoteException e) {
diff --git a/core/java/android/content/IClipboard.aidl b/core/java/android/content/IClipboard.aidl
index fe7798f..e0fba1d 100644
--- a/core/java/android/content/IClipboard.aidl
+++ b/core/java/android/content/IClipboard.aidl
@@ -28,6 +28,7 @@
interface IClipboard {
void setPrimaryClip(in ClipData clip, String callingPackage, String attributionTag, int userId,
int deviceId);
+ @EnforcePermission("SET_CLIP_SOURCE")
void setPrimaryClipAsPackage(in ClipData clip, String callingPackage, String attributionTag,
int userId, int deviceId, String sourcePackage);
void clearPrimaryClip(String callingPackage, String attributionTag, int userId, int deviceId);
@@ -46,6 +47,7 @@
boolean hasClipboardText(String callingPackage, String attributionTag, int userId,
int deviceId);
+ @EnforcePermission("SET_CLIP_SOURCE")
String getPrimaryClipSource(String callingPackage, String attributionTag, int userId,
int deviceId);
diff --git a/core/java/android/content/IContentService.aidl b/core/java/android/content/IContentService.aidl
index 127466d..0d11c78 100644
--- a/core/java/android/content/IContentService.aidl
+++ b/core/java/android/content/IContentService.aidl
@@ -160,6 +160,7 @@
* @param cname component to identify sync service, must be null if account/providerName are
* non-null.
*/
+ @EnforcePermission("READ_SYNC_STATS")
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
boolean isSyncActive(in Account account, String authority, in ComponentName cname);
@@ -183,6 +184,7 @@
* non-null.
*/
boolean isSyncPending(in Account account, String authority, in ComponentName cname);
+ @EnforcePermission("READ_SYNC_STATS")
boolean isSyncPendingAsUser(in Account account, String authority, in ComponentName cname,
int userId);
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 667ec7e..df8da24 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -5914,6 +5914,7 @@
/**
* A Parcelable[] of {@link ChooserAction} objects to provide the Android Sharesheet with
* app-specific actions to be presented to the user when invoking {@link #ACTION_CHOOSER}.
+ * You can provide as many as five custom actions.
*/
public static final String EXTRA_CHOOSER_CUSTOM_ACTIONS =
"android.intent.extra.CHOOSER_CUSTOM_ACTIONS";
diff --git a/core/java/android/content/IntentFilter.java b/core/java/android/content/IntentFilter.java
index 5928a50..6ff4271 100644
--- a/core/java/android/content/IntentFilter.java
+++ b/core/java/android/content/IntentFilter.java
@@ -2204,6 +2204,7 @@
* <p> Subsequent calls to this method will override any previously set extras.
*
* @param extras The intent extras to match against.
+ * @hide
*/
public final void setExtras(@NonNull PersistableBundle extras) {
mExtras = extras;
@@ -2214,6 +2215,7 @@
*
* @return the extras that were previously set using {@link #setExtras(PersistableBundle)} or
* an empty {@link PersistableBundle} object if no extras were set.
+ * @hide
*/
public final @NonNull PersistableBundle getExtras() {
return mExtras == null ? new PersistableBundle() : mExtras;
diff --git a/core/java/android/content/pm/IPackageInstaller.aidl b/core/java/android/content/pm/IPackageInstaller.aidl
index e3016a4..ebe2aa3 100644
--- a/core/java/android/content/pm/IPackageInstaller.aidl
+++ b/core/java/android/content/pm/IPackageInstaller.aidl
@@ -59,6 +59,7 @@
void installExistingPackage(String packageName, int installFlags, int installReason,
in IntentSender statusReceiver, int userId, in List<String> whiteListedPermissions);
+ @EnforcePermission("INSTALL_PACKAGES")
void setPermissionsResult(int sessionId, boolean accepted);
void bypassNextStagedInstallerCheck(boolean value);
diff --git a/core/java/android/content/pm/IPackageInstallerSession.aidl b/core/java/android/content/pm/IPackageInstallerSession.aidl
index 081f263..ea69a2b 100644
--- a/core/java/android/content/pm/IPackageInstallerSession.aidl
+++ b/core/java/android/content/pm/IPackageInstallerSession.aidl
@@ -49,8 +49,11 @@
void seal();
List<String> fetchPackageNames();
+ @EnforcePermission("USE_INSTALLER_V2")
DataLoaderParamsParcel getDataLoaderParams();
+ @EnforcePermission("USE_INSTALLER_V2")
void addFile(int location, String name, long lengthBytes, in byte[] metadata, in byte[] signature);
+ @EnforcePermission("USE_INSTALLER_V2")
void removeFile(int location, String name);
boolean isMultiPackage();
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 132b9af..5749128 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -159,6 +159,7 @@
*/
ParceledListSlice getInstalledPackages(long flags, in int userId);
+ @EnforcePermission("GET_APP_METADATA")
@nullable ParcelFileDescriptor getAppMetadataFd(String packageName,
int userId);
@@ -247,7 +248,7 @@
@UnsupportedAppUsage
String getInstallerPackageName(in String packageName);
- InstallSourceInfo getInstallSourceInfo(in String packageName);
+ InstallSourceInfo getInstallSourceInfo(in String packageName, int userId);
void resetApplicationPreferences(int userId);
@@ -282,9 +283,11 @@
void addCrossProfileIntentFilter(in IntentFilter intentFilter, String ownerPackage,
int sourceUserId, int targetUserId, int flags);
+ @EnforcePermission("INTERACT_ACROSS_USERS_FULL")
boolean removeCrossProfileIntentFilter(in IntentFilter intentFilter, String ownerPackage,
int sourceUserId, int targetUserId, int flags);
+ @EnforcePermission("INTERACT_ACROSS_USERS_FULL")
void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage);
String[] setDistractingPackageRestrictionsAsUser(in String[] packageNames, int restrictionFlags,
@@ -416,6 +419,7 @@
* @param observer call back used to notify when
* the operation is completed
*/
+ @EnforcePermission("CLEAR_APP_CACHE")
void freeStorageAndNotify(in String volumeUuid, in long freeStorageSize,
int storageFlags, IPackageDataObserver observer);
@@ -440,6 +444,7 @@
* notify when the operation is completed.May be null
* to indicate that no call back is desired.
*/
+ @EnforcePermission("CLEAR_APP_CACHE")
void freeStorage(in String volumeUuid, in long freeStorageSize,
int storageFlags, in IntentSender pi);
@@ -467,6 +472,7 @@
* files need to be deleted
* @param observer a callback used to notify when the operation is completed.
*/
+ @EnforcePermission("CLEAR_APP_USER_DATA")
void clearApplicationUserData(in String packageName, IPackageDataObserver observer, int userId);
/**
@@ -576,14 +582,20 @@
boolean performDexOptSecondary(String packageName,
String targetCompilerFilter, boolean force);
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
int getMoveStatus(int moveId);
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void registerMoveCallback(in IPackageMoveObserver callback);
+ @EnforcePermission("MOUNT_UNMOUNT_FILESYSTEMS")
void unregisterMoveCallback(in IPackageMoveObserver callback);
+ @EnforcePermission("MOVE_PACKAGE")
int movePackage(in String packageName, in String volumeUuid);
+ @EnforcePermission("MOVE_PACKAGE")
int movePrimaryStorage(in String volumeUuid);
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
boolean setInstallLocation(int loc);
@UnsupportedAppUsage
int getInstallLocation();
@@ -604,6 +616,7 @@
ParceledListSlice getIntentFilterVerifications(String packageName);
ParceledListSlice getAllIntentFilters(String packageName);
+ @EnforcePermission("PACKAGE_VERIFICATION_AGENT")
VerifierDeviceIdentity getVerifierDeviceIdentity();
boolean isFirstBoot();
@@ -613,6 +626,7 @@
@UnsupportedAppUsage
boolean isStorageLow();
+ @EnforcePermission("MANAGE_USERS")
@UnsupportedAppUsage
boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden, int userId);
boolean getApplicationHiddenSettingAsUser(String packageName, int userId);
@@ -623,6 +637,7 @@
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
IPackageInstaller getPackageInstaller();
+ @EnforcePermission("DELETE_PACKAGES")
boolean setBlockUninstallForUser(String packageName, boolean blockUninstall, int userId);
@UnsupportedAppUsage
boolean getBlockUninstallForUser(String packageName, int userId);
@@ -648,6 +663,7 @@
* Sets whether or not an update is available. Ostensibly for instant apps
* to force exteranl resolution.
*/
+ @EnforcePermission("INSTALL_PACKAGES")
void setUpdateAvailable(String packageName, boolean updateAvaialble);
@UnsupportedAppUsage(maxTargetSdk = 30, trackingBug = 170729553)
@@ -675,6 +691,7 @@
ComponentName getInstantAppInstallerComponent();
+ @EnforcePermission("ACCESS_INSTANT_APPS")
String getInstantAppAndroidId(String packageName, int userId);
IArtManager getArtManager();
@@ -773,6 +790,7 @@
void makeProviderVisible(int recipientAppId, String visibleAuthority);
+ @EnforcePermission("MAKE_UID_VISIBLE")
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ ".permission.MAKE_UID_VISIBLE)")
void makeUidVisible(int recipientAppId, int visibleUid);
diff --git a/core/java/android/content/pm/PackageInstaller.java b/core/java/android/content/pm/PackageInstaller.java
index cb988df..77d32a5 100644
--- a/core/java/android/content/pm/PackageInstaller.java
+++ b/core/java/android/content/pm/PackageInstaller.java
@@ -334,17 +334,6 @@
public static final String EXTRA_DATA_LOADER_TYPE = "android.content.pm.extra.DATA_LOADER_TYPE";
/**
- * Path to the validated base APK for this session, which may point at an
- * APK inside the session (when the session defines the base), or it may
- * point at the existing base APK (when adding splits to an existing app).
- *
- * @hide
- */
- @SystemApi
- public static final String EXTRA_RESOLVED_BASE_PATH =
- "android.content.pm.extra.RESOLVED_BASE_PATH";
-
- /**
* Streaming installation pending.
* Caller should make sure DataLoader is able to prepare image and reinitiate the operation.
*
@@ -3550,6 +3539,19 @@
}
/**
+ * @return the path to the validated base APK for this session, which may point at an
+ * APK inside the session (when the session defines the base), or it may
+ * point at the existing base APK (when adding splits to an existing app).
+ *
+ * @hide
+ */
+ @SystemApi
+ @RequiresPermission(Manifest.permission.READ_INSTALLED_SESSION_PATHS)
+ public @Nullable String getResolvedBaseApkPath() {
+ return resolvedBaseCodePath;
+ }
+
+ /**
* Get the value set in {@link SessionParams#setGrantedRuntimePermissions(String[])}.
*
* @hide
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index 328b0ae..b9c671a 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -8666,7 +8666,7 @@
* requesting its own install information and is not an instant app.
*
* @param packageName The name of the package to query
- * @throws NameNotFoundException if the given package name is not installed
+ * @throws NameNotFoundException if the given package name is not available to the caller.
*/
@NonNull
public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName)
diff --git a/core/java/android/credentials/CredentialOption.java b/core/java/android/credentials/CredentialOption.java
index 9a3b46d..da6656a 100644
--- a/core/java/android/credentials/CredentialOption.java
+++ b/core/java/android/credentials/CredentialOption.java
@@ -16,16 +16,25 @@
package android.credentials;
+import static android.Manifest.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS;
+
import static java.util.Objects.requireNonNull;
import android.annotation.NonNull;
+import android.annotation.SuppressLint;
+import android.content.ComponentName;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
+import android.util.ArraySet;
+
+import androidx.annotation.RequiresPermission;
import com.android.internal.util.AnnotationValidations;
import com.android.internal.util.Preconditions;
+import java.util.Set;
+
/**
* Information about a specific type of credential to be requested during a {@link
* CredentialManager#getCredential(GetCredentialRequest, Activity, CancellationSignal, Executor,
@@ -66,6 +75,14 @@
private final boolean mIsSystemProviderRequired;
/**
+ * A list of {@link ComponentName}s corresponding to the providers that this option must be
+ * queried against.
+ */
+ @NonNull
+ private final ArraySet<ComponentName> mAllowedProviders;
+
+
+ /**
* Returns the requested credential type.
*/
@NonNull
@@ -105,12 +122,22 @@
return mIsSystemProviderRequired;
}
+ /**
+ * Returns the set of {@link ComponentName} corresponding to providers that must receive
+ * this option.
+ */
+ @NonNull
+ public Set<ComponentName> getAllowedProviders() {
+ return mAllowedProviders;
+ }
+
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString8(mType);
dest.writeBundle(mCredentialRetrievalData);
dest.writeBundle(mCandidateQueryData);
dest.writeBoolean(mIsSystemProviderRequired);
+ dest.writeArraySet(mAllowedProviders);
}
@Override
@@ -125,6 +152,7 @@
+ ", requestData=" + mCredentialRetrievalData
+ ", candidateQueryData=" + mCandidateQueryData
+ ", isSystemProviderRequired=" + mIsSystemProviderRequired
+ + ", allowedProviders=" + mAllowedProviders
+ "}";
}
@@ -139,17 +167,50 @@
* provider
* @throws IllegalArgumentException If type is empty.
*/
- public CredentialOption(
+ private CredentialOption(
@NonNull String type,
@NonNull Bundle credentialRetrievalData,
@NonNull Bundle candidateQueryData,
- boolean isSystemProviderRequired) {
+ boolean isSystemProviderRequired,
+ @NonNull ArraySet<ComponentName> allowedProviders) {
mType = Preconditions.checkStringNotEmpty(type, "type must not be empty");
mCredentialRetrievalData = requireNonNull(credentialRetrievalData,
"requestData must not be null");
mCandidateQueryData = requireNonNull(candidateQueryData,
"candidateQueryData must not be null");
mIsSystemProviderRequired = isSystemProviderRequired;
+ mAllowedProviders = requireNonNull(allowedProviders, "providerFilterSer must"
+ + "not be empty");
+ }
+
+ /**
+ * Constructs a {@link CredentialOption}.
+ *
+ * @param type the requested credential type
+ * @param credentialRetrievalData the request data
+ * @param candidateQueryData the partial request data that will be sent to the provider
+ * during the initial credential candidate query stage
+ * @param isSystemProviderRequired whether the request must only be fulfilled by a system
+ * provider
+ * @throws IllegalArgumentException If type is empty, or null.
+ * @throws NullPointerException If {@code credentialRetrievalData}, or
+ * {@code candidateQueryData} is null.
+ *
+ * @deprecated replaced by Builder
+ */
+ @Deprecated
+ public CredentialOption(
+ @NonNull String type,
+ @NonNull Bundle credentialRetrievalData,
+ @NonNull Bundle candidateQueryData,
+ boolean isSystemProviderRequired) {
+ this(
+ type,
+ credentialRetrievalData,
+ candidateQueryData,
+ isSystemProviderRequired,
+ new ArraySet<>()
+ );
}
private CredentialOption(@NonNull Parcel in) {
@@ -165,6 +226,8 @@
mCandidateQueryData = candidateQueryData;
AnnotationValidations.validate(NonNull.class, null, mCandidateQueryData);
mIsSystemProviderRequired = isSystemProviderRequired;
+ mAllowedProviders = (ArraySet<ComponentName>) in.readArraySet(null);
+ AnnotationValidations.validate(NonNull.class, null, mAllowedProviders);
}
@NonNull
@@ -179,4 +242,108 @@
return new CredentialOption(in);
}
};
+
+ /** A builder for {@link CredentialOption}. */
+ public static final class Builder {
+
+ @NonNull
+ private String mType;
+
+ @NonNull
+ private Bundle mCredentialRetrievalData;
+
+ @NonNull
+ private Bundle mCandidateQueryData;
+
+ private boolean mIsSystemProviderRequired = false;
+
+ @NonNull
+ private ArraySet<ComponentName> mAllowedProviders = new ArraySet<>();
+
+ /**
+ * @param type the type of the credential option
+ * @param credentialRetrievalData the full request data
+ * @param candidateQueryData the partial request data that will be sent to the provider
+ * during the initial credential candidate query stage.
+ * @throws IllegalArgumentException If {@code type} is null, or empty
+ * @throws NullPointerException If {@code credentialRetrievalData}, or
+ * {@code candidateQueryData} is null
+ */
+ public Builder(@NonNull String type, @NonNull Bundle credentialRetrievalData,
+ @NonNull Bundle candidateQueryData) {
+ mType = Preconditions.checkStringNotEmpty(type, "type must not be "
+ + "null, or empty");
+ mCredentialRetrievalData = requireNonNull(credentialRetrievalData,
+ "credentialRetrievalData must not be null");
+ mCandidateQueryData = requireNonNull(candidateQueryData,
+ "candidateQueryData must not be null");
+ }
+
+ /**
+ * Sets a true/false value corresponding to whether this option must be serviced by
+ * system credentials providers only.
+ */
+ @SuppressLint("MissingGetterMatchingBuilder")
+ @NonNull
+ public Builder setIsSystemProviderRequired(boolean isSystemProviderRequired) {
+ mIsSystemProviderRequired = isSystemProviderRequired;
+ return this;
+ }
+
+ /**
+ * Adds a provider {@link ComponentName} to be queried while gathering credentials from
+ * credential providers on the device.
+ *
+ * If no candidate providers are specified, all user configured and system credential
+ * providers will be queried in the candidate query phase.
+ *
+ * If an invalid component name is provided, or a service corresponding to the
+ * component name does not exist on the device, that component name is ignored.
+ * If all component names are invalid, or not present on the device, no providers
+ * are queried and no credentials are retrieved.
+ *
+ * @throws NullPointerException If {@code allowedProvider} is null
+ */
+ @RequiresPermission(CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS)
+ @NonNull
+ public Builder addAllowedProvider(@NonNull ComponentName allowedProvider) {
+ mAllowedProviders.add(requireNonNull(allowedProvider,
+ "allowedProvider must not be null"));
+ return this;
+ }
+
+ /**
+ * Sets a set of provider {@link ComponentName} to be queried while gathering credentials
+ * from credential providers on the device.
+ *
+ * If no candidate providers are specified, all user configured and system credential
+ * providers will be queried in the candidate query phase.
+ *
+ * If an invalid component name is provided, or a service corresponding to the
+ * component name does not exist on the device, that component name is ignored.
+ * If all component names are invalid, or not present on the device, no providers
+ * are queried and no credentials are retrieved.
+ *
+ * @throws NullPointerException If {@code allowedProviders} is null, or any of its
+ * elements are null.
+ */
+ @RequiresPermission(CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS)
+ @NonNull
+ public Builder setAllowedProviders(@NonNull Set<ComponentName> allowedProviders) {
+ Preconditions.checkCollectionElementsNotNull(
+ allowedProviders,
+ /*valueName=*/ "allowedProviders");
+ mAllowedProviders = new ArraySet<>(allowedProviders);
+ return this;
+ }
+
+ /**
+ * Builds a {@link CredentialOption}.
+ */
+ @NonNull
+ public CredentialOption build() {
+ return new CredentialOption(mType, mCredentialRetrievalData, mCandidateQueryData,
+ mIsSystemProviderRequired, mAllowedProviders);
+ }
+ }
}
diff --git a/core/java/android/database/sqlite/SQLiteOpenHelper.java b/core/java/android/database/sqlite/SQLiteOpenHelper.java
index 3341800..5e523c0 100644
--- a/core/java/android/database/sqlite/SQLiteOpenHelper.java
+++ b/core/java/android/database/sqlite/SQLiteOpenHelper.java
@@ -513,6 +513,19 @@
* This method executes within a transaction. If an exception is thrown, all changes
* will automatically be rolled back.
* </p>
+ * <p>
+ * <em>Important:</em> You should NOT modify an existing migration step from version X to X+1
+ * once a build has been released containing that migration step. If a migration step has an
+ * error and it runs on a device, the step will NOT re-run itself in the future if a fix is made
+ * to the migration step.</p>
+ * <p>For example, suppose a migration step renames a database column from {@code foo} to
+ * {@code bar} when the name should have been {@code baz}. If that migration step is released
+ * in a build and runs on a user's device, the column will be renamed to {@code bar}. If the
+ * developer subsequently edits this same migration step to change the name to {@code baz} as
+ * intended, the user devices which have already run this step will still have the name
+ * {@code bar}. Instead, a NEW migration step should be created to correct the error and rename
+ * {@code bar} to {@code baz}, ensuring the error is corrected on devices which have already run
+ * the migration step with the error.</p>
*
* @param db The database.
* @param oldVersion The old database version.
diff --git a/core/java/android/ddm/DdmHandleHello.java b/core/java/android/ddm/DdmHandleHello.java
index 4160029..a51a740 100644
--- a/core/java/android/ddm/DdmHandleHello.java
+++ b/core/java/android/ddm/DdmHandleHello.java
@@ -16,6 +16,7 @@
package android.ddm;
+import android.os.DdmSyncState;
import android.os.Debug;
import android.os.UserHandle;
import android.util.Log;
@@ -44,6 +45,7 @@
private static final String[] FRAMEWORK_FEATURES = new String[] {
"opengl-tracing",
"view-hierarchy",
+ "support_boot_stages"
};
/* singleton, do not instantiate */
@@ -145,7 +147,9 @@
+ instructionSetDescription.length() * 2
+ vmFlags.length() * 2
+ 1
- + pkgName.length() * 2);
+ + pkgName.length() * 2
+ // STAG id (int)
+ + Integer.BYTES);
out.order(ChunkHandler.CHUNK_ORDER);
out.putInt(CLIENT_PROTOCOL_VERSION);
out.putInt(android.os.Process.myPid());
@@ -162,6 +166,10 @@
out.putInt(pkgName.length());
putString(out, pkgName);
+ // Added API 34 (and advertised via FEAT ddm packet)
+ // Send the current boot stage in ActivityThread
+ out.putInt(DdmSyncState.getStage().toInt());
+
Chunk reply = new Chunk(CHUNK_HELO, out);
/*
diff --git a/core/java/android/hardware/CameraSessionStats.java b/core/java/android/hardware/CameraSessionStats.java
index cf20459..79a551a 100644
--- a/core/java/android/hardware/CameraSessionStats.java
+++ b/core/java/android/hardware/CameraSessionStats.java
@@ -54,6 +54,7 @@
private int mApiLevel;
private boolean mIsNdk;
private int mLatencyMs;
+ private long mLogId;
private int mSessionType;
private int mInternalReconfigure;
private long mRequestCount;
@@ -70,6 +71,7 @@
mApiLevel = -1;
mIsNdk = false;
mLatencyMs = -1;
+ mLogId = 0;
mMaxPreviewFps = 0;
mSessionType = -1;
mInternalReconfigure = -1;
@@ -82,7 +84,7 @@
public CameraSessionStats(String cameraId, int facing, int newCameraState,
String clientName, int apiLevel, boolean isNdk, int creationDuration,
- float maxPreviewFps, int sessionType, int internalReconfigure) {
+ float maxPreviewFps, int sessionType, int internalReconfigure, long logId) {
mCameraId = cameraId;
mFacing = facing;
mNewCameraState = newCameraState;
@@ -90,6 +92,7 @@
mApiLevel = apiLevel;
mIsNdk = isNdk;
mLatencyMs = creationDuration;
+ mLogId = logId;
mMaxPreviewFps = maxPreviewFps;
mSessionType = sessionType;
mInternalReconfigure = internalReconfigure;
@@ -127,6 +130,7 @@
dest.writeInt(mApiLevel);
dest.writeBoolean(mIsNdk);
dest.writeInt(mLatencyMs);
+ dest.writeLong(mLogId);
dest.writeFloat(mMaxPreviewFps);
dest.writeInt(mSessionType);
dest.writeInt(mInternalReconfigure);
@@ -146,6 +150,7 @@
mApiLevel = in.readInt();
mIsNdk = in.readBoolean();
mLatencyMs = in.readInt();
+ mLogId = in.readLong();
mMaxPreviewFps = in.readFloat();
mSessionType = in.readInt();
mInternalReconfigure = in.readInt();
@@ -189,6 +194,10 @@
return mLatencyMs;
}
+ public long getLogId() {
+ return mLogId;
+ }
+
public float getMaxPreviewFps() {
return mMaxPreviewFps;
}
diff --git a/core/java/android/hardware/camera2/CameraCaptureSession.java b/core/java/android/hardware/camera2/CameraCaptureSession.java
index e9df553..1bc6099 100644
--- a/core/java/android/hardware/camera2/CameraCaptureSession.java
+++ b/core/java/android/hardware/camera2/CameraCaptureSession.java
@@ -661,7 +661,7 @@
*
* <p>Repeating burst requests are a simple way for an application to
* maintain a preview or other continuous stream of frames where each
- * request is different in a predicatable way, without having to continually
+ * request is different in a predictable way, without having to continually
* submit requests through {@link #captureBurst}.</p>
*
* <p>To stop the repeating capture, call {@link #stopRepeating}. Any
@@ -902,7 +902,7 @@
* {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_OFFLINE_PROCESSING OFFLINE_PROCESSING}
* capability in {@link CameraCharacteristics#REQUEST_AVAILABLE_CAPABILITIES}. When this method
* is supported, applications can use it to improve the latency of closing camera or recreating
- * capture session without losing the in progresss capture request outputs.</p>
+ * capture session without losing the in progress capture request outputs.</p>
*
* <p>Offline processing mode and the corresponding {@link CameraOfflineSession} differ from
* a regular online camera capture session in several ways. Successful offline switches will
@@ -1001,7 +1001,7 @@
*
* <p>Note that for common usage scenarios like creating a new session or closing the camera
* device, it is faster to call respective APIs directly (see below for more details) without
- * calling into this method. This API is only useful when application wants to uncofigure the
+ * calling into this method. This API is only useful when application wants to unconfigure the
* camera but keep the device open for later use.</p>
*
* <p>Creating a new capture session with {@link CameraDevice#createCaptureSession}
diff --git a/core/java/android/hardware/camera2/CameraCharacteristics.java b/core/java/android/hardware/camera2/CameraCharacteristics.java
index c95d081..0e4c3c0 100644
--- a/core/java/android/hardware/camera2/CameraCharacteristics.java
+++ b/core/java/android/hardware/camera2/CameraCharacteristics.java
@@ -651,7 +651,7 @@
* @param metadataClass The subclass of CameraMetadata that you want to get the keys for.
* @param keyClass The class of the metadata key, e.g. CaptureRequest.Key.class
* @param filterTags An array of tags to be used for filtering
- * @param includeSynthetic Include public syntethic tag by default.
+ * @param includeSynthetic Include public synthetic tag by default.
*
* @return List of keys supported by this CameraDevice for metadataClass.
*
@@ -2550,41 +2550,15 @@
* <ul>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED UNSPECIFIED}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB SRGB}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_LINEAR_SRGB LINEAR_SRGB}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_EXTENDED_SRGB EXTENDED_SRGB}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_LINEAR_EXTENDED_SRGB LINEAR_EXTENDED_SRGB}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT709 BT709}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020 BT2020}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DCI_P3 DCI_P3}</li>
* <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3 DISPLAY_P3}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_NTSC_1953 NTSC_1953}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SMPTE_C SMPTE_C}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ADOBE_RGB ADOBE_RGB}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_PRO_PHOTO_RGB PRO_PHOTO_RGB}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ACES ACES}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ACESCG ACESCG}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_CIE_XYZ CIE_XYZ}</li>
- * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_CIE_LAB CIE_LAB}</li>
+ * <li>{@link #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG BT2020_HLG}</li>
* </ul>
*
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_UNSPECIFIED
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SRGB
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_LINEAR_SRGB
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_EXTENDED_SRGB
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_LINEAR_EXTENDED_SRGB
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT709
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DCI_P3
* @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_DISPLAY_P3
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_NTSC_1953
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_SMPTE_C
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ADOBE_RGB
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_PRO_PHOTO_RGB
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ACES
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_ACESCG
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_CIE_XYZ
- * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_CIE_LAB
+ * @see #REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP_BT2020_HLG
* @hide
*/
public static final Key<long[]> REQUEST_AVAILABLE_COLOR_SPACE_PROFILES_MAP =
diff --git a/core/java/android/hardware/camera2/CameraDevice.java b/core/java/android/hardware/camera2/CameraDevice.java
index 42aa608..5feda78 100644
--- a/core/java/android/hardware/camera2/CameraDevice.java
+++ b/core/java/android/hardware/camera2/CameraDevice.java
@@ -141,7 +141,7 @@
* parameters. All automatic control is disabled (auto-exposure, auto-white
* balance, auto-focus), and post-processing parameters are set to preview
* quality. The manual capture parameters (exposure, sensitivity, and so on)
- * are set to reasonable defaults, but should be overriden by the
+ * are set to reasonable defaults, but should be overridden by the
* application depending on the intended use case.
* This template is guaranteed to be supported on camera devices that support the
* {@link CameraMetadata#REQUEST_AVAILABLE_CAPABILITIES_MANUAL_SENSOR MANUAL_SENSOR}
@@ -680,7 +680,7 @@
* <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th> </tr>
* <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td colspan="2" id="rb"></td> <td>Maximum-resolution GPU processing with preview.</td> </tr>
* <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV }</td><td id="rb">{@code MAXIMUM}</td> <td colspan="2" id="rb"></td> <td>Maximum-resolution in-app processing with preview.</td> </tr>
- * <tr> <td>{@code YUV }</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV }</td><td id="rb">{@code MAXIMUM}</td> <td colspan="2" id="rb"></td> <td>Maximum-resolution two-input in-app processsing.</td> </tr>
+ * <tr> <td>{@code YUV }</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV }</td><td id="rb">{@code MAXIMUM}</td> <td colspan="2" id="rb"></td> <td>Maximum-resolution two-input in-app processing.</td> </tr>
* <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code JPEG}</td><td id="rb">{@code MAXIMUM}</td> <td>Video recording with maximum-size video snapshot</td> </tr>
* <tr> <td>{@code YUV }</td><td id="rb">{@code 640x480}</td> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV }</td><td id="rb">{@code MAXIMUM}</td> <td>Standard video recording plus maximum-resolution in-app processing.</td> </tr>
* <tr> <td>{@code YUV }</td><td id="rb">{@code 640x480}</td> <td>{@code YUV }</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV }</td><td id="rb">{@code MAXIMUM}</td> <td>Preview plus two-input maximum-resolution in-app processing.</td> </tr>
@@ -722,7 +722,7 @@
* <tr><th>Type</th><th id="rb">Max size</th><th>Type</th><th id="rb">Max size</th> </tr>
* <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code PRIV}</td><td id="rb">{@code MAXIMUM}</td> <td>Maximum-resolution GPU processing with preview.</td> </tr>
* <tr> <td>{@code PRIV}</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV }</td><td id="rb">{@code MAXIMUM}</td> <td>Maximum-resolution in-app processing with preview.</td> </tr>
- * <tr> <td>{@code YUV }</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV }</td><td id="rb">{@code MAXIMUM}</td> <td>Maximum-resolution two-input in-app processsing.</td> </tr>
+ * <tr> <td>{@code YUV }</td><td id="rb">{@code PREVIEW}</td> <td>{@code YUV }</td><td id="rb">{@code MAXIMUM}</td> <td>Maximum-resolution two-input in-app processing.</td> </tr>
* </table><br>
* </p>
*
@@ -1137,7 +1137,7 @@
* <tr><th colspan="13">Additional guaranteed combinations for ULTRA_HIGH_RESOLUTION sensors (YUV / PRIV inputs are guaranteed only if YUV / PRIVATE reprocessing are supported)</th></tr>
* <tr> <th colspan="3" id="rb">Input</th> <th colspan="3" id="rb">Target 1</th> <th colspan="3" id="rb">Target 2</th> <th colspan="3" id="rb">Target 3</th> <th rowspan="2">Sample use case(s)</th> </tr>
* <tr> <th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th><th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th> <th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th> <th>Type</th><th id="rb"> SC Map</th><th id="rb">Max size</th></tr>
- * <tr> <td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code PRIV / YUV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td colspan="3" id="rb"></td> <td>RAW remosaic reprocessing with seperate preview</td> </tr>
+ * <tr> <td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code PRIV / YUV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td colspan="3" id="rb"></td> <td>RAW remosaic reprocessing with separate preview</td> </tr>
* <tr> <td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td>{@code RAW}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code PRIV / YUV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code JPEG / YUV}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td> <td>Ultra high res RAW -> JPEG / YUV with seperate preview</td> </tr>
* <tr> <td>{@code YUV / PRIV}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td> <td>{@code YUV / PRIV}</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td><td id="rb">{@code YUV / PRIV}</td><td id="rb">{@code DEFAULT}</td><td id="rb">{@code PREVIEW}</td><td id="rb">{@code JPEG }</td><td id="rb">{@code MAX_RES}</td><td id="rb">{@code MAX}</td> <td> Ultra high res PRIV / YUV -> YUV / JPEG reprocessing with seperate preview</td> </tr>
* </table><br>
@@ -1260,7 +1260,7 @@
* settings by calling {@link CaptureRequest.Builder#setPhysicalCameraKey}.</p>
*
* <p>Individual physical camera settings will only be honored for camera session
- * that was initialiazed with corresponding physical camera id output configuration
+ * that was initialized with corresponding physical camera id output configuration
* {@link OutputConfiguration#setPhysicalCameraId} and the same output targets are
* also attached in the request by {@link CaptureRequest.Builder#addTarget}.</p>
*
diff --git a/core/java/android/hardware/camera2/CameraManager.java b/core/java/android/hardware/camera2/CameraManager.java
index e6b3069..144b1de 100644
--- a/core/java/android/hardware/camera2/CameraManager.java
+++ b/core/java/android/hardware/camera2/CameraManager.java
@@ -121,6 +121,7 @@
* System property for allowing the above
* @hide
*/
+ @TestApi
public static final String LANDSCAPE_TO_PORTRAIT_PROP =
"camera.enable_landscape_to_portrait";
@@ -255,7 +256,7 @@
/**
* Similar to getCameraIdList(). However, getCamerIdListNoLazy() necessarily communicates with
- * cameraserver in order to get the list of camera ids. This is to faciliate testing since some
+ * cameraserver in order to get the list of camera ids. This is to facilitate testing since some
* camera ids may go 'offline' without callbacks from cameraserver because of changes in
* SYSTEM_CAMERA permissions (though this is not a changeable permission, tests may call
* adopt(drop)ShellPermissionIdentity() and effectively change their permissions). This call
@@ -559,7 +560,7 @@
}
// Query the characteristics of all physical sub-cameras, and combine the multi-resolution
- // stream configurations. Alternatively, for ultra-high resolution camera, direclty use
+ // stream configurations. Alternatively, for ultra-high resolution camera, directly use
// its multi-resolution stream configurations. Note that framework derived formats such as
// HEIC and DEPTH_JPEG aren't supported as multi-resolution input or output formats.
Set<String> physicalCameraIds = info.getPhysicalCameraIds();
@@ -622,6 +623,16 @@
@NonNull
public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId)
throws CameraAccessException {
+ return getCameraCharacteristics(cameraId, shouldOverrideToPortrait(mContext));
+ }
+
+ /**
+ * @hide
+ */
+ @TestApi
+ @NonNull
+ public CameraCharacteristics getCameraCharacteristics(@NonNull String cameraId,
+ boolean overrideToPortrait) throws CameraAccessException {
CameraCharacteristics characteristics = null;
if (CameraManagerGlobal.sCameraServiceDisabled) {
throw new IllegalArgumentException("No cameras available on device");
@@ -635,7 +646,6 @@
try {
Size displaySize = getDisplaySize();
- boolean overrideToPortrait = shouldOverrideToPortrait(mContext);
CameraMetadataNative info = cameraService.getCameraCharacteristics(cameraId,
mContext.getApplicationInfo().targetSdkVersion, overrideToPortrait);
try {
@@ -727,7 +737,7 @@
*/
private CameraDevice openCameraDeviceUserAsync(String cameraId,
CameraDevice.StateCallback callback, Executor executor, final int uid,
- final int oomScoreOffset) throws CameraAccessException {
+ final int oomScoreOffset, boolean overrideToPortrait) throws CameraAccessException {
CameraCharacteristics characteristics = getCameraCharacteristics(cameraId);
CameraDevice device = null;
Map<String, CameraCharacteristics> physicalIdsToChars =
@@ -755,7 +765,6 @@
"Camera service is currently unavailable");
}
- boolean overrideToPortrait = shouldOverrideToPortrait(mContext);
cameraUser = cameraService.connectDevice(callbacks, cameraId,
mContext.getOpPackageName(), mContext.getAttributionTag(), uid,
oomScoreOffset, mContext.getApplicationInfo().targetSdkVersion,
@@ -826,7 +835,7 @@
* Opening the same camera ID twice in the same application will similarly cause the
* {@link android.hardware.camera2.CameraDevice.StateCallback#onDisconnected} callback
* being fired for the {@link CameraDevice} from the first open call and all ongoing tasks
- * being droppped.</p>
+ * being dropped.</p>
*
* <p>Once the camera is successfully opened, {@link CameraDevice.StateCallback#onOpened} will
* be invoked with the newly opened {@link CameraDevice}. The camera device can then be set up
@@ -891,6 +900,43 @@
}
/**
+ * Open a connection to a camera with the given ID. Also specify overrideToPortrait for testing.
+ *
+ * @param cameraId
+ * The unique identifier of the camera device to open
+ * @param handler
+ * The handler on which the callback should be invoked, or
+ * {@code null} to use the current thread's {@link android.os.Looper looper}.
+ * @param callback
+ * The callback which is invoked once the camera is opened
+ * @param overrideToPortrait
+ * Whether to apply the landscape to portrait override, using rotate and crop.
+ *
+ * @throws CameraAccessException if the camera is disabled by device policy,
+ * has been disconnected, or is being used by a higher-priority camera API client.
+ *
+ * @throws IllegalArgumentException if cameraId, the callback or the executor was null,
+ * or the cameraId does not match any currently or previously available
+ * camera device.
+ *
+ * @throws SecurityException if the application does not have permission to
+ * access the camera
+ *
+ * @see #getCameraIdList
+ * @see android.app.admin.DevicePolicyManager#setCameraDisabled
+ *
+ * @hide
+ */
+ @TestApi
+ @RequiresPermission(android.Manifest.permission.CAMERA)
+ public void openCamera(@NonNull String cameraId, boolean overrideToPortrait,
+ @Nullable Handler handler,
+ @NonNull final CameraDevice.StateCallback callback) throws CameraAccessException {
+ openCameraForUid(cameraId, callback, CameraDeviceImpl.checkAndWrapHandler(handler),
+ USE_CALLING_UID, /*oomScoreOffset*/0, overrideToPortrait);
+ }
+
+ /**
* Open a connection to a camera with the given ID.
*
* <p>The behavior of this method matches that of
@@ -994,7 +1040,8 @@
throw new IllegalArgumentException(
"oomScoreOffset < 0, cannot increase priority of camera client");
}
- openCameraForUid(cameraId, callback, executor, USE_CALLING_UID, oomScoreOffset);
+ openCameraForUid(cameraId, callback, executor, USE_CALLING_UID, oomScoreOffset,
+ shouldOverrideToPortrait(mContext));
}
/**
@@ -1016,7 +1063,8 @@
*/
public void openCameraForUid(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
- int clientUid, int oomScoreOffset) throws CameraAccessException {
+ int clientUid, int oomScoreOffset, boolean overrideToPortrait)
+ throws CameraAccessException {
if (cameraId == null) {
throw new IllegalArgumentException("cameraId was null");
@@ -1027,7 +1075,8 @@
throw new IllegalArgumentException("No cameras available on device");
}
- openCameraDeviceUserAsync(cameraId, callback, executor, clientUid, oomScoreOffset);
+ openCameraDeviceUserAsync(cameraId, callback, executor, clientUid, oomScoreOffset,
+ overrideToPortrait);
}
/**
@@ -1048,7 +1097,8 @@
public void openCameraForUid(@NonNull String cameraId,
@NonNull final CameraDevice.StateCallback callback, @NonNull Executor executor,
int clientUid) throws CameraAccessException {
- openCameraForUid(cameraId, callback, executor, clientUid, /*oomScoreOffset*/0);
+ openCameraForUid(cameraId, callback, executor, clientUid, /*oomScoreOffset*/0,
+ shouldOverrideToPortrait(mContext));
}
/**
@@ -1191,17 +1241,32 @@
* @hide
*/
public static boolean shouldOverrideToPortrait(@Nullable Context context) {
+ PackageManager packageManager = null;
+ String packageName = null;
+
+ if (context != null) {
+ packageManager = context.getPackageManager();
+ packageName = context.getOpPackageName();
+ }
+
+ return shouldOverrideToPortrait(packageManager, packageName);
+ }
+
+ /**
+ * @hide
+ */
+ @TestApi
+ public static boolean shouldOverrideToPortrait(@Nullable PackageManager packageManager,
+ @Nullable String packageName) {
if (!CameraManagerGlobal.sLandscapeToPortrait) {
return false;
}
- if (context != null) {
- PackageManager packageManager = context.getPackageManager();
-
+ if (packageManager != null && packageName != null) {
try {
return packageManager.getProperty(
PackageManager.PROPERTY_COMPAT_OVERRIDE_LANDSCAPE_TO_PORTRAIT,
- context.getOpPackageName()).getBoolean();
+ packageName).getBoolean();
} catch (PackageManager.NameNotFoundException e) {
// No such property
}
@@ -1694,7 +1759,7 @@
private final Set<Set<String>> mConcurrentCameraIdCombinations =
new ArraySet<Set<String>>();
- // Registered availablility callbacks and their executors
+ // Registered availability callbacks and their executors
private final ArrayMap<AvailabilityCallback, Executor> mCallbackMap =
new ArrayMap<AvailabilityCallback, Executor>();
@@ -2781,7 +2846,7 @@
// Tell listeners that the cameras and torch modes are unavailable and schedule a
// reconnection to camera service. When camera service is reconnected, the camera
// and torch statuses will be updated.
- // Iterate from the end to the beginning befcause onStatusChangedLocked removes
+ // Iterate from the end to the beginning because onStatusChangedLocked removes
// entries from the ArrayMap.
for (int i = mDeviceStatus.size() - 1; i >= 0; i--) {
String cameraId = mDeviceStatus.keyAt(i);
diff --git a/core/java/android/hardware/camera2/CameraMetadata.java b/core/java/android/hardware/camera2/CameraMetadata.java
index ed2a198..a7e28e2 100644
--- a/core/java/android/hardware/camera2/CameraMetadata.java
+++ b/core/java/android/hardware/camera2/CameraMetadata.java
@@ -159,7 +159,7 @@
* Optionally, if {@code filterTags} is not {@code null}, then filter out any keys
* whose native {@code tag} is not in {@code filterTags}. The {@code filterTags} array will be
* sorted as a side effect.
- * {@code includeSynthetic} Includes public syntenthic fields by default.
+ * {@code includeSynthetic} Includes public synthetic fields by default.
* </p>
*/
/*package*/ @SuppressWarnings("unchecked")
@@ -2308,7 +2308,7 @@
/**
* <p>An external flash has been turned on.</p>
* <p>It informs the camera device that an external flash has been turned on, and that
- * metering (and continuous focus if active) should be quickly recaculated to account
+ * metering (and continuous focus if active) should be quickly recalculated to account
* for the external flash. Otherwise, this mode acts like ON.</p>
* <p>When the external flash is turned off, AE mode should be changed to one of the
* other available AE modes.</p>
@@ -3285,6 +3285,7 @@
/**
* <p>Automatically select ON or OFF based on the system level preferences.</p>
* @see CaptureRequest#CONTROL_AUTOFRAMING
+ * @hide
*/
public static final int CONTROL_AUTOFRAMING_AUTO = 2;
diff --git a/core/java/android/hardware/camera2/CameraOfflineSession.java b/core/java/android/hardware/camera2/CameraOfflineSession.java
index 312559c..c219886 100644
--- a/core/java/android/hardware/camera2/CameraOfflineSession.java
+++ b/core/java/android/hardware/camera2/CameraOfflineSession.java
@@ -152,7 +152,7 @@
*
* <p>Closing a session is idempotent; closing more than once has no effect.</p>
*
- * @throws IllegalStateException if the offline sesion is not ready.
+ * @throws IllegalStateException if the offline session is not ready.
*/
@Override
public abstract void close();
diff --git a/core/java/android/hardware/camera2/CaptureRequest.java b/core/java/android/hardware/camera2/CaptureRequest.java
index 929868b..3a66081 100644
--- a/core/java/android/hardware/camera2/CaptureRequest.java
+++ b/core/java/android/hardware/camera2/CaptureRequest.java
@@ -2532,7 +2532,6 @@
* <ul>
* <li>{@link #CONTROL_AUTOFRAMING_OFF OFF}</li>
* <li>{@link #CONTROL_AUTOFRAMING_ON ON}</li>
- * <li>{@link #CONTROL_AUTOFRAMING_AUTO AUTO}</li>
* </ul>
*
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2545,7 +2544,6 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see #CONTROL_AUTOFRAMING_OFF
* @see #CONTROL_AUTOFRAMING_ON
- * @see #CONTROL_AUTOFRAMING_AUTO
*/
@PublicKey
@NonNull
diff --git a/core/java/android/hardware/camera2/CaptureResult.java b/core/java/android/hardware/camera2/CaptureResult.java
index a429f30..1536376 100644
--- a/core/java/android/hardware/camera2/CaptureResult.java
+++ b/core/java/android/hardware/camera2/CaptureResult.java
@@ -2736,7 +2736,6 @@
* <ul>
* <li>{@link #CONTROL_AUTOFRAMING_OFF OFF}</li>
* <li>{@link #CONTROL_AUTOFRAMING_ON ON}</li>
- * <li>{@link #CONTROL_AUTOFRAMING_AUTO AUTO}</li>
* </ul>
*
* <p><b>Optional</b> - The value for this key may be {@code null} on some devices.</p>
@@ -2749,7 +2748,6 @@
* @see CaptureRequest#SCALER_CROP_REGION
* @see #CONTROL_AUTOFRAMING_OFF
* @see #CONTROL_AUTOFRAMING_ON
- * @see #CONTROL_AUTOFRAMING_AUTO
*/
@PublicKey
@NonNull
diff --git a/core/java/android/hardware/camera2/DngCreator.java b/core/java/android/hardware/camera2/DngCreator.java
index cc484ea..1ae2fe1 100644
--- a/core/java/android/hardware/camera2/DngCreator.java
+++ b/core/java/android/hardware/camera2/DngCreator.java
@@ -482,7 +482,7 @@
}
private static final int DEFAULT_PIXEL_STRIDE = 2; // bytes per sample
- private static final int BYTES_PER_RGB_PIX = 3; // byts per pixel
+ private static final int BYTES_PER_RGB_PIX = 3; // bytes per pixel
// TIFF tag values needed to map between public API and TIFF spec
private static final int TAG_ORIENTATION_UNKNOWN = 9;
diff --git a/core/java/android/hardware/camera2/extension/CameraOutputConfig.aidl b/core/java/android/hardware/camera2/extension/CameraOutputConfig.aidl
index 34d016a..7c54a9b 100644
--- a/core/java/android/hardware/camera2/extension/CameraOutputConfig.aidl
+++ b/core/java/android/hardware/camera2/extension/CameraOutputConfig.aidl
@@ -36,4 +36,5 @@
int surfaceGroupId;
String physicalCameraId;
List<CameraOutputConfig> sharedSurfaceConfigs;
+ boolean isMultiResolutionOutput;
}
diff --git a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
index 2fa8b87..cfade55 100644
--- a/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
+++ b/core/java/android/hardware/camera2/impl/CameraAdvancedExtensionSessionImpl.java
@@ -258,6 +258,9 @@
OutputConfiguration cameraOutput = new OutputConfiguration(output.surfaceGroupId,
outputSurface);
+ if (output.isMultiResolutionOutput) {
+ cameraOutput.setMultiResolutionOutput();
+ }
if ((output.sharedSurfaceConfigs != null) && !output.sharedSurfaceConfigs.isEmpty()) {
cameraOutput.enableSurfaceSharing();
for (CameraOutputConfig sharedOutputConfig : output.sharedSurfaceConfigs) {
diff --git a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
index 86c453b..0a4a1f0 100644
--- a/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
+++ b/core/java/android/hardware/camera2/params/MandatoryStreamCombination.java
@@ -607,7 +607,7 @@
new StreamCombinationTemplate(new StreamTemplate [] {
new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.MAXIMUM),
new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.MAXIMUM) },
- "Maximum-resolution two-input in-app processsing"),
+ "Maximum-resolution two-input in-app processing"),
new StreamCombinationTemplate(new StreamTemplate [] {
new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW),
new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.PREVIEW),
@@ -891,7 +891,7 @@
new StreamCombinationTemplate(new StreamTemplate [] {
new StreamTemplate(ImageFormat.PRIVATE, SizeThreshold.s720p),
new StreamTemplate(ImageFormat.JPEG, SizeThreshold.s1440p)},
- "Standard stil image capture"),
+ "Standard still image capture"),
new StreamCombinationTemplate(new StreamTemplate [] {
new StreamTemplate(ImageFormat.YUV_420_888, SizeThreshold.s720p),
new StreamTemplate(ImageFormat.JPEG, SizeThreshold.s1440p)},
diff --git a/core/java/android/hardware/camera2/params/OutputConfiguration.java b/core/java/android/hardware/camera2/params/OutputConfiguration.java
index 857f62d..21540bf 100644
--- a/core/java/android/hardware/camera2/params/OutputConfiguration.java
+++ b/core/java/android/hardware/camera2/params/OutputConfiguration.java
@@ -165,7 +165,7 @@
* device runs in fixed frame rate. The timestamp is roughly in the same time base as
* {@link android.os.SystemClock#uptimeMillis}.</li>
* <li> For an output surface of MediaRecorder, MediaCodec, or ImageReader with {@link
- * android.hardware.HardwareBuffer#USAGE_VIDEO_ENCODE} usge flag, the timestamp base is
+ * android.hardware.HardwareBuffer#USAGE_VIDEO_ENCODE} usage flag, the timestamp base is
* {@link #TIMESTAMP_BASE_MONOTONIC}, which is roughly the same time base as
* {@link android.os.SystemClock#uptimeMillis}.</li>
* <li> For all other cases, the timestamp base is {@link #TIMESTAMP_BASE_SENSOR}, the same
@@ -418,7 +418,7 @@
* call, or no non-negative group ID has been set.
* @hide
*/
- void setMultiResolutionOutput() {
+ public void setMultiResolutionOutput() {
if (mIsShared) {
throw new IllegalStateException("Multi-resolution output flag must not be set for " +
"configuration with surface sharing");
@@ -654,7 +654,7 @@
mSurfaceType = SURFACE_TYPE_SURFACE_TEXTURE;
} else {
mSurfaceType = SURFACE_TYPE_UNKNOWN;
- throw new IllegalArgumentException("Unknow surface source class type");
+ throw new IllegalArgumentException("Unknown surface source class type");
}
if (surfaceSize.getWidth() == 0 || surfaceSize.getHeight() == 0) {
@@ -715,7 +715,7 @@
* The supported surfaces for sharing must be of type SurfaceTexture, SurfaceView,
* MediaRecorder, MediaCodec, or implementation defined ImageReader.</p>
*
- * <p>This function must not be called from OuptutConfigurations created by {@link
+ * <p>This function must not be called from OutputConfigurations created by {@link
* #createInstancesForMultiResolutionOutput}.</p>
*
* @throws IllegalStateException If this OutputConfiguration is created via {@link
@@ -934,7 +934,7 @@
*
* <p> Surfaces added via calls to {@link #addSurface} can also be removed from the
* OutputConfiguration. The only notable exception is the surface associated with
- * the OutputConfigration see {@link #getSurface} which was passed as part of the constructor
+ * the OutputConfiguration see {@link #getSurface} which was passed as part of the constructor
* or was added first in the deferred case
* {@link OutputConfiguration#OutputConfiguration(Size, Class)}.</p>
*
@@ -962,7 +962,7 @@
* for scenarios where the immediate consumer target isn't sufficient to indicate the stream's
* usage.</p>
*
- * <p>The main difference beteween stream use case and capture intent is that the former
+ * <p>The main difference between stream use case and capture intent is that the former
* enables the camera device to optimize camera hardware and software pipelines based on user
* scenarios for each stream, whereas the latter is mainly a hint to camera to decide
* optimal 3A strategy that's applicable to the whole session. The camera device carries out
@@ -1123,7 +1123,7 @@
* CameraCharacteristics#SENSOR_READOUT_TIMESTAMP} is
* {@link CameraMetadata#SENSOR_READOUT_TIMESTAMP_HARDWARE}.</p>
*
- * <p>As long as readout timestamp is supported, if the timestamp base isi
+ * <p>As long as readout timestamp is supported, if the timestamp base is
* {@link #TIMESTAMP_BASE_CHOREOGRAPHER_SYNCED}, or if the timestamp base is DEFAULT for a
* SurfaceView output, the image timestamps for the output are always readout time regardless
* of whether this function is called.</p>
@@ -1420,9 +1420,9 @@
*/
@Override
public int hashCode() {
- // Need ensure that the hashcode remains unchanged after adding a deferred surface. Otherwise
- // the deferred output configuration will be lost in the camera streammap after the deferred
- // surface is set.
+ // Need ensure that the hashcode remains unchanged after adding a deferred surface.
+ // Otherwise the deferred output configuration will be lost in the camera stream map
+ // after the deferred surface is set.
if (mIsDeferredConfig) {
return HashCodeHelpers.hashCode(
mRotation, mConfiguredSize.hashCode(), mConfiguredFormat, mConfiguredDataspace,
@@ -1446,7 +1446,7 @@
private static final String TAG = "OutputConfiguration";
// A surfaceGroupId counter used for MultiResolutionImageReader. Its value is
- // incremented everytime {@link createInstancesForMultiResolutionOutput} is called.
+ // incremented every time {@link createInstancesForMultiResolutionOutput} is called.
private static int MULTI_RESOLUTION_GROUP_ID_COUNTER = 0;
private ArrayList<Surface> mSurfaces;
diff --git a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
index 5a48176..aabe149 100644
--- a/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
+++ b/core/java/android/hardware/camera2/params/StreamConfigurationMap.java
@@ -1790,7 +1790,7 @@
*
* <p>{@code ValidOutputFormatsForInput([in:%s(%d), out:%s(%d), ... %s(%d)],
* ... [in:%s(%d), out:%s(%d), ... %s(%d)])}, where {@code [in:%s(%d), out:%s(%d), ... %s(%d)]}
- * represents an input fomat and its valid output formats.</p>
+ * represents an input format and its valid output formats.</p>
*
* <p>{@code HighSpeedVideoConfigurations([w:%d, h:%d, min_fps:%d, max_fps:%d],
* ... [w:%d, h:%d, min_fps:%d, max_fps:%d])}, where
diff --git a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
index 0993160..0d73a11 100644
--- a/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
+++ b/core/java/android/hardware/devicestate/IDeviceStateManager.aidl
@@ -111,6 +111,7 @@
*
* This should only be called from the overlay itself.
*/
+ @EnforcePermission("CONTROL_DEVICE_STATE")
@JavaPassthrough(annotation=
"@android.annotation.RequiresPermission(android.Manifest.permission.CONTROL_DEVICE_STATE)")
void onStateRequestOverlayDismissed(boolean shouldCancelRequest);
diff --git a/core/java/android/hardware/display/HdrConversionMode.java b/core/java/android/hardware/display/HdrConversionMode.java
index 49e5eff..5fccb5e 100644
--- a/core/java/android/hardware/display/HdrConversionMode.java
+++ b/core/java/android/hardware/display/HdrConversionMode.java
@@ -29,9 +29,6 @@
/**
* Describes the HDR conversion mode for a device.
*
- * This class is used when user changes the HDR conversion mode of the device via
- * {@link DisplayManager#setHdrConversionMode(HdrConversionMode)}.
- * <p>
* HDR conversion mode has a conversionMode and preferredHdrOutputType. </p><p>
* The conversionMode can be one of:
* {@link HdrConversionMode#HDR_CONVERSION_UNSUPPORTED} : HDR conversion is unsupported. In this
diff --git a/core/java/android/hardware/display/IColorDisplayManager.aidl b/core/java/android/hardware/display/IColorDisplayManager.aidl
index 200cf736..77dfb47 100644
--- a/core/java/android/hardware/display/IColorDisplayManager.aidl
+++ b/core/java/android/hardware/display/IColorDisplayManager.aidl
@@ -32,26 +32,36 @@
int getTransformCapabilities();
boolean isNightDisplayActivated();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean setNightDisplayActivated(boolean activated);
int getNightDisplayColorTemperature();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean setNightDisplayColorTemperature(int temperature);
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
int getNightDisplayAutoMode();
int getNightDisplayAutoModeRaw();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean setNightDisplayAutoMode(int autoMode);
Time getNightDisplayCustomStartTime();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean setNightDisplayCustomStartTime(in Time time);
Time getNightDisplayCustomEndTime();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean setNightDisplayCustomEndTime(in Time time);
int getColorMode();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
void setColorMode(int colorMode);
boolean isDisplayWhiteBalanceEnabled();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean setDisplayWhiteBalanceEnabled(boolean enabled);
boolean isReduceBrightColorsActivated();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean setReduceBrightColorsActivated(boolean activated);
int getReduceBrightColorsStrength();
+ @EnforcePermission("CONTROL_DISPLAY_COLOR_TRANSFORMS")
boolean setReduceBrightColorsStrength(int strength);
float getReduceBrightColorsOffsetFactor();
}
\ No newline at end of file
diff --git a/core/java/android/hardware/display/IDisplayManager.aidl b/core/java/android/hardware/display/IDisplayManager.aidl
index a3b7b51..18edbdb 100644
--- a/core/java/android/hardware/display/IDisplayManager.aidl
+++ b/core/java/android/hardware/display/IDisplayManager.aidl
@@ -47,9 +47,11 @@
// Requires CONFIGURE_WIFI_DISPLAY permission.
// The process must have previously registered a callback.
+ @EnforcePermission("CONFIGURE_WIFI_DISPLAY")
void startWifiDisplayScan();
// Requires CONFIGURE_WIFI_DISPLAY permission.
+ @EnforcePermission("CONFIGURE_WIFI_DISPLAY")
void stopWifiDisplayScan();
// Requires CONFIGURE_WIFI_DISPLAY permission.
@@ -65,18 +67,22 @@
void forgetWifiDisplay(String address);
// Requires CONFIGURE_WIFI_DISPLAY permission.
+ @EnforcePermission("CONFIGURE_WIFI_DISPLAY")
void pauseWifiDisplay();
// Requires CONFIGURE_WIFI_DISPLAY permission.
+ @EnforcePermission("CONFIGURE_WIFI_DISPLAY")
void resumeWifiDisplay();
// No permissions required.
WifiDisplayStatus getWifiDisplayStatus();
// Requires WRITE_SECURE_SETTINGS permission.
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
void setUserDisabledHdrTypes(in int[] userDisabledTypes);
// Requires WRITE_SECURE_SETTINGS permission.
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
void setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed);
// No permissions required.
@@ -89,6 +95,7 @@
void overrideHdrTypes(int displayId, in int[] modes);
// Requires CONFIGURE_DISPLAY_COLOR_MODE
+ @EnforcePermission("CONFIGURE_DISPLAY_COLOR_MODE")
void requestColorMode(int displayId, int colorMode);
// Requires CAPTURE_VIDEO_OUTPUT, CAPTURE_SECURE_VIDEO_OUTPUT, or an appropriate
@@ -114,24 +121,29 @@
Point getStableDisplaySize();
// Requires BRIGHTNESS_SLIDER_USAGE permission.
+ @EnforcePermission("BRIGHTNESS_SLIDER_USAGE")
ParceledListSlice getBrightnessEvents(String callingPackage);
// Requires ACCESS_AMBIENT_LIGHT_STATS permission.
+ @EnforcePermission("ACCESS_AMBIENT_LIGHT_STATS")
ParceledListSlice getAmbientBrightnessStats();
// Sets the global brightness configuration for a given user. Requires
// CONFIGURE_DISPLAY_BRIGHTNESS, and INTERACT_ACROSS_USER if the user being configured is not
// the same as the calling user.
+ @EnforcePermission("CONFIGURE_DISPLAY_BRIGHTNESS")
void setBrightnessConfigurationForUser(in BrightnessConfiguration c, int userId,
String packageName);
// Sets the global brightness configuration for a given display. Requires
// CONFIGURE_DISPLAY_BRIGHTNESS.
+ @EnforcePermission("CONFIGURE_DISPLAY_BRIGHTNESS")
void setBrightnessConfigurationForDisplay(in BrightnessConfiguration c, String uniqueDisplayId,
int userId, String packageName);
// Gets the brightness configuration for a given display. Requires
// CONFIGURE_DISPLAY_BRIGHTNESS.
+ @EnforcePermission("CONFIGURE_DISPLAY_BRIGHTNESS")
BrightnessConfiguration getBrightnessConfigurationForDisplay(String uniqueDisplayId,
int userId);
@@ -141,27 +153,32 @@
BrightnessConfiguration getBrightnessConfigurationForUser(int userId);
// Gets the default brightness configuration if configured.
+ @EnforcePermission("CONFIGURE_DISPLAY_BRIGHTNESS")
BrightnessConfiguration getDefaultBrightnessConfiguration();
// Gets the last requested minimal post processing settings for display with displayId.
boolean isMinimalPostProcessingRequested(int displayId);
// Temporarily sets the display brightness.
+ @EnforcePermission("CONTROL_DISPLAY_BRIGHTNESS")
void setTemporaryBrightness(int displayId, float brightness);
// Saves the display brightness.
+ @EnforcePermission("CONTROL_DISPLAY_BRIGHTNESS")
void setBrightness(int displayId, float brightness);
// Retrieves the display brightness.
float getBrightness(int displayId);
// Temporarily sets the auto brightness adjustment factor.
+ @EnforcePermission("CONTROL_DISPLAY_BRIGHTNESS")
void setTemporaryAutoBrightnessAdjustment(float adjustment);
// Get the minimum brightness curve.
Curve getMinimumBrightnessCurve();
// Get Brightness Information for the specified display.
+ @EnforcePermission("CONTROL_DISPLAY_BRIGHTNESS")
BrightnessInfo getBrightnessInfo(int displayId);
// Gets the id of the preferred wide gamut color space for all displays.
@@ -171,6 +188,7 @@
// Sets the user preferred display mode.
// Requires MODIFY_USER_PREFERRED_DISPLAY_MODE permission.
+ @EnforcePermission("MODIFY_USER_PREFERRED_DISPLAY_MODE")
void setUserPreferredDisplayMode(int displayId, in Mode mode);
Mode getUserPreferredDisplayMode(int displayId);
Mode getSystemPreferredDisplayMode(int displayId);
@@ -187,10 +205,13 @@
// When enabled the app requested display resolution and refresh rate is always selected
// in DisplayModeDirector regardless of user settings and policies for low brightness, low
// battery etc.
+ @EnforcePermission("OVERRIDE_DISPLAY_MODE_REQUESTS")
void setShouldAlwaysRespectAppRequestedMode(boolean enabled);
+ @EnforcePermission("OVERRIDE_DISPLAY_MODE_REQUESTS")
boolean shouldAlwaysRespectAppRequestedMode();
// Sets the refresh rate switching type.
+ @EnforcePermission("MODIFY_REFRESH_RATE_SWITCHING_TYPE")
void setRefreshRateSwitchingType(int newValue);
// Returns the refresh rate switching type.
diff --git a/core/java/android/hardware/display/VirtualDisplayConfig.java b/core/java/android/hardware/display/VirtualDisplayConfig.java
index 490e55b..03d6d91 100644
--- a/core/java/android/hardware/display/VirtualDisplayConfig.java
+++ b/core/java/android/hardware/display/VirtualDisplayConfig.java
@@ -161,9 +161,8 @@
}
/**
- * Returns the recording session associated with this VirtualDisplay. Only used for
+ * Returns the recording session associated with this {@link VirtualDisplay}. Only used for
* recording via {@link MediaProjection}.
- *
* @hide
*/
@Nullable
@@ -438,7 +437,7 @@
*
* <p>For best results, specify a divisor of the physical refresh rate, e.g., 30 or 60 on
* a 120hz display. If an arbitrary refresh rate is specified, the rate will be rounded up
- * down to a divisor of the physical display. If unset or zero, the virtual display will be
+ * to a divisor of the physical display. If unset or zero, the virtual display will be
* refreshed at the physical display refresh rate.
*
* @see Display#getRefreshRate()
diff --git a/core/java/android/hardware/input/InputDeviceLightsManager.java b/core/java/android/hardware/input/InputDeviceLightsManager.java
index 802e6dd..f4ee9a2 100644
--- a/core/java/android/hardware/input/InputDeviceLightsManager.java
+++ b/core/java/android/hardware/input/InputDeviceLightsManager.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.app.ActivityThread;
+import android.content.Context;
import android.hardware.lights.Light;
import android.hardware.lights.LightState;
import android.hardware.lights.LightsManager;
@@ -30,22 +31,22 @@
import java.util.List;
/**
- * LightsManager manages an input device's lights {@link android.hardware.input.Light}.
+ * LightsManager manages an input device's lights {@link android.hardware.lights.Light}
*/
class InputDeviceLightsManager extends LightsManager {
private static final String TAG = "InputDeviceLightsManager";
private static final boolean DEBUG = false;
- private final InputManager mInputManager;
+ private final InputManagerGlobal mGlobal;
// The input device ID.
private final int mDeviceId;
// Package name
private final String mPackageName;
- InputDeviceLightsManager(InputManager inputManager, int deviceId) {
- super(ActivityThread.currentActivityThread().getSystemContext());
- mInputManager = inputManager;
+ InputDeviceLightsManager(Context context, int deviceId) {
+ super(context);
+ mGlobal = InputManagerGlobal.getInstance();
mDeviceId = deviceId;
mPackageName = ActivityThread.currentPackageName();
}
@@ -57,7 +58,7 @@
*/
@Override
public @NonNull List<Light> getLights() {
- return mInputManager.getLights(mDeviceId);
+ return mGlobal.getLights(mDeviceId);
}
/**
@@ -68,7 +69,7 @@
@Override
public @NonNull LightState getLightState(@NonNull Light light) {
Preconditions.checkNotNull(light);
- return mInputManager.getLightState(mDeviceId, light);
+ return mGlobal.getLightState(mDeviceId, light);
}
/**
@@ -77,7 +78,7 @@
@Override
public @NonNull LightsSession openSession() {
final LightsSession session = new InputDeviceLightsSession();
- mInputManager.openLightSession(mDeviceId, mPackageName, session.getToken());
+ mGlobal.openLightSession(mDeviceId, mPackageName, session.getToken());
return session;
}
@@ -113,7 +114,7 @@
Preconditions.checkNotNull(request);
Preconditions.checkArgument(!mClosed);
- mInputManager.requestLights(mDeviceId, request, getToken());
+ mGlobal.requestLights(mDeviceId, request, getToken());
}
/**
@@ -122,7 +123,7 @@
@Override
public void close() {
if (!mClosed) {
- mInputManager.closeLightSession(mDeviceId, getToken());
+ mGlobal.closeLightSession(mDeviceId, getToken());
mClosed = true;
mCloseGuard.close();
}
diff --git a/core/java/android/hardware/input/InputDeviceVibrator.java b/core/java/android/hardware/input/InputDeviceVibrator.java
index ce6b523..9c18260 100644
--- a/core/java/android/hardware/input/InputDeviceVibrator.java
+++ b/core/java/android/hardware/input/InputDeviceVibrator.java
@@ -45,14 +45,14 @@
private final int mDeviceId;
private final VibratorInfo mVibratorInfo;
private final Binder mToken;
- private final InputManager mInputManager;
+ private final InputManagerGlobal mGlobal;
@GuardedBy("mDelegates")
private final ArrayMap<OnVibratorStateChangedListener,
OnVibratorStateChangedListenerDelegate> mDelegates = new ArrayMap<>();
- InputDeviceVibrator(InputManager inputManager, int deviceId, int vibratorId) {
- mInputManager = inputManager;
+ InputDeviceVibrator(int deviceId, int vibratorId) {
+ mGlobal = InputManagerGlobal.getInstance();
mDeviceId = deviceId;
mVibratorInfo = new VibratorInfo.Builder(vibratorId)
.setCapabilities(IVibrator.CAP_AMPLITUDE_CONTROL)
@@ -93,7 +93,7 @@
@Override
public boolean isVibrating() {
- return mInputManager.isVibrating(mDeviceId);
+ return mGlobal.isVibrating(mDeviceId);
}
/**
@@ -132,7 +132,7 @@
final OnVibratorStateChangedListenerDelegate delegate =
new OnVibratorStateChangedListenerDelegate(listener, executor);
- if (!mInputManager.registerVibratorStateListener(mDeviceId, delegate)) {
+ if (!mGlobal.registerVibratorStateListener(mDeviceId, delegate)) {
Log.w(TAG, "Failed to register vibrate state listener");
return;
}
@@ -156,7 +156,7 @@
if (mDelegates.containsKey(listener)) {
final OnVibratorStateChangedListenerDelegate delegate = mDelegates.get(listener);
- if (!mInputManager.unregisterVibratorStateListener(mDeviceId, delegate)) {
+ if (!mGlobal.unregisterVibratorStateListener(mDeviceId, delegate)) {
Log.w(TAG, "Failed to unregister vibrate state listener");
return;
}
@@ -176,12 +176,12 @@
@Override
public void vibrate(int uid, String opPkg, @NonNull VibrationEffect effect, String reason,
@NonNull VibrationAttributes attributes) {
- mInputManager.vibrate(mDeviceId, effect, mToken);
+ mGlobal.vibrate(mDeviceId, effect, mToken);
}
@Override
public void cancel() {
- mInputManager.cancelVibrate(mDeviceId, mToken);
+ mGlobal.cancelVibrate(mDeviceId, mToken);
}
@Override
diff --git a/core/java/android/hardware/input/InputDeviceVibratorManager.java b/core/java/android/hardware/input/InputDeviceVibratorManager.java
index d77f9c3..64b56677 100644
--- a/core/java/android/hardware/input/InputDeviceVibratorManager.java
+++ b/core/java/android/hardware/input/InputDeviceVibratorManager.java
@@ -40,7 +40,7 @@
private static final boolean DEBUG = false;
private final Binder mToken;
- private final InputManager mInputManager;
+ private final InputManagerGlobal mGlobal;
// The input device Id.
private final int mDeviceId;
@@ -48,8 +48,8 @@
@GuardedBy("mVibrators")
private final SparseArray<Vibrator> mVibrators = new SparseArray<>();
- public InputDeviceVibratorManager(InputManager inputManager, int deviceId) {
- mInputManager = inputManager;
+ public InputDeviceVibratorManager(int deviceId) {
+ mGlobal = InputManagerGlobal.getInstance();
mDeviceId = deviceId;
mToken = new Binder();
@@ -61,10 +61,10 @@
mVibrators.clear();
InputDevice inputDevice = InputDevice.getDevice(mDeviceId);
final int[] vibratorIds =
- mInputManager.getVibratorIds(mDeviceId);
+ mGlobal.getVibratorIds(mDeviceId);
for (int i = 0; i < vibratorIds.length; i++) {
mVibrators.put(vibratorIds[i],
- new InputDeviceVibrator(mInputManager, mDeviceId, vibratorIds[i]));
+ new InputDeviceVibrator(mDeviceId, vibratorIds[i]));
}
}
}
@@ -127,12 +127,12 @@
@Override
public void vibrate(int uid, String opPkg, @NonNull CombinedVibration effect,
String reason, @Nullable VibrationAttributes attributes) {
- mInputManager.vibrate(mDeviceId, effect, mToken);
+ mGlobal.vibrate(mDeviceId, effect, mToken);
}
@Override
public void cancel() {
- mInputManager.cancelVibrate(mDeviceId, mToken);
+ mGlobal.cancelVibrate(mDeviceId, mToken);
}
@Override
diff --git a/core/java/android/hardware/input/InputManager.java b/core/java/android/hardware/input/InputManager.java
index 054ae21..5dc3825 100644
--- a/core/java/android/hardware/input/InputManager.java
+++ b/core/java/android/hardware/input/InputManager.java
@@ -33,21 +33,15 @@
import android.content.Context;
import android.hardware.BatteryState;
import android.hardware.SensorManager;
-import android.hardware.lights.Light;
-import android.hardware.lights.LightState;
import android.hardware.lights.LightsManager;
-import android.hardware.lights.LightsRequest;
import android.os.Binder;
import android.os.Build;
-import android.os.CombinedVibration;
import android.os.Handler;
import android.os.IBinder;
-import android.os.IVibratorStateListener;
import android.os.InputEventInjectionSync;
import android.os.Process;
import android.os.RemoteException;
import android.os.SystemClock;
-import android.os.VibrationEffect;
import android.os.Vibrator;
import android.os.VibratorManager;
import android.util.Log;
@@ -1380,7 +1374,7 @@
* @hide
*/
public Vibrator getInputDeviceVibrator(int deviceId, int vibratorId) {
- return new InputDeviceVibrator(this, deviceId, vibratorId);
+ return new InputDeviceVibrator(deviceId, vibratorId);
}
/**
@@ -1391,85 +1385,7 @@
*/
@NonNull
public VibratorManager getInputDeviceVibratorManager(int deviceId) {
- return new InputDeviceVibratorManager(InputManager.this, deviceId);
- }
-
- /*
- * Get the list of device vibrators
- * @return The list of vibrators IDs
- */
- int[] getVibratorIds(int deviceId) {
- try {
- return mIm.getVibratorIds(deviceId);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
- }
-
- /*
- * Perform vibration effect
- */
- void vibrate(int deviceId, VibrationEffect effect, IBinder token) {
- try {
- mIm.vibrate(deviceId, effect, token);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
- }
-
- /*
- * Perform combined vibration effect
- */
- void vibrate(int deviceId, CombinedVibration effect, IBinder token) {
- try {
- mIm.vibrateCombined(deviceId, effect, token);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
- }
-
- /*
- * Cancel an ongoing vibration
- */
- void cancelVibrate(int deviceId, IBinder token) {
- try {
- mIm.cancelVibrate(deviceId, token);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
- }
-
- /*
- * Check if input device is vibrating
- */
- boolean isVibrating(int deviceId) {
- try {
- return mIm.isVibrating(deviceId);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
- }
-
- /**
- * Register input device vibrator state listener
- */
- boolean registerVibratorStateListener(int deviceId, IVibratorStateListener listener) {
- try {
- return mIm.registerVibratorStateListener(deviceId, listener);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
- }
-
- /**
- * Unregister input device vibrator state listener
- */
- boolean unregisterVibratorStateListener(int deviceId, IVibratorStateListener listener) {
- try {
- return mIm.unregisterVibratorStateListener(deviceId, listener);
- } catch (RemoteException ex) {
- throw ex.rethrowFromSystemServer();
- }
+ return new InputDeviceVibratorManager(deviceId);
}
/**
@@ -1499,77 +1415,7 @@
*/
@NonNull
public LightsManager getInputDeviceLightsManager(int deviceId) {
- return new InputDeviceLightsManager(InputManager.this, deviceId);
- }
-
- /**
- * Gets a list of light objects associated with an input device.
- * @return The list of lights, never null.
- */
- @NonNull List<Light> getLights(int deviceId) {
- try {
- return mIm.getLights(deviceId);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Returns the state of an input device light.
- * @return the light state
- */
- @NonNull LightState getLightState(int deviceId, @NonNull Light light) {
- try {
- return mIm.getLightState(deviceId, light.getId());
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Request to modify the states of multiple lights.
- *
- * @param request the settings for lights that should change
- */
- void requestLights(int deviceId, @NonNull LightsRequest request, IBinder token) {
- try {
- List<Integer> lightIdList = request.getLights();
- int[] lightIds = new int[lightIdList.size()];
- for (int i = 0; i < lightIds.length; i++) {
- lightIds[i] = lightIdList.get(i);
- }
- List<LightState> lightStateList = request.getLightStates();
- mIm.setLightStates(deviceId, lightIds,
- lightStateList.toArray(new LightState[0]),
- token);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Open light session for input device manager
- *
- * @param token The token for the light session
- */
- void openLightSession(int deviceId, String opPkg, @NonNull IBinder token) {
- try {
- mIm.openLightSession(deviceId, opPkg, token);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
- }
-
- /**
- * Close light session
- *
- */
- void closeLightSession(int deviceId, @NonNull IBinder token) {
- try {
- mIm.closeLightSession(deviceId, token);
- } catch (RemoteException e) {
- throw e.rethrowFromSystemServer();
- }
+ return new InputDeviceLightsManager(getContext(), deviceId);
}
/**
diff --git a/core/java/android/hardware/input/InputManagerGlobal.java b/core/java/android/hardware/input/InputManagerGlobal.java
index 524d820..08d81bd 100644
--- a/core/java/android/hardware/input/InputManagerGlobal.java
+++ b/core/java/android/hardware/input/InputManagerGlobal.java
@@ -27,12 +27,18 @@
import android.hardware.input.InputManager.InputDeviceListener;
import android.hardware.input.InputManager.KeyboardBacklightListener;
import android.hardware.input.InputManager.OnTabletModeChangedListener;
+import android.hardware.lights.Light;
+import android.hardware.lights.LightState;
+import android.hardware.lights.LightsRequest;
+import android.os.CombinedVibration;
import android.os.Handler;
import android.os.IBinder;
+import android.os.IVibratorStateListener;
import android.os.Looper;
import android.os.Message;
import android.os.RemoteException;
import android.os.ServiceManager;
+import android.os.VibrationEffect;
import android.util.Log;
import android.util.SparseArray;
import android.view.Display;
@@ -903,4 +909,152 @@
throw ex.rethrowFromSystemServer();
}
}
+
+ /**
+ * Gets a list of light objects associated with an input device.
+ * @return The list of lights, never null.
+ */
+ @NonNull List<Light> getLights(int deviceId) {
+ try {
+ return mIm.getLights(deviceId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Returns the state of an input device light.
+ * @return the light state
+ */
+ @NonNull LightState getLightState(int deviceId, @NonNull Light light) {
+ try {
+ return mIm.getLightState(deviceId, light.getId());
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Request to modify the states of multiple lights.
+ *
+ * @param request the settings for lights that should change
+ */
+ void requestLights(int deviceId, @NonNull LightsRequest request, IBinder token) {
+ try {
+ List<Integer> lightIdList = request.getLights();
+ int[] lightIds = new int[lightIdList.size()];
+ for (int i = 0; i < lightIds.length; i++) {
+ lightIds[i] = lightIdList.get(i);
+ }
+ List<LightState> lightStateList = request.getLightStates();
+ mIm.setLightStates(deviceId, lightIds,
+ lightStateList.toArray(new LightState[0]),
+ token);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Open light session for input device manager
+ *
+ * @param token The token for the light session
+ */
+ void openLightSession(int deviceId, String opPkg, @NonNull IBinder token) {
+ try {
+ mIm.openLightSession(deviceId, opPkg, token);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Close light session
+ *
+ */
+ void closeLightSession(int deviceId, @NonNull IBinder token) {
+ try {
+ mIm.closeLightSession(deviceId, token);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /*
+ * Get the list of device vibrators
+ * @return The list of vibrators IDs
+ */
+ int[] getVibratorIds(int deviceId) {
+ try {
+ return mIm.getVibratorIds(deviceId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /*
+ * Perform vibration effect
+ */
+ void vibrate(int deviceId, VibrationEffect effect, IBinder token) {
+ try {
+ mIm.vibrate(deviceId, effect, token);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /*
+ * Perform combined vibration effect
+ */
+ void vibrate(int deviceId, CombinedVibration effect, IBinder token) {
+ try {
+ mIm.vibrateCombined(deviceId, effect, token);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /*
+ * Cancel an ongoing vibration
+ */
+ void cancelVibrate(int deviceId, IBinder token) {
+ try {
+ mIm.cancelVibrate(deviceId, token);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /*
+ * Check if input device is vibrating
+ */
+ boolean isVibrating(int deviceId) {
+ try {
+ return mIm.isVibrating(deviceId);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Register input device vibrator state listener
+ */
+ boolean registerVibratorStateListener(int deviceId, IVibratorStateListener listener) {
+ try {
+ return mIm.registerVibratorStateListener(deviceId, listener);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
+
+ /**
+ * Unregister input device vibrator state listener
+ */
+ boolean unregisterVibratorStateListener(int deviceId, IVibratorStateListener listener) {
+ try {
+ return mIm.unregisterVibratorStateListener(deviceId, listener);
+ } catch (RemoteException ex) {
+ throw ex.rethrowFromSystemServer();
+ }
+ }
}
diff --git a/core/java/android/hardware/input/VirtualKeyboardConfig.java b/core/java/android/hardware/input/VirtualKeyboardConfig.java
index d788df4..6d03065 100644
--- a/core/java/android/hardware/input/VirtualKeyboardConfig.java
+++ b/core/java/android/hardware/input/VirtualKeyboardConfig.java
@@ -110,10 +110,7 @@
/**
* Sets the preferred input language of the virtual keyboard using an IETF
- * <a href="https://tools.ietf.org/html/bcp47">BCP-47</a>
- * conformant tag. See {@code keyboardLocale} attribute in
- * frameworks/base/packages/InputDevices/res/xml/keyboard_layouts.xml for a list of
- * supported language tags.
+ * <a href="https://tools.ietf.org/html/bcp47">BCP-47</a> conformant tag.
*
* The passed in {@code languageTag} will be canonized using {@link
* ULocale} and used by the system as a hint to configure the keyboard layout.
@@ -135,7 +132,7 @@
public Builder setLanguageTag(@NonNull String languageTag) {
Objects.requireNonNull(languageTag, "languageTag cannot be null");
ULocale locale = ULocale.forLanguageTag(languageTag);
- if (locale.getLanguage().isEmpty() || locale.getCountry().isEmpty()) {
+ if (locale.getLanguage().isEmpty()) {
throw new IllegalArgumentException("The language tag is not valid.");
}
mLanguageTag = ULocale.createCanonical(locale).toLanguageTag();
@@ -144,8 +141,8 @@
/**
* Sets the preferred layout type of the virtual keyboard. See {@code keyboardLayoutType}
- * attribute in frameworks/base/packages/InputDevices/res/xml/keyboard_layouts.xml for a
- * list of supported layout types.
+ * attribute in frameworks/base/core/res/res/values/attrs.xml for a list of supported
+ * layout types.
*
* Note that the preferred layout is not guaranteed. If the specified layout type is
* well-formed but not supported, the keyboard will be using English US QWERTY layout.
diff --git a/core/java/android/hardware/radio/IRadioService.aidl b/core/java/android/hardware/radio/IRadioService.aidl
index c7131a7..9349cf7 100644
--- a/core/java/android/hardware/radio/IRadioService.aidl
+++ b/core/java/android/hardware/radio/IRadioService.aidl
@@ -31,7 +31,7 @@
List<RadioManager.ModuleProperties> listModules();
ITuner openTuner(int moduleId, in RadioManager.BandConfig bandConfig, boolean withAudio,
- in ITunerCallback callback, int targetSdkVersion);
+ in ITunerCallback callback);
ICloseHandle addAnnouncementListener(in int[] enabledTypes,
in IAnnouncementListener listener);
diff --git a/core/java/android/hardware/radio/RadioManager.java b/core/java/android/hardware/radio/RadioManager.java
index f072e3b..8c6083c 100644
--- a/core/java/android/hardware/radio/RadioManager.java
+++ b/core/java/android/hardware/radio/RadioManager.java
@@ -1796,7 +1796,7 @@
ITuner tuner;
TunerCallbackAdapter halCallback = new TunerCallbackAdapter(callback, handler);
try {
- tuner = mService.openTuner(moduleId, config, withAudio, halCallback, mTargetSdkVersion);
+ tuner = mService.openTuner(moduleId, config, withAudio, halCallback);
} catch (RemoteException | IllegalArgumentException | IllegalStateException ex) {
Log.e(TAG, "Failed to open tuner", ex);
return null;
@@ -1873,7 +1873,6 @@
@NonNull private final Context mContext;
@NonNull private final IRadioService mService;
- private final int mTargetSdkVersion;
/**
* @hide
@@ -1890,6 +1889,5 @@
public RadioManager(Context context, IRadioService service) {
mContext = context;
mService = service;
- mTargetSdkVersion = mContext.getApplicationInfo().targetSdkVersion;
}
}
diff --git a/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java b/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java
index 268db1e..47b8550 100644
--- a/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java
+++ b/core/java/android/inputmethodservice/IRemoteInputConnectionInvoker.java
@@ -25,6 +25,8 @@
import android.graphics.RectF;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.CancellationSignalBeamer;
+import android.os.IBinder;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.view.KeyEvent;
@@ -59,6 +61,7 @@
@NonNull
private final IRemoteInputConnection mConnection;
private final int mSessionId;
+ private CancellationSignalBeamer.Sender mBeamer;
private IRemoteInputConnectionInvoker(@NonNull IRemoteInputConnection inputConnection,
int sessionId) {
@@ -681,7 +684,7 @@
* InputConnectionCommandHeader, ParcelableHandwritingGesture, ResultReceiver)}.
*/
@AnyThread
- public void performHandwritingGesture(@NonNull ParcelableHandwritingGesture gesture,
+ public void performHandwritingGesture(@NonNull HandwritingGesture gesture,
@Nullable @CallbackExecutor Executor executor, @Nullable IntConsumer consumer) {
ResultReceiver resultReceiver = null;
if (consumer != null) {
@@ -689,7 +692,11 @@
resultReceiver = new IntResultReceiver(executor, consumer);
}
try {
- mConnection.performHandwritingGesture(createHeader(), gesture, resultReceiver);
+ try (var ignored = getCancellationSignalBeamer().beamScopeIfNeeded(gesture)) {
+ mConnection.performHandwritingGesture(createHeader(),
+ ParcelableHandwritingGesture.of(gesture),
+ resultReceiver);
+ }
} catch (RemoteException e) {
if (consumer != null && executor != null) {
executor.execute(() -> consumer.accept(
@@ -700,25 +707,59 @@
/**
* Invokes one of {@link IRemoteInputConnection#previewHandwritingGesture(
- * InputConnectionCommandHeader, ParcelableHandwritingGesture, CancellationSignal)}
+ * InputConnectionCommandHeader, HandwritingGesture, IBinder)}
*/
@AnyThread
public boolean previewHandwritingGesture(
- @NonNull ParcelableHandwritingGesture gesture,
+ @NonNull HandwritingGesture gesture,
@Nullable CancellationSignal cancellationSignal) {
- if (cancellationSignal != null && cancellationSignal.isCanceled()) {
- return false; // cancelled.
- }
-
- // TODO(b/254727073): Implement CancellationSignal
try {
- mConnection.previewHandwritingGesture(createHeader(), gesture, null);
+ try (var csToken = beam(cancellationSignal)) {
+ mConnection.previewHandwritingGesture(createHeader(),
+ ParcelableHandwritingGesture.of(gesture),
+ csToken);
+ }
return true;
} catch (RemoteException e) {
return false;
}
}
+ @Nullable
+ CancellationSignalBeamer.Sender.CloseableToken beam(CancellationSignal cs) {
+ if (cs == null) {
+ return null;
+ }
+ return getCancellationSignalBeamer().beam(cs);
+ }
+
+ private CancellationSignalBeamer.Sender getCancellationSignalBeamer() {
+ if (mBeamer != null) {
+ return mBeamer;
+ }
+ mBeamer = new CancellationSignalBeamer.Sender() {
+ @Override
+ public void onCancel(IBinder token) {
+ try {
+ mConnection.cancelCancellationSignal(token);
+ } catch (RemoteException e) {
+ // Remote process likely died, ignore.
+ }
+ }
+
+ @Override
+ public void onForget(IBinder token) {
+ try {
+ mConnection.forgetCancellationSignal(token);
+ } catch (RemoteException e) {
+ // Remote process likely died, ignore.
+ }
+ }
+ };
+
+ return mBeamer;
+ }
+
/**
* Invokes {@link IRemoteInputConnection#requestCursorUpdates(InputConnectionCommandHeader, int,
* int, AndroidFuture)}.
diff --git a/core/java/android/inputmethodservice/RemoteInputConnection.java b/core/java/android/inputmethodservice/RemoteInputConnection.java
index ec26ace..56e69bf 100644
--- a/core/java/android/inputmethodservice/RemoteInputConnection.java
+++ b/core/java/android/inputmethodservice/RemoteInputConnection.java
@@ -34,7 +34,6 @@
import android.view.inputmethod.HandwritingGesture;
import android.view.inputmethod.InputConnection;
import android.view.inputmethod.InputContentInfo;
-import android.view.inputmethod.ParcelableHandwritingGesture;
import android.view.inputmethod.PreviewableHandwritingGesture;
import android.view.inputmethod.SurroundingText;
import android.view.inputmethod.TextAttribute;
@@ -424,16 +423,18 @@
public void performHandwritingGesture(
@NonNull HandwritingGesture gesture, @Nullable @CallbackExecutor Executor executor,
@Nullable IntConsumer consumer) {
- mInvoker.performHandwritingGesture(ParcelableHandwritingGesture.of(gesture), executor,
- consumer);
+ mInvoker.performHandwritingGesture(gesture, executor, consumer);
}
@AnyThread
public boolean previewHandwritingGesture(
@NonNull PreviewableHandwritingGesture gesture,
@Nullable CancellationSignal cancellationSignal) {
- return mInvoker.previewHandwritingGesture(ParcelableHandwritingGesture.of(gesture),
- cancellationSignal);
+ if (cancellationSignal != null && cancellationSignal.isCanceled()) {
+ return false; // cancelled.
+ }
+
+ return mInvoker.previewHandwritingGesture(gesture, cancellationSignal);
}
@AnyThread
diff --git a/core/java/android/nfc/tech/IsoDep.java b/core/java/android/nfc/tech/IsoDep.java
index 089b159..0ba0c5a 100644
--- a/core/java/android/nfc/tech/IsoDep.java
+++ b/core/java/android/nfc/tech/IsoDep.java
@@ -88,6 +88,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param timeout timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public void setTimeout(int timeout) {
try {
@@ -106,6 +107,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @return timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public int getTimeout() {
try {
@@ -167,6 +169,7 @@
* @return response bytes received, will not be null
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or this operation is canceled
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public byte[] transceive(byte[] data) throws IOException {
return transceive(data, true);
@@ -193,6 +196,7 @@
* support.
*
* @return whether the NFC adapter on this device supports extended length APDUs.
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public boolean isExtendedLengthApduSupported() {
try {
diff --git a/core/java/android/nfc/tech/MifareClassic.java b/core/java/android/nfc/tech/MifareClassic.java
index 080e058..26f54e6 100644
--- a/core/java/android/nfc/tech/MifareClassic.java
+++ b/core/java/android/nfc/tech/MifareClassic.java
@@ -597,6 +597,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param timeout timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public void setTimeout(int timeout) {
try {
@@ -615,6 +616,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @return timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public int getTimeout() {
try {
diff --git a/core/java/android/nfc/tech/MifareUltralight.java b/core/java/android/nfc/tech/MifareUltralight.java
index dec2c65..c0416a3 100644
--- a/core/java/android/nfc/tech/MifareUltralight.java
+++ b/core/java/android/nfc/tech/MifareUltralight.java
@@ -236,6 +236,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param timeout timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public void setTimeout(int timeout) {
try {
@@ -255,6 +256,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @return timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public int getTimeout() {
try {
diff --git a/core/java/android/nfc/tech/Ndef.java b/core/java/android/nfc/tech/Ndef.java
index 39c355a..7d83f15 100644
--- a/core/java/android/nfc/tech/Ndef.java
+++ b/core/java/android/nfc/tech/Ndef.java
@@ -261,6 +261,7 @@
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or the operation is canceled
* @throws FormatException if the NDEF Message on the tag is malformed
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public NdefMessage getNdefMessage() throws IOException, FormatException {
checkConnected();
@@ -301,6 +302,7 @@
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or the operation is canceled
* @throws FormatException if the NDEF Message to write is malformed
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public void writeNdefMessage(NdefMessage msg) throws IOException, FormatException {
checkConnected();
@@ -339,6 +341,7 @@
* <p>Does not cause any RF activity and does not block.
*
* @return true if it is possible to make this tag read-only
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public boolean canMakeReadOnly() {
INfcTag tagService = mTag.getTagService();
@@ -370,6 +373,7 @@
* @return true on success, false if it is not possible to make this tag read-only
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or the operation is canceled
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public boolean makeReadOnly() throws IOException {
checkConnected();
diff --git a/core/java/android/nfc/tech/NdefFormatable.java b/core/java/android/nfc/tech/NdefFormatable.java
index 4175cd0..f19d302 100644
--- a/core/java/android/nfc/tech/NdefFormatable.java
+++ b/core/java/android/nfc/tech/NdefFormatable.java
@@ -111,6 +111,7 @@
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or the operation is canceled
* @throws FormatException if the NDEF Message to write is malformed
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public void formatReadOnly(NdefMessage firstMessage) throws IOException, FormatException {
format(firstMessage, true);
diff --git a/core/java/android/nfc/tech/NfcA.java b/core/java/android/nfc/tech/NfcA.java
index 88730f9..7e66483 100644
--- a/core/java/android/nfc/tech/NfcA.java
+++ b/core/java/android/nfc/tech/NfcA.java
@@ -141,6 +141,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param timeout timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public void setTimeout(int timeout) {
try {
@@ -159,6 +160,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @return timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public int getTimeout() {
try {
diff --git a/core/java/android/nfc/tech/NfcF.java b/core/java/android/nfc/tech/NfcF.java
index 4487121..2ccd388 100644
--- a/core/java/android/nfc/tech/NfcF.java
+++ b/core/java/android/nfc/tech/NfcF.java
@@ -145,6 +145,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @param timeout timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public void setTimeout(int timeout) {
try {
@@ -163,6 +164,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @return timeout value in milliseconds
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public int getTimeout() {
try {
diff --git a/core/java/android/nfc/tech/TagTechnology.java b/core/java/android/nfc/tech/TagTechnology.java
index 0e2c7c1..839fe42 100644
--- a/core/java/android/nfc/tech/TagTechnology.java
+++ b/core/java/android/nfc/tech/TagTechnology.java
@@ -176,6 +176,7 @@
* @see #close()
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or connect is canceled
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public void connect() throws IOException;
@@ -193,6 +194,7 @@
* @see #close()
* @throws TagLostException if the tag leaves the field
* @throws IOException if there is an I/O failure, or connect is canceled
+ * @throws SecurityException if the tag object is reused after the tag has left the field
* @hide
*/
public void reconnect() throws IOException;
@@ -205,6 +207,7 @@
* <p class="note">Requires the {@link android.Manifest.permission#NFC} permission.
*
* @see #connect()
+ * @throws SecurityException if the tag object is reused after the tag has left the field
*/
public void close() throws IOException;
diff --git a/core/java/android/os/CancellationSignalBeamer.java b/core/java/android/os/CancellationSignalBeamer.java
index afb5ff7..b424783 100644
--- a/core/java/android/os/CancellationSignalBeamer.java
+++ b/core/java/android/os/CancellationSignalBeamer.java
@@ -19,9 +19,13 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.system.SystemCleaner;
+import android.util.Pair;
+import android.view.inputmethod.CancellableHandwritingGesture;
+import android.view.inputmethod.HandwritingGesture;
import java.lang.ref.Cleaner;
import java.lang.ref.Reference;
+import java.util.ArrayList;
import java.util.HashMap;
/**
@@ -143,6 +147,58 @@
*/
public abstract void onForget(IBinder token);
+ private static final ThreadLocal<Pair<Sender, ArrayList<CloseableToken>>> sScope =
+ new ThreadLocal<>();
+
+ /**
+ * Beams a {@link CancellationSignal} through an existing Binder interface.
+ * @param gesture {@link HandwritingGesture} that supports
+ * {@link CancellableHandwritingGesture cancellation} requesting cancellation token.
+ * @return {@link IBinder} token. MUST be {@link MustClose#close}d <em>after</em>
+ * the binder call transporting it to the remote process, best with
+ * try-with-resources. {@code null} if {@code cs} was {@code null} or if
+ * {@link HandwritingGesture} isn't {@link CancellableHandwritingGesture cancellable}.
+ */
+ public MustClose beamScopeIfNeeded(HandwritingGesture gesture) {
+ if (!(gesture instanceof CancellableHandwritingGesture)) {
+ return null;
+ }
+ sScope.set(Pair.create(this, new ArrayList<>()));
+ return () -> {
+ var tokens = sScope.get().second;
+ sScope.remove();
+ for (int i = tokens.size() - 1; i >= 0; i--) {
+ if (tokens.get(i) != null) {
+ tokens.get(i).close();
+ }
+ }
+ };
+ }
+
+ /**
+ * An {@link AutoCloseable} interface with {@link AutoCloseable#close()} callback.
+ */
+ public interface MustClose extends AutoCloseable {
+ @Override
+ void close();
+ }
+
+ /**
+ * Beams a {@link CancellationSignal} token from existing scope created by previous call to
+ * {@link #beamScopeIfNeeded()}
+ * @param cs {@link CancellationSignal} for which token should be returned.
+ * @return {@link IBinder} token.
+ */
+ public static IBinder beamFromScope(CancellationSignal cs) {
+ var state = sScope.get();
+ if (state != null) {
+ var token = state.first.beam(cs);
+ state.second.add(token);
+ return token;
+ }
+ return null;
+ }
+
private static class Token extends Binder implements CloseableToken, Runnable {
private final Sender mSender;
@@ -200,7 +256,7 @@
*
* MUST be closed <em>after</em> it is sent over binder, ideally through try-with-resources.
*/
- public interface CloseableToken extends IBinder, AutoCloseable {
+ public interface CloseableToken extends IBinder, MustClose {
@Override
void close(); // No throws
}
@@ -215,10 +271,10 @@
* Constructs a new {@code Receiver}.
*
* @param cancelOnSenderDeath if true, {@link CancellationSignal}s obtained from
- * {@link #unbeam} are automatically {@link #cancel}led if the sender token
- * {@link Binder#linkToDeath dies}; otherwise they are simnply dropped. Note: if the
- * sending process drops all references to the {@link CancellationSignal} before
- * process death, the cancellation is not guaranteed.
+ * {@link #unbeam} are automatically {@link #cancel}led if the sender token
+ * {@link Binder#linkToDeath dies}; otherwise they are simnply dropped. Note: if the
+ * sending process drops all references to the {@link CancellationSignal} before
+ * process death, the cancellation is not guaranteed.
*/
public Receiver(boolean cancelOnSenderDeath) {
mCancelOnSenderDeath = cancelOnSenderDeath;
diff --git a/core/java/android/os/DdmSyncStageUpdater.java b/core/java/android/os/DdmSyncStageUpdater.java
new file mode 100644
index 0000000..90f7076
--- /dev/null
+++ b/core/java/android/os/DdmSyncStageUpdater.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import android.os.DdmSyncState.Stage;
+import android.util.Slog;
+
+import org.apache.harmony.dalvik.ddmc.Chunk;
+import org.apache.harmony.dalvik.ddmc.ChunkHandler;
+import org.apache.harmony.dalvik.ddmc.DdmServer;
+
+import java.nio.ByteBuffer;
+
+/**
+ * @hide
+ */
+// Making it public so ActivityThread can access it.
+public class DdmSyncStageUpdater {
+
+ private static final String TAG = "DdmSyncStageUpdater";
+
+ private static final int CHUNK_STAGE = ChunkHandler.type("STAG");
+
+ /**
+ * @hide
+ */
+ public DdmSyncStageUpdater() {
+ }
+
+ /**
+ * @hide
+ */
+ // Making it public so ActivityThread can access it.
+ public synchronized void next(Stage stage) {
+ try {
+ DdmSyncState.next(stage);
+
+ // Request DDMServer to send a STAG chunk
+ ByteBuffer data = ByteBuffer.allocate(Integer.BYTES);
+ data.putInt(stage.toInt());
+ Chunk stagChunk = new Chunk(CHUNK_STAGE, data);
+ DdmServer.sendChunk(stagChunk);
+ } catch (Exception e) {
+ // Catch everything to make sure we don't impact ActivityThread
+ Slog.w(TAG, "Unable to go to next stage" + stage, e);
+ }
+ }
+
+}
diff --git a/core/java/android/os/DdmSyncState.java b/core/java/android/os/DdmSyncState.java
new file mode 100644
index 0000000..09c9ef2
--- /dev/null
+++ b/core/java/android/os/DdmSyncState.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os;
+
+import java.util.Arrays;
+
+/**
+ * Keep track of an app boot state. The main purpose is to stream back DDM packet so a DDM client
+ * can synchronize with the app state.
+ *
+ * The state is static so it can be accessed from HELO handler.
+ *
+ * @hide
+ **/
+public final class DdmSyncState {
+
+ /**
+ * @hide
+ */
+ public enum Stage {
+ // From zygote to attach
+ Boot("BOOT"),
+
+ // From attach to handleBindApplication
+ Attach("ATCH"),
+
+ // When handleBindApplication is finally reached
+ Bind("BIND"),
+
+ // When the actual package name is known (not the early "<preinitalized>" value).
+ Named("NAMD"),
+
+ // Can be skipped if the app is not debugged.
+ Debugger("DEBG"),
+
+ // App is in RunLoop
+ Running("A_GO");
+
+ final String mLabel;
+
+ Stage(String label) {
+ if (label.length() != 4) {
+ throw new IllegalStateException(
+ "Bad stage id '" + label + "'. Must be four letters");
+ }
+ this.mLabel = label;
+ }
+
+ /**
+ * To be included in a DDM packet payload, the stage is encoded in a big-endian int
+ * @hide
+ */
+ public int toInt() {
+ int result = 0;
+ for (int i = 0; i < 4; ++i) {
+ result = ((result << 8) | (mLabel.charAt(i) & 0xff));
+ }
+ return result;
+ }
+ }
+
+ private static int sCurrentStageIndex = 0;
+
+ /**
+ * @hide
+ */
+ public static synchronized Stage getStage() {
+ return Stage.values()[sCurrentStageIndex];
+ }
+
+ /**
+ * @hide
+ */
+ public static void reset() {
+ sCurrentStageIndex = 0;
+ }
+
+ /**
+ * Search for the next level down the list of Stage. Only succeed if the next stage
+ * if a later stage (no cycling allowed).
+ *
+ * @hide
+ */
+ public static synchronized void next(Stage nextStage) {
+ Stage[] stages = Stage.values();
+ // Search for the requested next stage
+ int rover = sCurrentStageIndex;
+ while (rover < stages.length && stages[rover] != nextStage) {
+ rover++;
+ }
+
+ if (rover == stages.length || stages[rover] != nextStage) {
+ throw new IllegalStateException(
+ "Cannot go to " + nextStage + " from:" + getInternalState());
+ }
+
+ sCurrentStageIndex = rover;
+ }
+
+ /**
+ * Use to build error messages
+ * @hide
+ */
+ private static String getInternalState() {
+ StringBuilder sb = new StringBuilder("\n");
+ sb.append("level = ").append(sCurrentStageIndex);
+ sb.append("\n");
+ sb.append("stages = ");
+ sb.append(Arrays.toString(Arrays.stream(Stage.values()).map(Enum::name).toArray()));
+ sb.append("\n");
+ return sb.toString();
+ }
+}
diff --git a/core/java/android/os/IRecoverySystem.aidl b/core/java/android/os/IRecoverySystem.aidl
index 88bdb7f..b3628ff 100644
--- a/core/java/android/os/IRecoverySystem.aidl
+++ b/core/java/android/os/IRecoverySystem.aidl
@@ -23,6 +23,7 @@
/** @hide */
interface IRecoverySystem {
+ @EnforcePermission("RECOVERY")
boolean allocateSpaceForUpdate(in String packageFilePath);
boolean uncrypt(in String packageFile, IRecoverySystemProgressListener listener);
boolean setupBcb(in String command);
@@ -31,6 +32,7 @@
boolean requestLskf(in String packageName, in IntentSender sender);
boolean clearLskf(in String packageName);
boolean isLskfCaptured(in String packageName);
+ @EnforcePermission("RECOVERY")
int rebootWithLskfAssumeSlotSwitch(in String packageName, in String reason);
int rebootWithLskf(in String packageName, in String reason, in boolean slotSwitch);
}
diff --git a/core/java/android/os/ISystemUpdateManager.aidl b/core/java/android/os/ISystemUpdateManager.aidl
index f7f5079..cda2fa1 100644
--- a/core/java/android/os/ISystemUpdateManager.aidl
+++ b/core/java/android/os/ISystemUpdateManager.aidl
@@ -23,5 +23,6 @@
/** @hide */
interface ISystemUpdateManager {
Bundle retrieveSystemUpdateInfo();
+ @EnforcePermission("RECOVERY")
void updateSystemUpdateInfo(in PersistableBundle data);
}
diff --git a/core/java/android/os/IUserManager.aidl b/core/java/android/os/IUserManager.aidl
index fcebb45..8e1d2d6 100644
--- a/core/java/android/os/IUserManager.aidl
+++ b/core/java/android/os/IUserManager.aidl
@@ -134,7 +134,7 @@
boolean isUserForeground(int userId);
boolean isUserVisible(int userId);
int[] getVisibleUsers();
- int getDisplayIdAssignedToUser();
+ int getMainDisplayIdAssignedToUser();
boolean isUserNameSet(int userId);
boolean hasRestrictedProfiles(int userId);
boolean requestQuietModeEnabled(String callingPackage, boolean enableQuietMode, int userId, in IntentSender target, int flags);
diff --git a/core/java/android/os/IVibratorManagerService.aidl b/core/java/android/os/IVibratorManagerService.aidl
index fb9752f..6275352 100644
--- a/core/java/android/os/IVibratorManagerService.aidl
+++ b/core/java/android/os/IVibratorManagerService.aidl
@@ -25,8 +25,11 @@
interface IVibratorManagerService {
int[] getVibratorIds();
VibratorInfo getVibratorInfo(int vibratorId);
+ @EnforcePermission("ACCESS_VIBRATOR_STATE")
boolean isVibrating(int vibratorId);
+ @EnforcePermission("ACCESS_VIBRATOR_STATE")
boolean registerVibratorStateListener(int vibratorId, in IVibratorStateListener listener);
+ @EnforcePermission("ACCESS_VIBRATOR_STATE")
boolean unregisterVibratorStateListener(int vibratorId, in IVibratorStateListener listener);
boolean setAlwaysOnEffect(int uid, String opPkg, int alwaysOnId,
in CombinedVibration vibration, in VibrationAttributes attributes);
diff --git a/core/java/android/os/OWNERS b/core/java/android/os/OWNERS
index e9a3254..69889c5 100644
--- a/core/java/android/os/OWNERS
+++ b/core/java/android/os/OWNERS
@@ -79,3 +79,7 @@
# ART
per-file ArtModuleServiceManager.java = file:platform/art:/OWNERS
+
+# DDM Protocol
+per-file DdmSyncState.java = sanglardf@google.com, rpaquay@google.com
+per-file DdmSyncStageUpdater.java = sanglardf@google.com, rpaquay@google.com
diff --git a/core/java/android/os/Parcel.java b/core/java/android/os/Parcel.java
index 1673ade..e784c26 100644
--- a/core/java/android/os/Parcel.java
+++ b/core/java/android/os/Parcel.java
@@ -4499,17 +4499,28 @@
public void writeToParcel(Parcel out) {
Parcel source = mSource;
if (source != null) {
- out.appendFrom(source, mPosition, mLength);
- } else {
- out.writeValue(mObject);
+ synchronized (source) {
+ if (mSource != null) {
+ out.appendFrom(source, mPosition, mLength);
+ return;
+ }
+ }
}
+
+ out.writeValue(mObject);
}
public boolean hasFileDescriptors() {
Parcel source = mSource;
- return (source != null)
- ? source.hasFileDescriptors(mPosition, mLength)
- : Parcel.hasFileDescriptors(mObject);
+ if (source != null) {
+ synchronized (source) {
+ if (mSource != null) {
+ return source.hasFileDescriptors(mPosition, mLength);
+ }
+ }
+ }
+
+ return Parcel.hasFileDescriptors(mObject);
}
@Override
diff --git a/core/java/android/os/RemoteCallbackList.java b/core/java/android/os/RemoteCallbackList.java
index d89c3d5..2c58021 100644
--- a/core/java/android/os/RemoteCallbackList.java
+++ b/core/java/android/os/RemoteCallbackList.java
@@ -273,7 +273,7 @@
* handle such an exception by simply ignoring it.
*
* @param index Which of the registered callbacks you would like to
- * retrieve. Ranges from 0 to 1-{@link #beginBroadcast}.
+ * retrieve. Ranges from 0 to {@link #beginBroadcast}-1, inclusive.
*
* @return Returns the callback interface that you can call. This will
* always be non-null.
diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java
index 8824835..7337b37 100644
--- a/core/java/android/os/UserManager.java
+++ b/core/java/android/os/UserManager.java
@@ -3067,14 +3067,14 @@
}
/**
- * See {@link com.android.server.pm.UserManagerInternal#getDisplayAssignedToUser(int)}.
+ * See {@link com.android.server.pm.UserManagerInternal#getMainDisplayAssignedToUser(int)}.
*
* @hide
*/
@TestApi
- public int getDisplayIdAssignedToUser() {
+ public int getMainDisplayIdAssignedToUser() {
try {
- return mService.getDisplayIdAssignedToUser();
+ return mService.getMainDisplayIdAssignedToUser();
} catch (RemoteException re) {
throw re.rethrowFromSystemServer();
}
diff --git a/core/java/android/permission/IPermissionManager.aidl b/core/java/android/permission/IPermissionManager.aidl
index 16ae3bc..d19fd8f 100644
--- a/core/java/android/permission/IPermissionManager.aidl
+++ b/core/java/android/permission/IPermissionManager.aidl
@@ -76,6 +76,7 @@
List<SplitPermissionInfoParcelable> getSplitPermissions();
+ @EnforcePermission("MANAGE_ONE_TIME_PERMISSION_SESSIONS")
void startOneTimePermissionSession(String packageName, int userId, long timeout,
long revokeAfterKilledDelay);
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 01778f7..326f87e 100644
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -2428,6 +2428,24 @@
"android.settings.REQUEST_SET_AUTOFILL_SERVICE";
/**
+ * Activity Action: Show screen that let user enable a Credential Manager provider.
+ * <p>
+ * Input: Intent's data URI set with an application name, using the
+ * "package" schema (like "package:com.my.app").
+ *
+ * <p>
+ * Output: {@link android.app.Activity#RESULT_OK} if user selected a provider belonging
+ * to the caller package.
+ * <p>
+ * <b>NOTE: </b> Applications should call
+ * {@link android.credentials.CredentialManager#isEnabledCredentialProviderService()}
+ * and only use this action to start an activity if they return {@code false}.
+ */
+ @SdkConstant(SdkConstantType.ACTIVITY_INTENT_ACTION)
+ public static final String ACTION_CREDENTIAL_PROVIDER =
+ "android.settings.CREDENTIAL_PROVIDER";
+
+ /**
* Activity Action: Show screen for controlling the Quick Access Wallet.
* <p>
* In some cases, a matching Activity may not exist, so ensure you
@@ -11459,21 +11477,46 @@
public @interface DeviceStateRotationLockSetting {
}
+ /** @hide */
+ public static final int DEVICE_STATE_ROTATION_KEY_UNKNOWN = -1;
+ /** @hide */
+ public static final int DEVICE_STATE_ROTATION_KEY_FOLDED = 0;
+ /** @hide */
+ public static final int DEVICE_STATE_ROTATION_KEY_HALF_FOLDED = 1;
+ /** @hide */
+ public static final int DEVICE_STATE_ROTATION_KEY_UNFOLDED = 2;
+
+ /**
+ * The different postures that can be used as keys with
+ * {@link #DEVICE_STATE_ROTATION_LOCK}.
+ * @hide
+ */
+ @IntDef(prefix = {"DEVICE_STATE_ROTATION_KEY_"}, value = {
+ DEVICE_STATE_ROTATION_KEY_UNKNOWN,
+ DEVICE_STATE_ROTATION_KEY_FOLDED,
+ DEVICE_STATE_ROTATION_KEY_HALF_FOLDED,
+ DEVICE_STATE_ROTATION_KEY_UNFOLDED,
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface DeviceStateRotationLockKey {
+ }
+
/**
* Rotation lock setting keyed on device state.
*
- * This holds a serialized map using int keys that represent Device States and value of
+ * This holds a serialized map using int keys that represent postures in
+ * {@link DeviceStateRotationLockKey} and value of
* {@link DeviceStateRotationLockSetting} representing the rotation lock setting for that
- * device state.
+ * posture.
*
* Serialized as key0:value0:key1:value1:...:keyN:valueN.
*
* Example: "0:1:1:2:2:1"
* This example represents a map of:
* <ul>
- * <li>0 -> DEVICE_STATE_ROTATION_LOCK_LOCKED</li>
- * <li>1 -> DEVICE_STATE_ROTATION_LOCK_UNLOCKED</li>
- * <li>2 -> DEVICE_STATE_ROTATION_LOCK_IGNORED</li>
+ * <li>DEVICE_STATE_ROTATION_KEY_FOLDED -> DEVICE_STATE_ROTATION_LOCK_LOCKED</li>
+ * <li>DEVICE_STATE_ROTATION_KEY_HALF_FOLDED -> DEVICE_STATE_ROTATION_LOCK_UNLOCKED</li>
+ * <li>DEVICE_STATE_ROTATION_KEY_UNFOLDED -> DEVICE_STATE_ROTATION_LOCK_IGNORED</li>
* </ul>
*
* @hide
@@ -14763,23 +14806,6 @@
"adaptive_battery_management_enabled";
/**
- * Whether or not apps are allowed into the
- * {@link android.app.usage.UsageStatsManager#STANDBY_BUCKET_RESTRICTED} bucket.
- * Type: int (0 for false, 1 for true)
- * Default: {@value #DEFAULT_ENABLE_RESTRICTED_BUCKET}
- *
- * @hide
- */
- @Readable
- public static final String ENABLE_RESTRICTED_BUCKET = "enable_restricted_bucket";
-
- /**
- * @see #ENABLE_RESTRICTED_BUCKET
- * @hide
- */
- public static final int DEFAULT_ENABLE_RESTRICTED_BUCKET = 1;
-
- /**
* Whether or not app auto restriction is enabled. When it is enabled, settings app will
* auto restrict the app if it has bad behavior (e.g. hold wakelock for long time).
*
@@ -18625,7 +18651,7 @@
* The modes that can be used when disabling syncs to the 'config' settings.
* @hide
*/
- @IntDef(prefix = "DISABLE_SYNC_MODE_",
+ @IntDef(prefix = "SYNC_DISABLED_MODE_",
value = { SYNC_DISABLED_MODE_NONE, SYNC_DISABLED_MODE_PERSISTENT,
SYNC_DISABLED_MODE_UNTIL_REBOOT })
@Retention(RetentionPolicy.SOURCE)
@@ -18635,23 +18661,36 @@
/**
* Sync is not disabled.
*
+ * @deprecated use the constant in DeviceConfig
+ *
* @hide
*/
- public static final int SYNC_DISABLED_MODE_NONE = 0;
+ @Deprecated
+ public static final int SYNC_DISABLED_MODE_NONE = DeviceConfig.SYNC_DISABLED_MODE_NONE;
/**
* Disabling of Config bulk update / syncing is persistent, i.e. it survives a device
* reboot.
+ *
+ * @deprecated use the constant in DeviceConfig
+ *
* @hide
*/
- public static final int SYNC_DISABLED_MODE_PERSISTENT = 1;
+ @Deprecated
+ public static final int SYNC_DISABLED_MODE_PERSISTENT =
+ DeviceConfig.SYNC_DISABLED_MODE_PERSISTENT;
/**
* Disabling of Config bulk update / syncing is not persistent, i.e. it will not survive a
* device reboot.
+ *
+ * @deprecated use the constant in DeviceConfig
+ *
* @hide
*/
- public static final int SYNC_DISABLED_MODE_UNTIL_REBOOT = 2;
+ @Deprecated
+ public static final int SYNC_DISABLED_MODE_UNTIL_REBOOT =
+ DeviceConfig.SYNC_DISABLED_MODE_UNTIL_REBOOT;
/**
* The content:// style URL for the config table.
diff --git a/core/java/android/security/net/config/SystemCertificateSource.java b/core/java/android/security/net/config/SystemCertificateSource.java
index 13f7e5d..3a254c1 100644
--- a/core/java/android/security/net/config/SystemCertificateSource.java
+++ b/core/java/android/security/net/config/SystemCertificateSource.java
@@ -39,9 +39,13 @@
}
private static File getDirectory() {
- // TODO(miguelaranda): figure out correct code path.
+ if ((System.getProperty("system.certs.enabled") != null)
+ && (System.getProperty("system.certs.enabled")).equals("true")) {
+ return new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts");
+ }
File updatable_dir = new File("/apex/com.android.conscrypt/cacerts");
- if (updatable_dir.exists() && !(updatable_dir.list().length == 0)) {
+ if (updatable_dir.exists()
+ && !(updatable_dir.list().length == 0)) {
return updatable_dir;
}
return new File(System.getenv("ANDROID_ROOT") + "/etc/security/cacerts");
diff --git a/core/java/android/service/autofill/Dataset.java b/core/java/android/service/autofill/Dataset.java
index e81ca1a..5f7486a 100644
--- a/core/java/android/service/autofill/Dataset.java
+++ b/core/java/android/service/autofill/Dataset.java
@@ -1260,6 +1260,36 @@
return mFieldIds.size() - 1;
}
+ private void createFromParcel(
+ @Nullable AutofillId id, @Nullable String datatype,
+ @Nullable AutofillValue value, @Nullable RemoteViews presentation,
+ @Nullable InlinePresentation inlinePresentation,
+ @Nullable InlinePresentation tooltip,
+ @Nullable DatasetFieldFilter filter,
+ @Nullable RemoteViews dialogPresentation) {
+ if (id != null) {
+ final int existingIdx = mFieldIds.indexOf(id);
+ if (existingIdx >= 0) {
+ mFieldValues.set(existingIdx, value);
+ mFieldPresentations.set(existingIdx, presentation);
+ mFieldDialogPresentations.set(existingIdx, dialogPresentation);
+ mFieldInlinePresentations.set(existingIdx, inlinePresentation);
+ mFieldInlineTooltipPresentations.set(existingIdx, tooltip);
+ mFieldFilters.set(existingIdx, filter);
+ return;
+ }
+ }
+ mFieldIds.add(id);
+ mAutofillDatatypes.add(datatype);
+ mFieldValues.add(value);
+ mFieldPresentations.add(presentation);
+ mFieldDialogPresentations.add(dialogPresentation);
+ mFieldInlinePresentations.add(inlinePresentation);
+ mFieldInlineTooltipPresentations.add(tooltip);
+ mFieldFilters.add(filter);
+ return;
+ }
+
/**
* Creates a new {@link Dataset} instance.
*
@@ -1391,37 +1421,20 @@
builder.setContent(ids.get(0), fieldContent);
}
final int inlinePresentationsSize = inlinePresentations.size();
-
- if (ids.size() == 0 && autofillDatatypes.size() > 0) {
- for (int i = 0; i < autofillDatatypes.size(); i++) {
- final String datatype = autofillDatatypes.get(i);
- final AutofillValue value = values.get(i);
- final RemoteViews fieldPresentation = presentations.get(i);
- final RemoteViews fieldDialogPresentation = dialogPresentations.get(i);
- final InlinePresentation fieldInlinePresentation =
- i < inlinePresentationsSize ? inlinePresentations.get(i) : null;
- final InlinePresentation fieldInlineTooltipPresentation =
- i < inlinePresentationsSize ? inlineTooltipPresentations.get(i) : null;
- final DatasetFieldFilter filter = filters.get(i);
- builder.setLifeTheUniverseAndEverything(
- datatype, value, fieldPresentation, fieldInlinePresentation,
- fieldInlineTooltipPresentation, filter, fieldDialogPresentation);
- }
- } else {
- for (int i = 0; i < ids.size(); i++) {
- final AutofillId id = ids.get(i);
- final AutofillValue value = values.get(i);
- final RemoteViews fieldPresentation = presentations.get(i);
- final RemoteViews fieldDialogPresentation = dialogPresentations.get(i);
- final InlinePresentation fieldInlinePresentation =
- i < inlinePresentationsSize ? inlinePresentations.get(i) : null;
- final InlinePresentation fieldInlineTooltipPresentation =
- i < inlinePresentationsSize ? inlineTooltipPresentations.get(i) : null;
- final DatasetFieldFilter filter = filters.get(i);
- builder.setLifeTheUniverseAndEverything(id, value, fieldPresentation,
- fieldInlinePresentation, fieldInlineTooltipPresentation, filter,
- fieldDialogPresentation);
- }
+ for (int i = 0; i < ids.size(); i++) {
+ final AutofillId id = ids.get(i);
+ final String datatype = autofillDatatypes.get(i);
+ final AutofillValue value = values.get(i);
+ final RemoteViews fieldPresentation = presentations.get(i);
+ final RemoteViews fieldDialogPresentation = dialogPresentations.get(i);
+ final InlinePresentation fieldInlinePresentation =
+ i < inlinePresentationsSize ? inlinePresentations.get(i) : null;
+ final InlinePresentation fieldInlineTooltipPresentation =
+ i < inlinePresentationsSize ? inlineTooltipPresentations.get(i) : null;
+ final DatasetFieldFilter filter = filters.get(i);
+ builder.createFromParcel(id, datatype, value, fieldPresentation,
+ fieldInlinePresentation, fieldInlineTooltipPresentation, filter,
+ fieldDialogPresentation);
}
builder.setAuthentication(authentication);
builder.setId(datasetId);
diff --git a/core/java/android/service/credentials/CredentialProviderInfoFactory.java b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
index 6f17b87..8072330 100644
--- a/core/java/android/service/credentials/CredentialProviderInfoFactory.java
+++ b/core/java/android/service/credentials/CredentialProviderInfoFactory.java
@@ -359,16 +359,6 @@
Log.e(TAG, "Failed to get capabilities: ", e);
}
- try {
- String[] discovered =
- metadata.getStringArray(CredentialProviderService.CAPABILITY_META_DATA_KEY);
- if (discovered != null) {
- capabilities.addAll(Arrays.asList(discovered));
- }
- } catch (Resources.NotFoundException | NullPointerException e) {
- Log.e(TAG, "Failed to get capabilities: ", e);
- }
-
if (capabilities.size() == 0) {
Log.e(TAG, "No capabilities found for provider:" + serviceInfo);
return output;
diff --git a/core/java/android/service/dreams/DreamOverlayConnectionHandler.java b/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
new file mode 100644
index 0000000..cafe02a
--- /dev/null
+++ b/core/java/android/service/dreams/DreamOverlayConnectionHandler.java
@@ -0,0 +1,242 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.dreams;
+
+import android.annotation.NonNull;
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
+import android.os.RemoteException;
+import android.util.Log;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ObservableServiceConnection;
+import com.android.internal.util.PersistentServiceConnection;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.Executor;
+import java.util.function.Consumer;
+
+/**
+ * Handles the service connection to {@link IDreamOverlay}
+ *
+ * @hide
+ */
+@VisibleForTesting
+public final class DreamOverlayConnectionHandler {
+ private static final String TAG = "DreamOverlayConnection";
+
+ private static final int MSG_ADD_CONSUMER = 1;
+ private static final int MSG_REMOVE_CONSUMER = 2;
+ private static final int MSG_OVERLAY_CLIENT_READY = 3;
+
+ private final Handler mHandler;
+ private final PersistentServiceConnection<IDreamOverlay> mConnection;
+ // Retrieved Client
+ private IDreamOverlayClient mClient;
+ // A list of pending requests to execute on the overlay.
+ private final List<Consumer<IDreamOverlayClient>> mConsumers = new ArrayList<>();
+ private final OverlayConnectionCallback mCallback;
+
+ DreamOverlayConnectionHandler(
+ Context context,
+ Looper looper,
+ Intent serviceIntent,
+ int minConnectionDurationMs,
+ int maxReconnectAttempts,
+ int baseReconnectDelayMs) {
+ this(context, looper, serviceIntent, minConnectionDurationMs, maxReconnectAttempts,
+ baseReconnectDelayMs, new Injector());
+ }
+
+ @VisibleForTesting
+ public DreamOverlayConnectionHandler(
+ Context context,
+ Looper looper,
+ Intent serviceIntent,
+ int minConnectionDurationMs,
+ int maxReconnectAttempts,
+ int baseReconnectDelayMs,
+ Injector injector) {
+ mCallback = new OverlayConnectionCallback();
+ mHandler = new Handler(looper, new OverlayHandlerCallback());
+ mConnection = injector.buildConnection(
+ context,
+ mHandler,
+ serviceIntent,
+ minConnectionDurationMs,
+ maxReconnectAttempts,
+ baseReconnectDelayMs
+ );
+ }
+
+ /**
+ * Bind to the overlay service. If binding fails, we automatically call unbind to clean
+ * up resources.
+ *
+ * @return true if binding was successful, false otherwise.
+ */
+ public boolean bind() {
+ mConnection.addCallback(mCallback);
+ final boolean success = mConnection.bind();
+ if (!success) {
+ unbind();
+ }
+ return success;
+ }
+
+ /**
+ * Unbind from the overlay service, clearing any pending callbacks.
+ */
+ public void unbind() {
+ mConnection.removeCallback(mCallback);
+ // Remove any pending messages.
+ mHandler.removeCallbacksAndMessages(null);
+ mClient = null;
+ mConsumers.clear();
+ mConnection.unbind();
+ }
+
+ /**
+ * Adds a consumer to run once the overlay service has connected. If the overlay service
+ * disconnects (eg binding dies) and then reconnects, this consumer will be re-run unless
+ * removed.
+ *
+ * @param consumer The consumer to run. This consumer is always executed asynchronously.
+ */
+ public void addConsumer(Consumer<IDreamOverlayClient> consumer) {
+ final Message msg = mHandler.obtainMessage(MSG_ADD_CONSUMER, consumer);
+ mHandler.sendMessage(msg);
+ }
+
+ /**
+ * Removes the consumer, preventing this consumer from being called again.
+ *
+ * @param consumer The consumer to remove.
+ */
+ public void removeConsumer(Consumer<IDreamOverlayClient> consumer) {
+ final Message msg = mHandler.obtainMessage(MSG_REMOVE_CONSUMER, consumer);
+ mHandler.sendMessage(msg);
+ // Clear any pending messages to add this consumer
+ mHandler.removeMessages(MSG_ADD_CONSUMER, consumer);
+ }
+
+ private final class OverlayHandlerCallback implements Handler.Callback {
+ @Override
+ public boolean handleMessage(@NonNull Message msg) {
+ switch (msg.what) {
+ case MSG_OVERLAY_CLIENT_READY:
+ onOverlayClientReady((IDreamOverlayClient) msg.obj);
+ break;
+ case MSG_ADD_CONSUMER:
+ onAddConsumer((Consumer<IDreamOverlayClient>) msg.obj);
+ break;
+ case MSG_REMOVE_CONSUMER:
+ onRemoveConsumer((Consumer<IDreamOverlayClient>) msg.obj);
+ break;
+ }
+ return true;
+ }
+ }
+
+ private void onOverlayClientReady(IDreamOverlayClient client) {
+ mClient = client;
+ for (Consumer<IDreamOverlayClient> consumer : mConsumers) {
+ consumer.accept(mClient);
+ }
+ }
+
+ private void onAddConsumer(Consumer<IDreamOverlayClient> consumer) {
+ if (mClient != null) {
+ consumer.accept(mClient);
+ }
+ mConsumers.add(consumer);
+ }
+
+ private void onRemoveConsumer(Consumer<IDreamOverlayClient> consumer) {
+ mConsumers.remove(consumer);
+ }
+
+ private final class OverlayConnectionCallback implements
+ ObservableServiceConnection.Callback<IDreamOverlay> {
+
+ private final IDreamOverlayClientCallback mClientCallback =
+ new IDreamOverlayClientCallback.Stub() {
+ @Override
+ public void onDreamOverlayClient(IDreamOverlayClient client) {
+ final Message msg =
+ mHandler.obtainMessage(MSG_OVERLAY_CLIENT_READY, client);
+ mHandler.sendMessage(msg);
+ }
+ };
+
+ @Override
+ public void onConnected(
+ ObservableServiceConnection<IDreamOverlay> connection,
+ IDreamOverlay service) {
+ try {
+ service.getClient(mClientCallback);
+ } catch (RemoteException e) {
+ Log.e(TAG, "could not get DreamOverlayClient", e);
+ }
+ }
+
+ @Override
+ public void onDisconnected(ObservableServiceConnection<IDreamOverlay> connection,
+ int reason) {
+ mClient = null;
+ // Cancel any pending messages about the overlay being ready, since it is no
+ // longer ready.
+ mHandler.removeMessages(MSG_OVERLAY_CLIENT_READY);
+ }
+ }
+
+ /**
+ * Injector for testing
+ */
+ @VisibleForTesting
+ public static class Injector {
+ /**
+ * Returns milliseconds since boot, not counting time spent in deep sleep. Can be overridden
+ * in tests with a fake clock.
+ */
+ public PersistentServiceConnection<IDreamOverlay> buildConnection(
+ Context context,
+ Handler handler,
+ Intent serviceIntent,
+ int minConnectionDurationMs,
+ int maxReconnectAttempts,
+ int baseReconnectDelayMs) {
+ final Executor executor = handler::post;
+ final int flags = Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE;
+ return new PersistentServiceConnection<>(
+ context,
+ executor,
+ handler,
+ IDreamOverlay.Stub::asInterface,
+ serviceIntent,
+ flags,
+ minConnectionDurationMs,
+ maxReconnectAttempts,
+ baseReconnectDelayMs
+ );
+ }
+ }
+}
diff --git a/core/java/android/service/dreams/DreamService.java b/core/java/android/service/dreams/DreamService.java
index d0f3820..3a32352 100644
--- a/core/java/android/service/dreams/DreamService.java
+++ b/core/java/android/service/dreams/DreamService.java
@@ -68,8 +68,6 @@
import com.android.internal.R;
import com.android.internal.util.DumpUtils;
-import com.android.internal.util.ObservableServiceConnection;
-import com.android.internal.util.PersistentServiceConnection;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -77,8 +75,6 @@
import java.io.FileDescriptor;
import java.io.IOException;
import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.concurrent.Executor;
import java.util.function.Consumer;
/**
@@ -234,7 +230,6 @@
private boolean mCanDoze;
private boolean mDozing;
private boolean mWindowless;
- private boolean mOverlayFinishing;
private int mDozeScreenState = Display.STATE_UNKNOWN;
private int mDozeScreenBrightness = PowerManager.BRIGHTNESS_DEFAULT;
@@ -246,88 +241,7 @@
private DreamServiceWrapper mDreamServiceWrapper;
private Runnable mDispatchAfterOnAttachedToWindow;
- private OverlayConnection mOverlayConnection;
-
- private static class OverlayConnection extends PersistentServiceConnection<IDreamOverlay> {
- // Retrieved Client
- private IDreamOverlayClient mClient;
-
- // A list of pending requests to execute on the overlay.
- private final ArrayList<Consumer<IDreamOverlayClient>> mConsumers = new ArrayList<>();
-
- private final IDreamOverlayClientCallback mClientCallback =
- new IDreamOverlayClientCallback.Stub() {
- @Override
- public void onDreamOverlayClient(IDreamOverlayClient client) {
- mClient = client;
-
- for (Consumer<IDreamOverlayClient> consumer : mConsumers) {
- consumer.accept(mClient);
- }
- }
- };
-
- private final Callback<IDreamOverlay> mCallback = new Callback<IDreamOverlay>() {
- @Override
- public void onConnected(ObservableServiceConnection<IDreamOverlay> connection,
- IDreamOverlay service) {
- try {
- service.getClient(mClientCallback);
- } catch (RemoteException e) {
- Log.e(TAG, "could not get DreamOverlayClient", e);
- }
- }
-
- @Override
- public void onDisconnected(ObservableServiceConnection<IDreamOverlay> connection,
- int reason) {
- mClient = null;
- }
- };
-
- OverlayConnection(Context context,
- Executor executor,
- Handler handler,
- ServiceTransformer<IDreamOverlay> transformer,
- Intent serviceIntent,
- int flags,
- int minConnectionDurationMs,
- int maxReconnectAttempts,
- int baseReconnectDelayMs) {
- super(context, executor, handler, transformer, serviceIntent, flags,
- minConnectionDurationMs,
- maxReconnectAttempts, baseReconnectDelayMs);
- }
-
- @Override
- public boolean bind() {
- addCallback(mCallback);
- return super.bind();
- }
-
- @Override
- public void unbind() {
- removeCallback(mCallback);
- super.unbind();
- }
-
- public void addConsumer(Consumer<IDreamOverlayClient> consumer) {
- execute(() -> {
- mConsumers.add(consumer);
- if (mClient != null) {
- consumer.accept(mClient);
- }
- });
- }
-
- public void removeConsumer(Consumer<IDreamOverlayClient> consumer) {
- execute(() -> mConsumers.remove(consumer));
- }
-
- public void clearConsumers() {
- execute(() -> mConsumers.clear());
- }
- }
+ private DreamOverlayConnectionHandler mOverlayConnection;
private final IDreamOverlayCallback mOverlayCallback = new IDreamOverlayCallback.Stub() {
@Override
@@ -1030,18 +944,18 @@
final Resources resources = getResources();
final Intent overlayIntent = new Intent().setComponent(overlayComponent);
- mOverlayConnection = new OverlayConnection(
+ mOverlayConnection = new DreamOverlayConnectionHandler(
/* context= */ this,
- getMainExecutor(),
- mHandler,
- IDreamOverlay.Stub::asInterface,
+ Looper.getMainLooper(),
overlayIntent,
- /* flags= */ Context.BIND_AUTO_CREATE | Context.BIND_FOREGROUND_SERVICE,
resources.getInteger(R.integer.config_minDreamOverlayDurationMs),
resources.getInteger(R.integer.config_dreamOverlayMaxReconnectAttempts),
resources.getInteger(R.integer.config_dreamOverlayReconnectTimeoutMs));
- mOverlayConnection.bind();
+ if (!mOverlayConnection.bind()) {
+ // Binding failed.
+ mOverlayConnection = null;
+ }
}
return mDreamServiceWrapper;
@@ -1069,9 +983,7 @@
// If there is an active overlay connection, signal that the dream is ending before
// continuing. Note that the overlay cannot rely on the unbound state, since another dream
// might have bound to it in the meantime.
- if (mOverlayConnection != null && !mOverlayFinishing) {
- // Set mOverlayFinish to true to only allow this consumer to be added once.
- mOverlayFinishing = true;
+ if (mOverlayConnection != null) {
mOverlayConnection.addConsumer(overlay -> {
try {
overlay.endDream();
@@ -1082,7 +994,6 @@
Log.e(mTag, "could not inform overlay of dream end:" + e);
}
});
- mOverlayConnection.clearConsumers();
return;
}
diff --git a/core/java/android/service/notification/NotificationListenerService.java b/core/java/android/service/notification/NotificationListenerService.java
index e55e2e5..1d49049 100644
--- a/core/java/android/service/notification/NotificationListenerService.java
+++ b/core/java/android/service/notification/NotificationListenerService.java
@@ -77,6 +77,7 @@
* <pre>
* <service android:name=".NotificationListener"
* android:label="@string/service_name"
+ * android:exported="false"
* android:permission="android.permission.BIND_NOTIFICATION_LISTENER_SERVICE">
* <intent-filter>
* <action android:name="android.service.notification.NotificationListenerService" />
@@ -1420,7 +1421,7 @@
if (getContext().getApplicationInfo().targetSdkVersion < Build.VERSION_CODES.P) {
ArrayList<Person> people = notification.extras.getParcelableArrayList(
Notification.EXTRA_PEOPLE_LIST, android.app.Person.class);
- if (people != null && people.isEmpty()) {
+ if (people != null && !people.isEmpty()) {
int size = people.size();
String[] peopleArray = new String[size];
for (int i = 0; i < size; i++) {
diff --git a/core/java/android/service/voice/AbstractDetector.java b/core/java/android/service/voice/AbstractDetector.java
index 644a2bf..8648e38 100644
--- a/core/java/android/service/voice/AbstractDetector.java
+++ b/core/java/android/service/voice/AbstractDetector.java
@@ -20,7 +20,6 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityThread;
-import android.app.compat.CompatChanges;
import android.media.AudioFormat;
import android.media.permission.Identity;
import android.os.Binder;
@@ -100,7 +99,7 @@
public boolean startRecognition(
@NonNull ParcelFileDescriptor audioStream,
@NonNull AudioFormat audioFormat,
- @Nullable PersistableBundle options) throws IllegalDetectorStateException {
+ @Nullable PersistableBundle options) {
if (DEBUG) {
Slog.i(TAG, "#recognizeHotword");
}
@@ -132,18 +131,13 @@
* @param sharedMemory The unrestricted data blob to provide to the
* {@link VisualQueryDetectionService} and {@link HotwordDetectionService}. Use this to
* provide the hotword models data or other such data to the trusted process.
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of
- * Android Tiramisu or above and attempts to start a recognition when the detector is
- * not able based on the state. Because the caller receives updates via an asynchronous
- * callback and the state of the detector can change without caller's knowledge, a
- * checked exception is thrown.
* @throws IllegalStateException if this {@link HotwordDetector} wasn't specified to use a
* {@link HotwordDetectionService} or {@link VisualQueryDetectionService} when it was
* created.
*/
@Override
public void updateState(@Nullable PersistableBundle options,
- @Nullable SharedMemory sharedMemory) throws IllegalDetectorStateException {
+ @Nullable SharedMemory sharedMemory) {
if (DEBUG) {
Slog.d(TAG, "updateState()");
}
@@ -199,13 +193,9 @@
}
}
- protected void throwIfDetectorIsNoLongerActive() throws IllegalDetectorStateException {
+ protected void throwIfDetectorIsNoLongerActive() {
if (!mIsDetectorActive.get()) {
Slog.e(TAG, "attempting to use a destroyed detector which is no longer active");
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "attempting to use a destroyed detector which is no longer active");
- }
throw new IllegalStateException(
"attempting to use a destroyed detector which is no longer active");
}
@@ -238,11 +228,16 @@
/** Called when the detection fails due to an error. */
@Override
- public void onError(DetectorFailure detectorFailure) {
- Slog.v(TAG, "BinderCallback#onError detectorFailure: " + detectorFailure);
+ public void onHotwordDetectionServiceFailure(
+ HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
+ Slog.v(TAG, "BinderCallback#onHotwordDetectionServiceFailure: "
+ + hotwordDetectionServiceFailure);
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
- mCallback.onFailure(detectorFailure != null ? detectorFailure
- : new UnknownFailure("Error data is null"));
+ if (hotwordDetectionServiceFailure != null) {
+ mCallback.onFailure(hotwordDetectionServiceFailure);
+ } else {
+ mCallback.onUnknownFailure("Error data is null");
+ }
}));
}
diff --git a/core/java/android/service/voice/AlwaysOnHotwordDetector.java b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
index d613b38..a987773 100644
--- a/core/java/android/service/voice/AlwaysOnHotwordDetector.java
+++ b/core/java/android/service/voice/AlwaysOnHotwordDetector.java
@@ -280,6 +280,9 @@
private static final int MSG_HOTWORD_REJECTED = 6;
private static final int MSG_HOTWORD_STATUS_REPORTED = 7;
private static final int MSG_PROCESS_RESTARTED = 8;
+ private static final int MSG_DETECTION_HOTWORD_DETECTION_SERVICE_FAILURE = 9;
+ private static final int MSG_DETECTION_SOUND_TRIGGER_FAILURE = 10;
+ private static final int MSG_DETECTION_UNKNOWN_FAILURE = 11;
private final String mText;
private final Locale mLocale;
@@ -773,12 +776,28 @@
/**
* {@inheritDoc}
*
- * @deprecated Use {@link HotwordDetector.Callback#onError(DetectorFailure)} instead.
+ * @deprecated On {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above,
+ * implement {@link HotwordDetector.Callback#onFailure(HotwordDetectionServiceFailure)},
+ * {@link AlwaysOnHotwordDetector.Callback#onFailure(SoundTriggerFailure)},
+ * {@link HotwordDetector.Callback#onUnknownFailure(String)} instead.
*/
@Deprecated
@Override
public abstract void onError();
+ /**
+ * Called when the detection fails due to an error occurs in the
+ * {@link com.android.server.soundtrigger.SoundTriggerService} and
+ * {@link com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareService},
+ * {@link SoundTriggerFailure} will be reported to the detector.
+ *
+ * @param soundTriggerFailure It provides the error code, error message and suggested
+ * action.
+ */
+ public void onFailure(@NonNull SoundTriggerFailure soundTriggerFailure) {
+ onError();
+ }
+
/** {@inheritDoc} */
public abstract void onRecognitionPaused();
@@ -865,28 +884,19 @@
/**
* {@inheritDoc}
*
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above and this AlwaysOnHotwordDetector wasn't specified to use a
- * {@link HotwordDetectionService} when it was created. In addition, the exception can
- * be thrown if this AlwaysOnHotwordDetector is in an invalid or error state.
- * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if
- * this AlwaysOnHotwordDetector wasn't specified to use a
- * {@link HotwordDetectionService} when it was created. In addition, the exception can
- * be thrown if this AlwaysOnHotwordDetector is in an invalid or error state.
+ * @throws IllegalStateException if this AlwaysOnHotwordDetector wasn't specified to use a
+ * {@link HotwordDetectionService} when it was created. In addition, if this
+ * AlwaysOnHotwordDetector is in an invalid or error state.
*/
@Override
public final void updateState(@Nullable PersistableBundle options,
- @Nullable SharedMemory sharedMemory) throws IllegalDetectorStateException {
+ @Nullable SharedMemory sharedMemory) {
synchronized (mLock) {
if (!mSupportSandboxedDetectionService) {
throw new IllegalStateException(
"updateState called, but it doesn't support hotword detection service");
}
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "updateState called on an invalid detector or error state");
- }
throw new IllegalStateException(
"updateState called on an invalid detector or error state");
}
@@ -907,17 +917,16 @@
@TestApi
public void overrideAvailability(int availability) {
synchronized (mLock) {
+ mAvailability = availability;
+ mIsAvailabilityOverriddenByTestApi = true;
// ENROLLED state requires there to be metadata about the sound model so a fake one
// is created.
- if (mKeyphraseMetadata == null && availability == STATE_KEYPHRASE_ENROLLED) {
+ if (mKeyphraseMetadata == null && mAvailability == STATE_KEYPHRASE_ENROLLED) {
Set<Locale> fakeSupportedLocales = new HashSet<>();
fakeSupportedLocales.add(mLocale);
mKeyphraseMetadata = new KeyphraseMetadata(1, mText, fakeSupportedLocales,
AlwaysOnHotwordDetector.RECOGNITION_MODE_VOICE_TRIGGER);
}
-
- mAvailability = availability;
- mIsAvailabilityOverriddenByTestApi = true;
notifyStateChangedLocked();
}
}
@@ -974,23 +983,14 @@
* @see #RECOGNITION_MODE_USER_IDENTIFICATION
* @see #RECOGNITION_MODE_VOICE_TRIGGER
*
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above. Because the caller receives availability updates via an asynchronous
- * callback, it may be due to the availability changing while this call is performed.
- * - Throws if the detector is in an invalid or error state.
- * This may happen if another detector has been instantiated or the
- * {@link VoiceInteractionService} hosting this detector has been shut down.
- * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
- * 33 Android if the recognition isn't supported. Callers should only call this method
- * after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
- * avoid this exception.
- * @throws IllegalStateException Thrown when a caller has a target SDK below Android API level
- * 33 if the detector is in an invalid or error state. This may happen if another
- * detector has been instantiated or the {@link VoiceInteractionService} hosting this
- * detector has been shut down.
+ * @throws UnsupportedOperationException if the keyphrase itself isn't supported.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+ * @throws IllegalStateException if the detector is in an invalid or error state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
- public @RecognitionModes
- int getSupportedRecognitionModes() throws IllegalDetectorStateException {
+ public @RecognitionModes int getSupportedRecognitionModes() {
if (DBG) Slog.d(TAG, "getSupportedRecognitionModes()");
synchronized (mLock) {
return getSupportedRecognitionModesLocked();
@@ -998,22 +998,14 @@
}
@GuardedBy("mLock")
- private int getSupportedRecognitionModesLocked() throws IllegalDetectorStateException {
+ private int getSupportedRecognitionModesLocked() {
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException("getSupportedRecognitionModes called on an"
- + " invalid detector or error state");
- }
throw new IllegalStateException(
"getSupportedRecognitionModes called on an invalid detector or error state");
}
// This method only makes sense if we can actually support a recognition.
if (mAvailability != STATE_KEYPHRASE_ENROLLED || mKeyphraseMetadata == null) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException("Getting supported recognition modes for"
- + " the keyphrase is not supported");
- }
throw new UnsupportedOperationException(
"Getting supported recognition modes for the keyphrase is not supported");
}
@@ -1068,30 +1060,15 @@
* startRecognition request. This data is intended to provide additional parameters
* when starting the opaque sound model.
* @return Indicates whether the call succeeded or not.
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above and attempts to start a recognition when the detector is not able based on
- * the availability state. This can be thrown even if the state has been checked before
- * calling this method because the caller receives availability updates via an
- * asynchronous callback, it may be due to the availability changing while this call is
- * performed.
- * - Throws if the recognition isn't supported.
- * Callers should only call this method after a supported state callback on
- * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
- * - Also throws if the detector is in an invalid or error state.
- * This may happen if another detector has been instantiated or the
- * {@link VoiceInteractionService} hosting this detector has been shut down.
- * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
- * 33 Android if the recognition isn't supported. Callers should only call this method
- * after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
- * avoid this exception.
- * @throws IllegalStateException Thrown when a caller has a target SDK below Android API level
- * 33 if the detector is in an invalid or error state. This may happen if another
- * detector has been instantiated or the {@link VoiceInteractionService} hosting this
- * detector has been shut down.
+ * @throws UnsupportedOperationException if the recognition isn't supported.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+ * @throws IllegalStateException if the detector is in an invalid or error state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
- public boolean startRecognition(@RecognitionFlags int recognitionFlags, @NonNull byte[] data)
- throws IllegalDetectorStateException {
+ public boolean startRecognition(@RecognitionFlags int recognitionFlags, @NonNull byte[] data) {
synchronized (mLock) {
return startRecognitionLocked(recognitionFlags, data)
== STATUS_OK;
@@ -1108,30 +1085,15 @@
*
* @param recognitionFlags The flags to control the recognition properties.
* @return Indicates whether the call succeeded or not.
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above and attempts to start a recognition when the detector is not able based on
- * the availability state. This can be thrown even if the state has been checked before
- * calling this method because the caller receives availability updates via an
- * asynchronous callback, it may be due to the availability changing while this call is
- * performed.
- * - Throws if the recognition isn't supported.
- * Callers should only call this method after a supported state callback on
- * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
- * - Also throws if the detector is in an invalid or error state.
- * This may happen if another detector has been instantiated or the
- * {@link VoiceInteractionService} hosting this detector has been shut down.
- * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
- * 33 if the recognition isn't supported. Callers should only call this method after a
- * supported state callback on {@link Callback#onAvailabilityChanged(int)} to avoid this
- * exception.
- * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
- * detector is in an invalid or error state. This may happen if another detector has
- * been instantiated or the {@link VoiceInteractionService} hosting this detector has
- * been shut down.
+ * @throws UnsupportedOperationException if the recognition isn't supported.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+ * @throws IllegalStateException if the detector is in an invalid or error state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
- public boolean startRecognition(@RecognitionFlags int recognitionFlags)
- throws IllegalDetectorStateException {
+ public boolean startRecognition(@RecognitionFlags int recognitionFlags) {
if (DBG) Slog.d(TAG, "startRecognition(" + recognitionFlags + ")");
synchronized (mLock) {
return startRecognitionLocked(recognitionFlags, null /* data */) == STATUS_OK;
@@ -1145,8 +1107,7 @@
*/
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
@Override
- public boolean startRecognition()
- throws IllegalDetectorStateException {
+ public boolean startRecognition() {
return startRecognition(0);
}
@@ -1156,44 +1117,28 @@
* Settings.Secure.VOICE_INTERACTION_SERVICE.
*
* @return Indicates whether the call succeeded or not.
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of
- * API level 33 or above and attempts to stop a recognition when the detector is
- * not able based on the state. This can be thrown even if the state has been checked
- * before calling this method because the caller receives availability updates via an
- * asynchronous callback, it may be due to the availability changing while this call is
- * performed.
- * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
- * 33 if the recognition isn't supported. Callers should only call this method after a
- * supported state callback on {@link Callback#onAvailabilityChanged(int)} to avoid this
- * exception.
- * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
- * detector is in an invalid or error state. This may happen if another detector has
- * been instantiated or the {@link VoiceInteractionService} hosting this detector has
- * been shut down.
+ * @throws UnsupportedOperationException if the recognition isn't supported.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+ * @throws IllegalStateException if the detector is in an invalid or error state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
// TODO: Remove this RequiresPermission since it isn't actually enforced. Also fix the javadoc
// about permissions enforcement (when it throws vs when it just returns false) for other
// methods in this class.
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
@Override
- public boolean stopRecognition() throws IllegalDetectorStateException {
+ public boolean stopRecognition() {
if (DBG) Slog.d(TAG, "stopRecognition()");
synchronized (mLock) {
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "stopRecognition called on an invalid detector or error state");
- }
throw new IllegalStateException(
"stopRecognition called on an invalid detector or error state");
}
// Check if we can start/stop a recognition.
if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "Recognition for the given keyphrase is not supported");
- }
throw new UnsupportedOperationException(
"Recognition for the given keyphrase is not supported");
}
@@ -1218,28 +1163,18 @@
* - {@link SoundTrigger#STATUS_BAD_VALUE} invalid input parameter
* - {@link SoundTrigger#STATUS_INVALID_OPERATION} if the call is out of sequence or
* if API is not supported by HAL
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * if the detector is in an invalid or error state. This may happen if another detector
- * has been instantiated or the {@link VoiceInteractionService} hosting this detector
- * has been shut down.
- * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
- * detector is in an invalid or error state. This may happen if another detector has
- * been instantiated or the {@link VoiceInteractionService} hosting this detector has
- * been shut down.
+ * @throws IllegalStateException if the detector is in an invalid or error state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
- public int setParameter(@ModelParams int modelParam, int value)
- throws IllegalDetectorStateException {
+ public int setParameter(@ModelParams int modelParam, int value) {
if (DBG) {
Slog.d(TAG, "setParameter(" + modelParam + ", " + value + ")");
}
synchronized (mLock) {
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "setParameter called on an invalid detector or error state");
- }
throw new IllegalStateException(
"setParameter called on an invalid detector or error state");
}
@@ -1260,27 +1195,18 @@
*
* @param modelParam {@link ModelParams}
* @return value of parameter
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * if the detector is in an invalid or error state. This may happen if another detector
- * has been instantiated or the {@link VoiceInteractionService} hosting this detector
- * has been shut down.
- * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if
- * the detector is in an invalid or error state. This may happen if another detector has
- * been instantiated or the {@link VoiceInteractionService} hosting this detector has
- * been shut down.
+ * @throws IllegalStateException if the detector is in an invalid or error state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
- public int getParameter(@ModelParams int modelParam) throws IllegalDetectorStateException {
+ public int getParameter(@ModelParams int modelParam) {
if (DBG) {
Slog.d(TAG, "getParameter(" + modelParam + ")");
}
synchronized (mLock) {
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "getParameter called on an invalid detector or error state");
- }
throw new IllegalStateException(
"getParameter called on an invalid detector or error state");
}
@@ -1298,29 +1224,19 @@
*
* @param modelParam {@link ModelParams}
* @return supported range of parameter, null if not supported
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * if the detector is in an invalid or error state. This may happen if another detector
- * has been instantiated or the {@link VoiceInteractionService} hosting this detector
- * has been shut down.
- * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if
- * the detector is in an invalid or error state. This may happen if another detector has
- * been instantiated or the {@link VoiceInteractionService} hosting this detector has
- * been shut down.
+ * @throws IllegalStateException if the detector is in an invalid or error state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
@Nullable
- public ModelParamRange queryParameter(@ModelParams int modelParam)
- throws IllegalDetectorStateException {
+ public ModelParamRange queryParameter(@ModelParams int modelParam) {
if (DBG) {
Slog.d(TAG, "queryParameter(" + modelParam + ")");
}
synchronized (mLock) {
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "queryParameter called on an invalid detector or error state");
- }
throw new IllegalStateException(
"queryParameter called on an invalid detector or error state");
}
@@ -1337,25 +1253,15 @@
* otherwise {@link #createReEnrollIntent()} should be preferred.
*
* @return An {@link Intent} to start enrollment for the given keyphrase.
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above.
- * - Thrown if managing they keyphrase isn't supported. Callers should only call this
- * method after a supported state callback on
- * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
- * - Thrown if the detector is in an invalid state. This may happen if another detector
- * has been instantiated or the {@link VoiceInteractionService} hosting this detector
- * has been shut down.
- * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
- * 33 if managing they keyphrase isn't supported. Callers should only call this method
- * after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
- * avoid this exception.
- * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
- * detector is in an invalid state. This may happen if another detector has been
- * instantiated or the {@link VoiceInteractionService} hosting this detector has been
- * shut down.
+ * @throws UnsupportedOperationException if managing they keyphrase isn't supported.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+ * @throws IllegalStateException if the detector is in an invalid state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
@Nullable
- public Intent createEnrollIntent() throws IllegalDetectorStateException {
+ public Intent createEnrollIntent() {
if (DBG) Slog.d(TAG, "createEnrollIntent");
synchronized (mLock) {
return getManageIntentLocked(KeyphraseEnrollmentInfo.MANAGE_ACTION_ENROLL);
@@ -1369,25 +1275,15 @@
* i.e. {@link #STATE_KEYPHRASE_ENROLLED}, otherwise invoking this may result in an error.
*
* @return An {@link Intent} to start un-enrollment for the given keyphrase.
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above.
- * - Thrown if managing they keyphrase isn't supported. Callers should only call this
- * method after a supported state callback on
- * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
- * - Thrown if the detector is in an invalid state. This may happen if another detector
- * has been instantiated or the {@link VoiceInteractionService} hosting this detector
- * has been shut down.
- * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
- * 33 if managing they keyphrase isn't supported. Callers should only call this method
- * after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
- * avoid this exception.
- * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
- * detector is in an invalid state. This may happen if another detector has been
- * instantiated or the {@link VoiceInteractionService} hosting this detector has been
- * shut down.
+ * @throws UnsupportedOperationException if managing they keyphrase isn't supported.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+ * @throws IllegalStateException if the detector is in an invalid state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
@Nullable
- public Intent createUnEnrollIntent() throws IllegalDetectorStateException {
+ public Intent createUnEnrollIntent() {
if (DBG) Slog.d(TAG, "createUnEnrollIntent");
synchronized (mLock) {
return getManageIntentLocked(KeyphraseEnrollmentInfo.MANAGE_ACTION_UN_ENROLL);
@@ -1401,25 +1297,15 @@
* i.e. {@link #STATE_KEYPHRASE_ENROLLED}, otherwise invoking this may result in an error.
*
* @return An {@link Intent} to start re-enrollment for the given keyphrase.
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above.
- * - Thrown if managing they keyphrase isn't supported. Callers should only call this
- * method after a supported state callback on
- * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
- * - Thrown if the detector is in an invalid state. This may happen if another detector
- * has been instantiated or the {@link VoiceInteractionService} hosting this detector
- * has been shut down.
- * @throws UnsupportedOperationException Thrown when a caller has a target SDK below API level
- * 33 if managing they keyphrase isn't supported. Callers should only call this method
- * after a supported state callback on {@link Callback#onAvailabilityChanged(int)} to
- * avoid this exception.
- * @throws IllegalStateException Thrown when a caller has a target SDK below API level 33 if the
- * detector is in an invalid state. This may happen if another detector has been
- * instantiated or the {@link VoiceInteractionService} hosting this detector has been
- * shut down.
+ * @throws UnsupportedOperationException if managing they keyphrase isn't supported.
+ * Callers should only call this method after a supported state callback on
+ * {@link Callback#onAvailabilityChanged(int)} to avoid this exception.
+ * @throws IllegalStateException if the detector is in an invalid or error state.
+ * This may happen if another detector has been instantiated or the
+ * {@link VoiceInteractionService} hosting this detector has been shut down.
*/
@Nullable
- public Intent createReEnrollIntent() throws IllegalDetectorStateException {
+ public Intent createReEnrollIntent() {
if (DBG) Slog.d(TAG, "createReEnrollIntent");
synchronized (mLock) {
return getManageIntentLocked(KeyphraseEnrollmentInfo.MANAGE_ACTION_RE_ENROLL);
@@ -1427,24 +1313,15 @@
}
@GuardedBy("mLock")
- private Intent getManageIntentLocked(@KeyphraseEnrollmentInfo.ManageActions int action)
- throws IllegalDetectorStateException {
+ private Intent getManageIntentLocked(@KeyphraseEnrollmentInfo.ManageActions int action) {
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "getManageIntent called on an invalid detector or error state");
- }
throw new IllegalStateException(
- "getManageIntent called on an invalid detector or error state");
+ "getManageIntent called on an invalid detector or error state");
}
// This method only makes sense if we can actually support a recognition.
if (mAvailability != STATE_KEYPHRASE_ENROLLED
&& mAvailability != STATE_KEYPHRASE_UNENROLLED) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "Managing the given keyphrase is not supported");
- }
throw new UnsupportedOperationException(
"Managing the given keyphrase is not supported");
}
@@ -1528,27 +1405,19 @@
@GuardedBy("mLock")
private int startRecognitionLocked(int recognitionFlags,
- @Nullable byte[] data) throws IllegalDetectorStateException {
+ @Nullable byte[] data) {
if (DBG) {
Slog.d(TAG, "startRecognition("
+ recognitionFlags
+ ", " + Arrays.toString(data) + ")");
}
if (mAvailability == STATE_INVALID || mAvailability == STATE_ERROR) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "startRecognition called on an invalid detector or error state");
- }
throw new IllegalStateException(
"startRecognition called on an invalid detector or error state");
}
// Check if we can start/stop a recognition.
if (mAvailability != STATE_KEYPHRASE_ENROLLED) {
- if (CompatChanges.isChangeEnabled(HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION)) {
- throw new IllegalDetectorStateException(
- "Recognition for the given keyphrase is not supported");
- }
throw new UnsupportedOperationException(
"Recognition for the given keyphrase is not supported");
}
@@ -1705,18 +1574,43 @@
@Override
public void onError(int status) {
Slog.i(TAG, "onError: " + status);
- // This is a workaround before the sound trigger uses the onDetectionFailure method.
- Message.obtain(mHandler, MSG_DETECTION_ERROR,
- new SoundTriggerFailure(status, "Sound trigger error")).sendToTarget();
+ // TODO(b/271534248): This is a workaround before the sound trigger uses the new error
+ // method.
+ Message.obtain(mHandler, MSG_DETECTION_SOUND_TRIGGER_FAILURE,
+ new SoundTriggerFailure(SoundTriggerFailure.ERROR_CODE_UNKNOWN,
+ "Sound trigger error")).sendToTarget();
}
@Override
- public void onDetectionFailure(DetectorFailure detectorFailure) {
- Slog.v(TAG, "onDetectionFailure detectorFailure: " + detectorFailure);
- Message.obtain(mHandler, MSG_DETECTION_ERROR,
- detectorFailure != null ? detectorFailure
- : new UnknownFailure("Error data is null")).sendToTarget();
+ public void onHotwordDetectionServiceFailure(
+ HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
+ Slog.v(TAG, "onHotwordDetectionServiceFailure: " + hotwordDetectionServiceFailure);
+ if (hotwordDetectionServiceFailure != null) {
+ Message.obtain(mHandler, MSG_DETECTION_HOTWORD_DETECTION_SERVICE_FAILURE,
+ hotwordDetectionServiceFailure).sendToTarget();
+ } else {
+ Message.obtain(mHandler, MSG_DETECTION_UNKNOWN_FAILURE,
+ "Error data is null").sendToTarget();
+ }
}
+
+ @Override
+ public void onVisualQueryDetectionServiceFailure(
+ VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure)
+ throws RemoteException {
+ // It should never be called here.
+ Slog.w(TAG,
+ "onVisualQueryDetectionServiceFailure: " + visualQueryDetectionServiceFailure);
+ }
+
+ @Override
+ public void onUnknownFailure(String errorMessage) throws RemoteException {
+ Slog.v(TAG, "onUnknownFailure: " + errorMessage);
+ Message.obtain(mHandler, MSG_DETECTION_UNKNOWN_FAILURE,
+ !TextUtils.isEmpty(errorMessage) ? errorMessage
+ : "Error data is null").sendToTarget();
+ }
+
@Override
public void onRecognitionPaused() {
Slog.i(TAG, "onRecognitionPaused");
@@ -1749,7 +1643,7 @@
}
void onDetectorRemoteException() {
- Message.obtain(mHandler, MSG_DETECTION_ERROR,
+ Message.obtain(mHandler, MSG_DETECTION_HOTWORD_DETECTION_SERVICE_FAILURE,
new HotwordDetectionServiceFailure(
HotwordDetectionServiceFailure.ERROR_CODE_REMOTE_EXCEPTION,
"Detector remote exception occurs")).sendToTarget();
@@ -1779,7 +1673,9 @@
mExternalCallback.onDetected((EventPayload) message.obj);
break;
case MSG_DETECTION_ERROR:
- mExternalCallback.onFailure((DetectorFailure) message.obj);
+ // TODO(b/271534248): After reverting the workaround, this logic is still
+ // necessary.
+ mExternalCallback.onError();
break;
case MSG_DETECTION_PAUSE:
mExternalCallback.onRecognitionPaused();
@@ -1796,6 +1692,15 @@
case MSG_PROCESS_RESTARTED:
mExternalCallback.onHotwordDetectionServiceRestarted();
break;
+ case MSG_DETECTION_HOTWORD_DETECTION_SERVICE_FAILURE:
+ mExternalCallback.onFailure((HotwordDetectionServiceFailure) message.obj);
+ break;
+ case MSG_DETECTION_SOUND_TRIGGER_FAILURE:
+ mExternalCallback.onFailure((SoundTriggerFailure) message.obj);
+ break;
+ case MSG_DETECTION_UNKNOWN_FAILURE:
+ mExternalCallback.onUnknownFailure((String) message.obj);
+ break;
default:
super.handleMessage(message);
}
diff --git a/core/java/android/service/voice/DetectedPhrase.aidl b/core/java/android/service/voice/DetectedPhrase.aidl
deleted file mode 100644
index 23a405d..0000000
--- a/core/java/android/service/voice/DetectedPhrase.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.voice;
-
-parcelable DetectedPhrase;
diff --git a/core/java/android/service/voice/DetectedPhrase.java b/core/java/android/service/voice/DetectedPhrase.java
deleted file mode 100644
index bd90612..0000000
--- a/core/java/android/service/voice/DetectedPhrase.java
+++ /dev/null
@@ -1,286 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.voice;
-
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.SystemApi;
-import android.os.Parcelable;
-
-import com.android.internal.util.DataClass;
-import com.android.internal.util.Preconditions;
-
-/**
- * Details about the phrase used to generate a {@link HotwordDetectedResult}
- *
- * @hide
- */
-@DataClass(
- genConstructor = false,
- genBuilder = true,
- genEqualsHashCode = true,
- genHiddenConstDefs = true,
- genParcelable = true,
- genToString = true
-)
-@SystemApi
-public final class DetectedPhrase implements Parcelable {
-
- /**
- * An ID representing the keyphrase that triggered the successful detection.
- */
- private int mId = 0;
-
- static int defaultHotwordPhraseId() {
- return 0;
- }
-
- /**
- * A string representing exactly what was heard and interpreted by the service leading to
- * a successful detection.
- *
- * <p>Can be null if not set in {@link DetectedPhrase.Builder}
- */
- @Nullable
- private String mPhrase = null;
-
- /**
- * Provides an instance of {@link DetectedPhrase.Builder} with state corresponding to
- * this instance.
- * @hide
- */
- public DetectedPhrase.Builder buildUpon() {
- return new DetectedPhrase.Builder()
- .setId(mId)
- .setPhrase(mPhrase);
- }
-
- private void onConstructed() {
- Preconditions.checkArgumentNonnegative(mId, "hotwordPhraseId");
- }
-
-
-
- // Code below generated by codegen v1.0.23.
- //
- // DO NOT MODIFY!
- // CHECKSTYLE:OFF Generated code
- //
- // To regenerate run:
- // $ codegen $ANDROID_BUILD_TOP/frameworks/base/core/java/android/service/voice/DetectedPhrase.java
- //
- // To exclude the generated code from IntelliJ auto-formatting enable (one-time):
- // Settings > Editor > Code Style > Formatter Control
- //@formatter:off
-
-
- @DataClass.Generated.Member
- /* package-private */ DetectedPhrase(
- int id,
- @Nullable String phrase) {
- this.mId = id;
- this.mPhrase = phrase;
-
- onConstructed();
- }
-
- /**
- * An ID representing the keyphrase that triggered the successful detection.
- */
- @DataClass.Generated.Member
- public int getId() {
- return mId;
- }
-
- /**
- * A string representing exactly what was heard and interpreted by the service leading to
- * a successful detection.
- *
- * <p>Can be null if not set in {@link DetectedPhrase.Builder}
- */
- @DataClass.Generated.Member
- public @Nullable String getPhrase() {
- return mPhrase;
- }
-
- @Override
- @DataClass.Generated.Member
- public String toString() {
- // You can override field toString logic by defining methods like:
- // String fieldNameToString() { ... }
-
- return "DetectedPhrase { " +
- "id = " + mId + ", " +
- "phrase = " + mPhrase +
- " }";
- }
-
- @Override
- @DataClass.Generated.Member
- public boolean equals(@Nullable Object o) {
- // You can override field equality logic by defining either of the methods like:
- // boolean fieldNameEquals(DetectedPhrase other) { ... }
- // boolean fieldNameEquals(FieldType otherValue) { ... }
-
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
- @SuppressWarnings("unchecked")
- DetectedPhrase that = (DetectedPhrase) o;
- //noinspection PointlessBooleanExpression
- return true
- && mId == that.mId
- && java.util.Objects.equals(mPhrase, that.mPhrase);
- }
-
- @Override
- @DataClass.Generated.Member
- public int hashCode() {
- // You can override field hashCode logic by defining methods like:
- // int fieldNameHashCode() { ... }
-
- int _hash = 1;
- _hash = 31 * _hash + mId;
- _hash = 31 * _hash + java.util.Objects.hashCode(mPhrase);
- return _hash;
- }
-
- @Override
- @DataClass.Generated.Member
- public void writeToParcel(@NonNull android.os.Parcel dest, int flags) {
- // You can override field parcelling by defining methods like:
- // void parcelFieldName(Parcel dest, int flags) { ... }
-
- byte flg = 0;
- if (mPhrase != null) flg |= 0x2;
- dest.writeByte(flg);
- dest.writeInt(mId);
- if (mPhrase != null) dest.writeString(mPhrase);
- }
-
- @Override
- @DataClass.Generated.Member
- public int describeContents() { return 0; }
-
- /** @hide */
- @SuppressWarnings({"unchecked", "RedundantCast"})
- @DataClass.Generated.Member
- /* package-private */ DetectedPhrase(@NonNull android.os.Parcel in) {
- // You can override field unparcelling by defining methods like:
- // static FieldType unparcelFieldName(Parcel in) { ... }
-
- byte flg = in.readByte();
- int id = in.readInt();
- String phrase = (flg & 0x2) == 0 ? null : in.readString();
-
- this.mId = id;
- this.mPhrase = phrase;
-
- onConstructed();
- }
-
- @DataClass.Generated.Member
- public static final @NonNull Parcelable.Creator<DetectedPhrase> CREATOR
- = new Parcelable.Creator<DetectedPhrase>() {
- @Override
- public DetectedPhrase[] newArray(int size) {
- return new DetectedPhrase[size];
- }
-
- @Override
- public DetectedPhrase createFromParcel(@NonNull android.os.Parcel in) {
- return new DetectedPhrase(in);
- }
- };
-
- /**
- * A builder for {@link DetectedPhrase}
- */
- @SuppressWarnings("WeakerAccess")
- @DataClass.Generated.Member
- public static final class Builder {
-
- private int mId;
- private @Nullable String mPhrase;
-
- private long mBuilderFieldsSet = 0L;
-
- public Builder() {
- }
-
- /**
- * An ID representing the keyphrase that triggered the successful detection.
- */
- @DataClass.Generated.Member
- public @NonNull Builder setId(int value) {
- checkNotUsed();
- mBuilderFieldsSet |= 0x1;
- mId = value;
- return this;
- }
-
- /**
- * A string representing exactly what was heard and interpreted by the service leading to
- * a successful detection.
- *
- * <p>Can be null if not set in {@link DetectedPhrase.Builder}
- */
- @DataClass.Generated.Member
- public @NonNull Builder setPhrase(@NonNull String value) {
- checkNotUsed();
- mBuilderFieldsSet |= 0x2;
- mPhrase = value;
- return this;
- }
-
- /** Builds the instance. This builder should not be touched after calling this! */
- public @NonNull DetectedPhrase build() {
- checkNotUsed();
- mBuilderFieldsSet |= 0x4; // Mark builder used
-
- if ((mBuilderFieldsSet & 0x1) == 0) {
- mId = 0;
- }
- if ((mBuilderFieldsSet & 0x2) == 0) {
- mPhrase = null;
- }
- DetectedPhrase o = new DetectedPhrase(
- mId,
- mPhrase);
- return o;
- }
-
- private void checkNotUsed() {
- if ((mBuilderFieldsSet & 0x4) != 0) {
- throw new IllegalStateException(
- "This Builder should not be reused. Use a new Builder instance instead");
- }
- }
- }
-
- @DataClass.Generated(
- time = 1676870329959L,
- codegenVersion = "1.0.23",
- sourceFile = "frameworks/base/core/java/android/service/voice/DetectedPhrase.java",
- inputSignatures = "private int mId\nprivate @android.annotation.Nullable java.lang.String mPhrase\nstatic int defaultHotwordPhraseId()\npublic android.service.voice.DetectedPhrase.Builder buildUpon()\nprivate void onConstructed()\nclass DetectedPhrase extends java.lang.Object implements [android.os.Parcelable]\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)")
- @Deprecated
- private void __metadata() {}
-
-
- //@formatter:on
- // End of generated code
-
-}
diff --git a/core/java/android/service/voice/DetectorFailure.java b/core/java/android/service/voice/DetectorFailure.java
deleted file mode 100644
index c6efdc3..0000000
--- a/core/java/android/service/voice/DetectorFailure.java
+++ /dev/null
@@ -1,218 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.voice;
-
-import android.annotation.IntDef;
-import android.annotation.NonNull;
-import android.annotation.SuppressLint;
-import android.annotation.SystemApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-import android.text.TextUtils;
-
-import com.android.internal.util.Preconditions;
-
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-
-/**
- * This is used by the assistant application to know what went wrong during using the detector
- * and which action the application should take. The detector can be a HotwordDector or a visual
- * query detector.
- *
- * <p>Any class that derives this class must only add an integer value of error source type, an
- * integer value of error code and a string of error message passed into the constructor. Any other
- * field will not be parceled through. If the derived class has custom parceling implementation,
- * this class will not be able to unpack the parcel without having access to that implementation.
- *
- * @hide
- */
-@SuppressLint("ParcelNotFinal") // Safe because the constructor is package-private
-@SystemApi
-public abstract class DetectorFailure implements Parcelable {
-
- /**
- * A suggested action due to an unknown error occurs.
- */
- public static final int SUGGESTED_ACTION_UNKNOWN = 0;
-
- /**
- * Indicates that an error occurs, but no action is needed for the client. The error will be
- * recovered from within the framework.
- */
- public static final int SUGGESTED_ACTION_NONE = 1;
-
- /**
- * Indicates that an error occurs, but no action is needed for the client due to the error can
- * not be recovered. It means that the detection will not work even though the assistant
- * application creates the detector again.
- *
- * Example: The detection service always crashes after assistant application creates the
- * detector. The assistant application can stop re-creating the detector and show a suitable
- * error dialog to notify the user.
- */
- public static final int SUGGESTED_ACTION_DISABLE_DETECTION = 2;
-
- /**
- * Indicates that the detection service is invalid, the client needs to destroy its detector
- * first and recreate its detector later.
- */
- public static final int SUGGESTED_ACTION_RECREATE_DETECTOR = 3;
-
- /**
- * Indicates that the detection has stopped. The client needs to start recognition again.
- *
- * Example: The system server receives a Dsp trigger event.
- */
- public static final int SUGGESTED_ACTION_RESTART_RECOGNITION = 4;
-
- /**
- * @hide
- */
- @IntDef(prefix = {"SUGGESTED_ACTION_"}, value = {
- SUGGESTED_ACTION_UNKNOWN,
- SUGGESTED_ACTION_NONE,
- SUGGESTED_ACTION_DISABLE_DETECTION,
- SUGGESTED_ACTION_RECREATE_DETECTOR,
- SUGGESTED_ACTION_RESTART_RECOGNITION
- })
- @Retention(RetentionPolicy.SOURCE)
- public @interface SuggestedAction {}
-
- /**
- * Indicates that an error occurs from the unknown error source.
- *
- * @hide
- */
- public static final int ERROR_SOURCE_TYPE_UNKNOWN = -1;
-
- /**
- * Indicates that an error occurs from the hotword detection.
- *
- * @see HotwordDetectionServiceFailure#ERROR_CODE_BIND_FAILURE
- * @see HotwordDetectionServiceFailure#ERROR_CODE_BINDING_DIED
- * @see HotwordDetectionServiceFailure#ERROR_CODE_COPY_AUDIO_DATA_FAILURE
- * @see HotwordDetectionServiceFailure#ERROR_CODE_DETECT_TIMEOUT
- * @see HotwordDetectionServiceFailure#ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION
- * @see HotwordDetectionServiceFailure#ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE
- * @see HotwordDetectionServiceFailure#ERROR_CODE_REMOTE_EXCEPTION
- *
- * @hide
- */
- public static final int ERROR_SOURCE_TYPE_HOTWORD_DETECTION = 0;
-
- /**
- * Indicates that an error occurs from the sound trigger system service
- * {@link com.android.server.soundtrigger.SoundTriggerService} and
- * {@link com.android.server.soundtrigger_middleware.SoundTriggerMiddlewareService}.
- *
- * @see SoundTriggerFailure#ERROR_CODE_MODULE_DIED
- * @see SoundTriggerFailure#ERROR_CODE_RECOGNITION_RESUME_FAILED
- * @see SoundTriggerFailure#ERROR_CODE_UNEXPECTED_PREEMPTION
- *
- * @hide
- */
- public static final int ERROR_SOURCE_TYPE_SOUND_TRIGGER = 1;
-
- /**
- * Indicates that an error occurs from {@link VisualQueryDetectionService}.
- *
- * @see VisualQueryDetectionServiceFailure#ERROR_CODE_BIND_FAILURE
- * @see VisualQueryDetectionServiceFailure#ERROR_CODE_BINDING_DIED
- * @see VisualQueryDetectionServiceFailure#ERROR_CODE_ILLEGAL_ATTENTION_STATE
- * @see VisualQueryDetectionServiceFailure#ERROR_CODE_ILLEGAL_STREAMING_STATE
- * @see VisualQueryDetectionServiceFailure#ERROR_CODE_REMOTE_EXCEPTION
- *
- * @hide
- */
- public static final int ERROR_SOURCE_TYPE_VISUAL_QUERY_DETECTION = 2;
-
- private int mErrorSourceType = ERROR_SOURCE_TYPE_UNKNOWN;
- private int mErrorCode = UnknownFailure.ERROR_CODE_UNKNOWN;
- private String mErrorMessage = "Unknown";
-
- DetectorFailure(int errorSourceType, int errorCode, @NonNull String errorMessage) {
- Preconditions.checkArgumentInRange(errorSourceType, ERROR_SOURCE_TYPE_UNKNOWN,
- ERROR_SOURCE_TYPE_VISUAL_QUERY_DETECTION, "errorSourceType");
- if (TextUtils.isEmpty(errorMessage)) {
- throw new IllegalArgumentException("errorMessage is empty or null.");
- }
- mErrorSourceType = errorSourceType;
- mErrorCode = errorCode;
- mErrorMessage = errorMessage;
- }
-
- /**
- * Returns the suggested action.
- */
- @SuggestedAction
- public abstract int getSuggestedAction();
-
- /**
- * Returns the error code.
- *
- * @hide
- */
- public int getErrorCode() {
- return mErrorCode;
- }
-
- /**
- * Returns the error message.
- */
- @NonNull
- public String getErrorMessage() {
- return mErrorMessage;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- dest.writeInt(mErrorSourceType);
- dest.writeInt(mErrorCode);
- dest.writeString8(mErrorMessage);
- }
-
- public static final @NonNull Parcelable.Creator<DetectorFailure> CREATOR =
- new Parcelable.Creator<DetectorFailure>() {
- @Override
- public DetectorFailure[] newArray(int size) {
- return new DetectorFailure[size];
- }
-
- @Override
- public DetectorFailure createFromParcel(@NonNull Parcel in) {
- final int errorSourceType = in.readInt();
- final int errorCode = in.readInt();
- final String errorMessage = in.readString8();
- switch (errorSourceType) {
- case ERROR_SOURCE_TYPE_HOTWORD_DETECTION:
- return new HotwordDetectionServiceFailure(errorCode, errorMessage);
- case ERROR_SOURCE_TYPE_SOUND_TRIGGER:
- return new SoundTriggerFailure(errorCode, errorMessage);
- case ERROR_SOURCE_TYPE_VISUAL_QUERY_DETECTION:
- return new VisualQueryDetectionServiceFailure(errorCode, errorMessage);
- default:
- return new UnknownFailure(errorMessage);
- }
- }
- };
-}
diff --git a/core/java/android/service/voice/FailureSuggestedAction.java b/core/java/android/service/voice/FailureSuggestedAction.java
new file mode 100644
index 0000000..8408c3b
--- /dev/null
+++ b/core/java/android/service/voice/FailureSuggestedAction.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.voice;
+
+import android.annotation.IntDef;
+import android.annotation.SystemApi;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * This is used by the assistant application to know which action the application should take on a
+ * failure callback. The detector can be a HotwordDector or a visual query detector.
+ *
+ * @hide
+ */
+@SystemApi
+public final class FailureSuggestedAction {
+
+ /**
+ * A suggested action due to an unknown error occurs.
+ */
+ public static final int UNKNOWN = 0;
+
+ /**
+ * Indicates that an error occurs, but no action is needed for the client. The error will be
+ * recovered from within the framework.
+ */
+ public static final int NONE = 1;
+
+ /**
+ * Indicates that an error occurs, but no action is needed for the client due to the error can
+ * not be recovered. It means that the detection will not work even though the assistant
+ * application creates the detector again.
+ */
+ public static final int DISABLE_DETECTION = 2;
+
+ /**
+ * Indicates that the detection service is invalid, the client needs to destroy its detector
+ * first and recreate its detector later.
+ */
+ public static final int RECREATE_DETECTOR = 3;
+
+ /**
+ * Indicates that the detection has stopped. The client needs to start recognition again.
+ *
+ * Example: The system server receives a Dsp trigger event.
+ */
+ public static final int RESTART_RECOGNITION = 4;
+
+ /**
+ * @hide
+ */
+ @IntDef({UNKNOWN, NONE, DISABLE_DETECTION, RECREATE_DETECTOR, RESTART_RECOGNITION})
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface FailureSuggestedActionDef {}
+
+ private FailureSuggestedAction() {}
+}
diff --git a/core/java/android/service/voice/HotwordDetectedResult.java b/core/java/android/service/voice/HotwordDetectedResult.java
index dd3f99c..a1c5593 100644
--- a/core/java/android/service/voice/HotwordDetectedResult.java
+++ b/core/java/android/service/voice/HotwordDetectedResult.java
@@ -94,6 +94,9 @@
/** Represents unset value for the triggered audio channel. */
public static final int AUDIO_CHANNEL_UNSET = -1;
+ /** Represents unset value for the background audio signal power. */
+ public static final int BACKGROUND_AUDIO_POWER_UNSET = -1;
+
/** Limits the max value for the hotword offset. */
private static final int LIMIT_HOTWORD_OFFSET_MAX_VALUE = 60 * 60 * 1000; // 1 hour
@@ -203,23 +206,17 @@
* An ID representing the keyphrase that triggered the successful detection.
*
* <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted.
- *
- * @deprecated Use {@link #getDetectedPhrase()} and
- * {@link DetectedPhrase#getId()}.
*/
- @Deprecated
- public int getHotwordPhraseId() {
- return mDetectedPhrase.getId();
+ private final int mHotwordPhraseId;
+ private static int defaultHotwordPhraseId() {
+ return 0;
}
/**
* Returns the maximum value of {@link #getHotwordPhraseId()}.
- *
- * @deprecated There is no maximum phrase ID enforced
*/
- @Deprecated
public static int getMaxHotwordPhraseId() {
- return Integer.MAX_VALUE;
+ return 63;
}
/**
@@ -291,9 +288,23 @@
return mMediaSyncEvent;
}
- @NonNull
- private DetectedPhrase mDetectedPhrase =
- new DetectedPhrase.Builder().build();
+ /**
+ * Power of the background audio signal in which the hotword phrase was detected.
+ *
+ * <p> Only values between 0 and {@link #getMaxBackgroundAudioPower} (inclusive)
+ * and the special value {@link #BACKGROUND_AUDIO_POWER_UNSET} are valid.
+ */
+ private final int mBackgroundAudioPower;
+ private static int defaultBackgroundAudioPower() {
+ return BACKGROUND_AUDIO_POWER_UNSET;
+ }
+
+ /**
+ * Returns the maximum value of {@link #getBackgroundAudioPower()}.
+ */
+ public static int getMaxBackgroundAudioPower() {
+ return 255;
+ }
/**
* Returns how many bytes should be written into the Parcel
@@ -312,9 +323,6 @@
/**
* Returns how many bits have been written into the HotwordDetectedResult.
*
- * <p>{@link #getAudioStreams()} and {@link #getDetectedPhrase()}
- * are not counted here.
- *
* @hide
*/
public static int getUsageSize(@NonNull HotwordDetectedResult hotwordDetectedResult) {
@@ -342,14 +350,21 @@
if (hotwordDetectedResult.getPersonalizedScore() != defaultPersonalizedScore()) {
totalBits += bitCount(HotwordDetectedResult.getMaxScore());
}
+ if (hotwordDetectedResult.getHotwordPhraseId() != defaultHotwordPhraseId()) {
+ totalBits += bitCount(HotwordDetectedResult.getMaxHotwordPhraseId());
+ }
PersistableBundle persistableBundle = hotwordDetectedResult.getExtras();
if (!persistableBundle.isEmpty()) {
totalBits += getParcelableSize(persistableBundle) * Byte.SIZE;
}
+ if (hotwordDetectedResult.getBackgroundAudioPower() != defaultBackgroundAudioPower()) {
+ totalBits += bitCount(HotwordDetectedResult.getMaxBackgroundAudioPower());
+ }
+
return totalBits;
}
- static int bitCount(long value) {
+ private static int bitCount(long value) {
int bits = 0;
while (value > 0) {
bits++;
@@ -362,6 +377,12 @@
Preconditions.checkArgumentInRange(mScore, 0, getMaxScore(), "score");
Preconditions.checkArgumentInRange(mPersonalizedScore, 0, getMaxScore(),
"personalizedScore");
+ Preconditions.checkArgumentInRange(mHotwordPhraseId, 0, getMaxHotwordPhraseId(),
+ "hotwordPhraseId");
+ if (mBackgroundAudioPower != BACKGROUND_AUDIO_POWER_UNSET) {
+ Preconditions.checkArgumentInRange(mBackgroundAudioPower,
+ 0, getMaxBackgroundAudioPower(), "backgroundAudioPower");
+ }
Preconditions.checkArgumentInRange((long) mHotwordDurationMillis, 0,
AudioRecord.getMaxSharedAudioHistoryMillis(), "hotwordDurationMillis");
if (mHotwordOffsetMillis != HOTWORD_OFFSET_UNSET) {
@@ -456,25 +477,10 @@
Objects.requireNonNull(value, "value should not be null");
final Builder builder = (Builder) this;
// If the code gen flag in build() is changed, we must update the flag e.g. 0x200 here.
- builder.mBuilderFieldsSet |= 0x100;
+ builder.mBuilderFieldsSet |= 0x200;
builder.mAudioStreams = List.copyOf(value);
return builder;
}
-
- /**
- * An ID representing the keyphrase that triggered the successful detection.
- *
- * <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted.
- *
- * @deprecated Use {@link HotwordDetectedResult.Builder#setDetectedPhrase(DetectedPhrase)}
- * and {@link DetectedPhrase.Builder#setId(int)}
- */
- @Deprecated
- public @NonNull Builder setHotwordPhraseId(int value) {
- final Builder builder = (Builder) this;
- builder.setDetectedPhrase(new DetectedPhrase.Builder().setId(value).build());
- return builder;
- }
}
/**
@@ -491,9 +497,10 @@
.setHotwordDetectionPersonalized(mHotwordDetectionPersonalized)
.setScore(mScore)
.setPersonalizedScore(mPersonalizedScore)
+ .setHotwordPhraseId(mHotwordPhraseId)
.setAudioStreams(mAudioStreams)
.setExtras(mExtras)
- .setDetectedPhrase(mDetectedPhrase);
+ .setBackgroundAudioPower(mBackgroundAudioPower);
}
@@ -602,9 +609,10 @@
boolean hotwordDetectionPersonalized,
int score,
int personalizedScore,
+ int hotwordPhraseId,
@NonNull List<HotwordAudioStream> audioStreams,
@NonNull PersistableBundle extras,
- @NonNull DetectedPhrase detectedPhrase) {
+ int backgroundAudioPower) {
this.mConfidenceLevel = confidenceLevel;
com.android.internal.util.AnnotationValidations.validate(
HotwordConfidenceLevelValue.class, null, mConfidenceLevel);
@@ -615,15 +623,14 @@
this.mHotwordDetectionPersonalized = hotwordDetectionPersonalized;
this.mScore = score;
this.mPersonalizedScore = personalizedScore;
+ this.mHotwordPhraseId = hotwordPhraseId;
this.mAudioStreams = audioStreams;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mAudioStreams);
this.mExtras = extras;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mExtras);
- this.mDetectedPhrase = detectedPhrase;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mDetectedPhrase);
+ this.mBackgroundAudioPower = backgroundAudioPower;
onConstructed();
}
@@ -698,6 +705,16 @@
}
/**
+ * An ID representing the keyphrase that triggered the successful detection.
+ *
+ * <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted.
+ */
+ @DataClass.Generated.Member
+ public int getHotwordPhraseId() {
+ return mHotwordPhraseId;
+ }
+
+ /**
* App-specific extras to support trigger.
*
* <p>The size of this bundle will be limited to {@link #getMaxBundleSize}. Results will larger
@@ -727,9 +744,15 @@
return mExtras;
}
+ /**
+ * Power of the background audio signal in which the hotword phrase was detected.
+ *
+ * <p> Only values between 0 and {@link #getMaxBackgroundAudioPower} (inclusive)
+ * and the special value {@link #BACKGROUND_AUDIO_POWER_UNSET} are valid.
+ */
@DataClass.Generated.Member
- public @NonNull DetectedPhrase getDetectedPhrase() {
- return mDetectedPhrase;
+ public int getBackgroundAudioPower() {
+ return mBackgroundAudioPower;
}
@Override
@@ -747,9 +770,10 @@
"hotwordDetectionPersonalized = " + mHotwordDetectionPersonalized + ", " +
"score = " + mScore + ", " +
"personalizedScore = " + mPersonalizedScore + ", " +
+ "hotwordPhraseId = " + mHotwordPhraseId + ", " +
"audioStreams = " + mAudioStreams + ", " +
"extras = " + mExtras + ", " +
- "detectedPhrase = " + mDetectedPhrase +
+ "backgroundAudioPower = " + mBackgroundAudioPower +
" }";
}
@@ -774,9 +798,10 @@
&& mHotwordDetectionPersonalized == that.mHotwordDetectionPersonalized
&& mScore == that.mScore
&& mPersonalizedScore == that.mPersonalizedScore
+ && mHotwordPhraseId == that.mHotwordPhraseId
&& Objects.equals(mAudioStreams, that.mAudioStreams)
&& Objects.equals(mExtras, that.mExtras)
- && Objects.equals(mDetectedPhrase, that.mDetectedPhrase);
+ && mBackgroundAudioPower == that.mBackgroundAudioPower;
}
@Override
@@ -794,9 +819,10 @@
_hash = 31 * _hash + Boolean.hashCode(mHotwordDetectionPersonalized);
_hash = 31 * _hash + mScore;
_hash = 31 * _hash + mPersonalizedScore;
+ _hash = 31 * _hash + mHotwordPhraseId;
_hash = 31 * _hash + Objects.hashCode(mAudioStreams);
_hash = 31 * _hash + Objects.hashCode(mExtras);
- _hash = 31 * _hash + Objects.hashCode(mDetectedPhrase);
+ _hash = 31 * _hash + mBackgroundAudioPower;
return _hash;
}
@@ -817,9 +843,10 @@
dest.writeInt(mAudioChannel);
dest.writeInt(mScore);
dest.writeInt(mPersonalizedScore);
+ dest.writeInt(mHotwordPhraseId);
dest.writeParcelableList(mAudioStreams, flags);
dest.writeTypedObject(mExtras, flags);
- dest.writeTypedObject(mDetectedPhrase, flags);
+ dest.writeInt(mBackgroundAudioPower);
}
@Override
@@ -842,10 +869,11 @@
int audioChannel = in.readInt();
int score = in.readInt();
int personalizedScore = in.readInt();
+ int hotwordPhraseId = in.readInt();
List<HotwordAudioStream> audioStreams = new ArrayList<>();
in.readParcelableList(audioStreams, HotwordAudioStream.class.getClassLoader());
PersistableBundle extras = (PersistableBundle) in.readTypedObject(PersistableBundle.CREATOR);
- DetectedPhrase detectedPhrase = (DetectedPhrase) in.readTypedObject(DetectedPhrase.CREATOR);
+ int backgroundAudioPower = in.readInt();
this.mConfidenceLevel = confidenceLevel;
com.android.internal.util.AnnotationValidations.validate(
@@ -857,15 +885,14 @@
this.mHotwordDetectionPersonalized = hotwordDetectionPersonalized;
this.mScore = score;
this.mPersonalizedScore = personalizedScore;
+ this.mHotwordPhraseId = hotwordPhraseId;
this.mAudioStreams = audioStreams;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mAudioStreams);
this.mExtras = extras;
com.android.internal.util.AnnotationValidations.validate(
NonNull.class, null, mExtras);
- this.mDetectedPhrase = detectedPhrase;
- com.android.internal.util.AnnotationValidations.validate(
- NonNull.class, null, mDetectedPhrase);
+ this.mBackgroundAudioPower = backgroundAudioPower;
onConstructed();
}
@@ -899,9 +926,10 @@
private boolean mHotwordDetectionPersonalized;
private int mScore;
private int mPersonalizedScore;
+ private int mHotwordPhraseId;
private @NonNull List<HotwordAudioStream> mAudioStreams;
private @NonNull PersistableBundle mExtras;
- private @NonNull DetectedPhrase mDetectedPhrase;
+ private int mBackgroundAudioPower;
private long mBuilderFieldsSet = 0L;
@@ -1012,6 +1040,19 @@
}
/**
+ * An ID representing the keyphrase that triggered the successful detection.
+ *
+ * <p>Only values between 0 and {@link #getMaxHotwordPhraseId()} (inclusive) are accepted.
+ */
+ @DataClass.Generated.Member
+ public @NonNull Builder setHotwordPhraseId(int value) {
+ checkNotUsed();
+ mBuilderFieldsSet |= 0x100;
+ mHotwordPhraseId = value;
+ return this;
+ }
+
+ /**
* App-specific extras to support trigger.
*
* <p>The size of this bundle will be limited to {@link #getMaxBundleSize}. Results will larger
@@ -1039,23 +1080,29 @@
@DataClass.Generated.Member
public @NonNull Builder setExtras(@NonNull PersistableBundle value) {
checkNotUsed();
- mBuilderFieldsSet |= 0x200;
+ mBuilderFieldsSet |= 0x400;
mExtras = value;
return this;
}
+ /**
+ * Power of the background audio signal in which the hotword phrase was detected.
+ *
+ * <p> Only values between 0 and {@link #getMaxBackgroundAudioPower} (inclusive)
+ * and the special value {@link #BACKGROUND_AUDIO_POWER_UNSET} are valid.
+ */
@DataClass.Generated.Member
- public @NonNull Builder setDetectedPhrase(@NonNull DetectedPhrase value) {
+ public @NonNull Builder setBackgroundAudioPower(int value) {
checkNotUsed();
- mBuilderFieldsSet |= 0x400;
- mDetectedPhrase = value;
+ mBuilderFieldsSet |= 0x800;
+ mBackgroundAudioPower = value;
return this;
}
/** Builds the instance. This builder should not be touched after calling this! */
public @NonNull HotwordDetectedResult build() {
checkNotUsed();
- mBuilderFieldsSet |= 0x800; // Mark builder used
+ mBuilderFieldsSet |= 0x1000; // Mark builder used
if ((mBuilderFieldsSet & 0x1) == 0) {
mConfidenceLevel = defaultConfidenceLevel();
@@ -1082,13 +1129,16 @@
mPersonalizedScore = defaultPersonalizedScore();
}
if ((mBuilderFieldsSet & 0x100) == 0) {
- mAudioStreams = defaultAudioStreams();
+ mHotwordPhraseId = defaultHotwordPhraseId();
}
if ((mBuilderFieldsSet & 0x200) == 0) {
- mExtras = defaultExtras();
+ mAudioStreams = defaultAudioStreams();
}
if ((mBuilderFieldsSet & 0x400) == 0) {
- mDetectedPhrase = new DetectedPhrase.Builder().build();
+ mExtras = defaultExtras();
+ }
+ if ((mBuilderFieldsSet & 0x800) == 0) {
+ mBackgroundAudioPower = defaultBackgroundAudioPower();
}
HotwordDetectedResult o = new HotwordDetectedResult(
mConfidenceLevel,
@@ -1099,14 +1149,15 @@
mHotwordDetectionPersonalized,
mScore,
mPersonalizedScore,
+ mHotwordPhraseId,
mAudioStreams,
mExtras,
- mDetectedPhrase);
+ mBackgroundAudioPower);
return o;
}
private void checkNotUsed() {
- if ((mBuilderFieldsSet & 0x800) != 0) {
+ if ((mBuilderFieldsSet & 0x1000) != 0) {
throw new IllegalStateException(
"This Builder should not be reused. Use a new Builder instance instead");
}
@@ -1114,10 +1165,10 @@
}
@DataClass.Generated(
- time = 1676870324215L,
+ time = 1679081102676L,
codegenVersion = "1.0.23",
sourceFile = "frameworks/base/core/java/android/service/voice/HotwordDetectedResult.java",
- inputSignatures = "public static final int CONFIDENCE_LEVEL_NONE\npublic static final int CONFIDENCE_LEVEL_LOW\npublic static final int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final int CONFIDENCE_LEVEL_HIGH\npublic static final int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final int HOTWORD_OFFSET_UNSET\npublic static final int AUDIO_CHANNEL_UNSET\nprivate static final int LIMIT_HOTWORD_OFFSET_MAX_VALUE\nprivate static final int LIMIT_AUDIO_CHANNEL_MAX_VALUE\nprivate static final java.lang.String EXTRA_PROXIMITY\npublic static final int PROXIMITY_UNKNOWN\npublic static final int PROXIMITY_NEAR\npublic static final int PROXIMITY_FAR\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate int mHotwordOffsetMillis\nprivate int mHotwordDurationMillis\nprivate int mAudioChannel\nprivate boolean mHotwordDetectionPersonalized\nprivate final int mScore\nprivate final int mPersonalizedScore\nprivate final @android.annotation.NonNull java.util.List<android.service.voice.HotwordAudioStream> mAudioStreams\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static int sMaxBundleSize\nprivate @android.annotation.NonNull android.service.voice.DetectedPhrase mDetectedPhrase\nprivate static int defaultConfidenceLevel()\nprivate static int defaultScore()\nprivate static int defaultPersonalizedScore()\npublic static int getMaxScore()\npublic @java.lang.Deprecated int getHotwordPhraseId()\npublic static @java.lang.Deprecated int getMaxHotwordPhraseId()\nprivate static java.util.List<android.service.voice.HotwordAudioStream> defaultAudioStreams()\nprivate static android.os.PersistableBundle defaultExtras()\npublic static int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\npublic static int getParcelableSize(android.os.Parcelable)\npublic static int getUsageSize(android.service.voice.HotwordDetectedResult)\nstatic int bitCount(long)\nprivate void onConstructed()\npublic @android.annotation.NonNull java.util.List<android.service.voice.HotwordAudioStream> getAudioStreams()\npublic void setProximity(double)\npublic @android.service.voice.HotwordDetectedResult.ProximityValue int getProximity()\nprivate @android.service.voice.HotwordDetectedResult.ProximityValue int convertToProximityLevel(double)\npublic android.service.voice.HotwordDetectedResult.Builder buildUpon()\nclass HotwordDetectedResult extends java.lang.Object implements [android.os.Parcelable]\npublic @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setAudioStreams(java.util.List<android.service.voice.HotwordAudioStream>)\npublic @java.lang.Deprecated @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setHotwordPhraseId(int)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)\npublic @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setAudioStreams(java.util.List<android.service.voice.HotwordAudioStream>)\npublic @java.lang.Deprecated @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setHotwordPhraseId(int)\nclass BaseBuilder extends java.lang.Object implements []")
+ inputSignatures = "public static final int CONFIDENCE_LEVEL_NONE\npublic static final int CONFIDENCE_LEVEL_LOW\npublic static final int CONFIDENCE_LEVEL_LOW_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM\npublic static final int CONFIDENCE_LEVEL_MEDIUM_HIGH\npublic static final int CONFIDENCE_LEVEL_HIGH\npublic static final int CONFIDENCE_LEVEL_VERY_HIGH\npublic static final int HOTWORD_OFFSET_UNSET\npublic static final int AUDIO_CHANNEL_UNSET\npublic static final int BACKGROUND_AUDIO_POWER_UNSET\nprivate static final int LIMIT_HOTWORD_OFFSET_MAX_VALUE\nprivate static final int LIMIT_AUDIO_CHANNEL_MAX_VALUE\nprivate static final java.lang.String EXTRA_PROXIMITY\npublic static final int PROXIMITY_UNKNOWN\npublic static final int PROXIMITY_NEAR\npublic static final int PROXIMITY_FAR\nprivate final @android.service.voice.HotwordDetectedResult.HotwordConfidenceLevelValue int mConfidenceLevel\nprivate @android.annotation.Nullable android.media.MediaSyncEvent mMediaSyncEvent\nprivate int mHotwordOffsetMillis\nprivate int mHotwordDurationMillis\nprivate int mAudioChannel\nprivate boolean mHotwordDetectionPersonalized\nprivate final int mScore\nprivate final int mPersonalizedScore\nprivate final int mHotwordPhraseId\nprivate final @android.annotation.NonNull java.util.List<android.service.voice.HotwordAudioStream> mAudioStreams\nprivate final @android.annotation.NonNull android.os.PersistableBundle mExtras\nprivate static int sMaxBundleSize\nprivate final int mBackgroundAudioPower\nprivate static int defaultConfidenceLevel()\nprivate static int defaultScore()\nprivate static int defaultPersonalizedScore()\npublic static int getMaxScore()\nprivate static int defaultHotwordPhraseId()\npublic static int getMaxHotwordPhraseId()\nprivate static java.util.List<android.service.voice.HotwordAudioStream> defaultAudioStreams()\nprivate static android.os.PersistableBundle defaultExtras()\npublic static int getMaxBundleSize()\npublic @android.annotation.Nullable android.media.MediaSyncEvent getMediaSyncEvent()\nprivate static int defaultBackgroundAudioPower()\npublic static int getMaxBackgroundAudioPower()\npublic static int getParcelableSize(android.os.Parcelable)\npublic static int getUsageSize(android.service.voice.HotwordDetectedResult)\nprivate static int bitCount(long)\nprivate void onConstructed()\npublic @android.annotation.NonNull java.util.List<android.service.voice.HotwordAudioStream> getAudioStreams()\npublic void setProximity(double)\npublic @android.service.voice.HotwordDetectedResult.ProximityValue int getProximity()\nprivate @android.service.voice.HotwordDetectedResult.ProximityValue int convertToProximityLevel(double)\npublic android.service.voice.HotwordDetectedResult.Builder buildUpon()\nclass HotwordDetectedResult extends java.lang.Object implements [android.os.Parcelable]\npublic @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setAudioStreams(java.util.List<android.service.voice.HotwordAudioStream>)\nclass BaseBuilder extends java.lang.Object implements []\n@com.android.internal.util.DataClass(genConstructor=false, genBuilder=true, genEqualsHashCode=true, genHiddenConstDefs=true, genParcelable=true, genToString=true)\npublic @android.annotation.NonNull android.service.voice.HotwordDetectedResult.Builder setAudioStreams(java.util.List<android.service.voice.HotwordAudioStream>)\nclass BaseBuilder extends java.lang.Object implements []")
@Deprecated
private void __metadata() {}
diff --git a/core/java/android/service/voice/HotwordDetectionServiceFailure.java b/core/java/android/service/voice/HotwordDetectionServiceFailure.java
index 3d9f66b..5cf245d 100644
--- a/core/java/android/service/voice/HotwordDetectionServiceFailure.java
+++ b/core/java/android/service/voice/HotwordDetectionServiceFailure.java
@@ -22,6 +22,7 @@
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -36,7 +37,7 @@
* @hide
*/
@SystemApi
-public final class HotwordDetectionServiceFailure extends DetectorFailure {
+public final class HotwordDetectionServiceFailure implements Parcelable {
/**
* An error code which means an unknown error occurs.
@@ -94,12 +95,19 @@
@Retention(RetentionPolicy.SOURCE)
public @interface HotwordDetectionServiceErrorCode {}
+ private int mErrorCode = ERROR_CODE_UNKNOWN;
+ private String mErrorMessage = "Unknown";
+
/**
* @hide
*/
@TestApi
public HotwordDetectionServiceFailure(int errorCode, @NonNull String errorMessage) {
- super(ERROR_SOURCE_TYPE_HOTWORD_DETECTION, errorCode, errorMessage);
+ if (TextUtils.isEmpty(errorMessage)) {
+ throw new IllegalArgumentException("errorMessage is empty or null.");
+ }
+ mErrorCode = errorCode;
+ mErrorMessage = errorMessage;
}
/**
@@ -107,22 +115,33 @@
*/
@HotwordDetectionServiceErrorCode
public int getErrorCode() {
- return super.getErrorCode();
+ return mErrorCode;
}
- @Override
+ /**
+ * Returns the error message.
+ */
+ @NonNull
+ public String getErrorMessage() {
+ return mErrorMessage;
+ }
+
+ /**
+ * Returns the suggested action.
+ */
+ @FailureSuggestedAction.FailureSuggestedActionDef
public int getSuggestedAction() {
- switch (getErrorCode()) {
+ switch (mErrorCode) {
case ERROR_CODE_BIND_FAILURE:
case ERROR_CODE_BINDING_DIED:
case ERROR_CODE_REMOTE_EXCEPTION:
- return SUGGESTED_ACTION_RECREATE_DETECTOR;
+ return FailureSuggestedAction.RECREATE_DETECTOR;
case ERROR_CODE_DETECT_TIMEOUT:
case ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION:
case ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE:
- return SUGGESTED_ACTION_RESTART_RECOGNITION;
+ return FailureSuggestedAction.RESTART_RECOGNITION;
default:
- return SUGGESTED_ACTION_NONE;
+ return FailureSuggestedAction.NONE;
}
}
@@ -133,7 +152,14 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
+ dest.writeInt(mErrorCode);
+ dest.writeString8(mErrorMessage);
+ }
+
+ @Override
+ public String toString() {
+ return "HotwordDetectionServiceFailure { errorCode = " + mErrorCode + ", errorMessage = "
+ + mErrorMessage + " }";
}
public static final @NonNull Parcelable.Creator<HotwordDetectionServiceFailure> CREATOR =
@@ -145,8 +171,7 @@
@Override
public HotwordDetectionServiceFailure createFromParcel(@NonNull Parcel in) {
- DetectorFailure detectorFailure = DetectorFailure.CREATOR.createFromParcel(in);
- return (HotwordDetectionServiceFailure) detectorFailure;
+ return new HotwordDetectionServiceFailure(in.readInt(), in.readString8());
}
};
}
diff --git a/core/java/android/service/voice/HotwordDetector.java b/core/java/android/service/voice/HotwordDetector.java
index 93fcec1..32a93ee 100644
--- a/core/java/android/service/voice/HotwordDetector.java
+++ b/core/java/android/service/voice/HotwordDetector.java
@@ -23,14 +23,10 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
-import android.compat.annotation.ChangeId;
-import android.compat.annotation.EnabledSince;
import android.media.AudioFormat;
-import android.os.Build;
import android.os.ParcelFileDescriptor;
import android.os.PersistableBundle;
import android.os.SharedMemory;
-import android.util.AndroidException;
import java.io.PrintWriter;
@@ -44,23 +40,6 @@
public interface HotwordDetector {
/**
- * Prior to API level 33, API calls of {@link android.service.voice.HotwordDetector} could
- * return both {@link java.lang.IllegalStateException} or
- * {@link java.lang.UnsupportedOperationException} depending on the detector's underlying state.
- * This lead to confusing behavior as the underlying state of the detector can be modified
- * without the knowledge of the caller via system service layer updates.
- *
- * This change ID, when enabled, changes the API calls to only throw checked exception
- * {@link android.service.voice.HotwordDetector.IllegalDetectorStateException} when checking
- * against state information modified by both the caller and the system services.
- *
- * @hide
- */
- @ChangeId
- @EnabledSince(targetSdkVersion = Build.VERSION_CODES.TIRAMISU)
- long HOTWORD_DETECTOR_THROW_CHECKED_EXCEPTION = 226355112L;
-
- /**
* Indicates that it is a non-trusted hotword detector.
*
* @hide
@@ -109,26 +88,16 @@
* Calling this again while recognition is active does nothing.
*
* @return {@code true} if the request to start recognition succeeded
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above and attempts to start a recognition when the detector is not able based on
- * the state. This can be thrown even if the state has been checked before calling this
- * method because the caller receives updates via an asynchronous callback, and the
- * state of the detector can change concurrently to the caller calling this method.
*/
@RequiresPermission(allOf = {RECORD_AUDIO, CAPTURE_AUDIO_HOTWORD})
- boolean startRecognition() throws IllegalDetectorStateException;
+ boolean startRecognition();
/**
* Stops sandboxed detection recognition.
*
* @return {@code true} if the request to stop recognition succeeded
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above and attempts to stop a recognition when the detector is not able based on
- * the state. This can be thrown even if the state has been checked before calling this
- * method because the caller receives updates via an asynchronous callback, and the
- * state of the detector can change concurrently to the caller calling this method.
*/
- boolean stopRecognition() throws IllegalDetectorStateException;
+ boolean stopRecognition();
/**
* Starts hotword recognition on audio coming from an external connected microphone.
@@ -142,16 +111,11 @@
* PersistableBundle does not allow any remotable objects or other contents that can be
* used to communicate with other processes.
* @return {@code true} if the request to start recognition succeeded
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above and attempts to start a recognition when the detector is not able based on
- * the state. This can be thrown even if the state has been checked before calling this
- * method because the caller receives updates via an asynchronous callback, and the
- * state of the detector can change concurrently to the caller calling this method.
*/
boolean startRecognition(
@NonNull ParcelFileDescriptor audioStream,
@NonNull AudioFormat audioFormat,
- @Nullable PersistableBundle options) throws IllegalDetectorStateException;
+ @Nullable PersistableBundle options);
/**
* Set configuration and pass read-only data to sandboxed detection service.
@@ -161,17 +125,10 @@
* communicate with other processes.
* @param sharedMemory The unrestricted data blob to provide to sandboxed detection services.
* Use this to provide model data or other such data to the trusted process.
- * @throws IllegalDetectorStateException Thrown when a caller has a target SDK of API level 33
- * or above and the detector is not able to perform the operation based on the
- * underlying state. This can be thrown even if the state has been checked before
- * calling this method because the caller receives updates via an asynchronous callback,
- * and the state of the detector can change concurrently to the caller calling this
- * method.
* @throws IllegalStateException if this HotwordDetector wasn't specified to use a
* sandboxed detection service when it was created.
*/
- void updateState(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory)
- throws IllegalDetectorStateException;
+ void updateState(@Nullable PersistableBundle options, @Nullable SharedMemory sharedMemory);
/**
* Invalidates this detector so that any future calls to this result
@@ -232,24 +189,34 @@
/**
* Called when the detection fails due to an error.
*
- * @deprecated On Android 14 and above, implement {@link #onFailure(DetectorFailure)}
- * instead.
+ * @deprecated On {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE} and above,
+ * implement {@link HotwordDetector.Callback#onFailure(HotwordDetectionServiceFailure)},
+ * {@link AlwaysOnHotwordDetector.Callback#onFailure(SoundTriggerFailure)},
+ * {@link HotwordDetector.Callback#onUnknownFailure(String)} instead.
*/
@Deprecated
void onError();
/**
- * Called when the detection fails due to an error, the subclasses of
- * {@link DetectorFailure} will be reported to the detector.
+ * Called when the detection fails due to an error occurs in the
+ * {@link HotwordDetectionService}, {@link HotwordDetectionServiceFailure} will be reported
+ * to the detector.
*
- * @see android.service.voice.HotwordDetectionServiceFailure
- * @see android.service.voice.SoundTriggerFailure
- * @see android.service.voice.UnknownFailure
- * @see android.service.voice.VisualQueryDetectionServiceFailure
- *
- * @param detectorFailure It provides the error code, error message and suggested action.
+ * @param hotwordDetectionServiceFailure It provides the error code, error message and
+ * suggested action.
*/
- default void onFailure(@NonNull DetectorFailure detectorFailure) {
+ default void onFailure(
+ @NonNull HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
+ onError();
+ }
+
+ /**
+ * Called when the detection fails due to an unknown error occurs, an error message
+ * will be reported to the detector.
+ *
+ * @param errorMessage It provides the error message.
+ */
+ default void onUnknownFailure(@NonNull String errorMessage) {
onError();
}
@@ -298,14 +265,4 @@
*/
void onHotwordDetectionServiceRestarted();
}
-
- /**
- * {@link HotwordDetector} specific exception thrown when the underlying state of the detector
- * is invalid for the given action.
- */
- class IllegalDetectorStateException extends AndroidException {
- IllegalDetectorStateException(String message) {
- super(message);
- }
- }
}
diff --git a/core/java/android/service/voice/IMicrophoneHotwordDetectionVoiceInteractionCallback.aidl b/core/java/android/service/voice/IMicrophoneHotwordDetectionVoiceInteractionCallback.aidl
index f800c1e..fab830a 100644
--- a/core/java/android/service/voice/IMicrophoneHotwordDetectionVoiceInteractionCallback.aidl
+++ b/core/java/android/service/voice/IMicrophoneHotwordDetectionVoiceInteractionCallback.aidl
@@ -17,8 +17,8 @@
package android.service.voice;
import android.media.AudioFormat;
-import android.service.voice.DetectorFailure;
import android.service.voice.HotwordDetectedResult;
+import android.service.voice.HotwordDetectionServiceFailure;
import android.service.voice.HotwordRejectedResult;
/**
@@ -39,7 +39,8 @@
/**
* Called when the detection fails due to an error.
*/
- void onError(in DetectorFailure detectorFailure);
+ void onHotwordDetectionServiceFailure(
+ in HotwordDetectionServiceFailure hotwordDetectionServiceFailure);
/**
* Called when the detected result was not detected.
diff --git a/core/java/android/service/voice/IVisualQueryDetectionVoiceInteractionCallback.aidl b/core/java/android/service/voice/IVisualQueryDetectionVoiceInteractionCallback.aidl
index 1a935c0..cedb7ff 100644
--- a/core/java/android/service/voice/IVisualQueryDetectionVoiceInteractionCallback.aidl
+++ b/core/java/android/service/voice/IVisualQueryDetectionVoiceInteractionCallback.aidl
@@ -16,7 +16,7 @@
package android.service.voice;
-import android.service.voice.DetectorFailure;
+import android.service.voice.VisualQueryDetectionServiceFailure;
/**
* Callback for returning the detected result from the VisualQueryDetectionService.
@@ -43,5 +43,6 @@
/**
* Called when the detection fails due to an error.
*/
- void onDetectionFailure(in DetectorFailure detectorFailure);
+ void onVisualQueryDetectionServiceFailure(
+ in VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure);
}
diff --git a/core/java/android/service/voice/SoftwareHotwordDetector.java b/core/java/android/service/voice/SoftwareHotwordDetector.java
index 767fe37..eac7aee 100644
--- a/core/java/android/service/voice/SoftwareHotwordDetector.java
+++ b/core/java/android/service/voice/SoftwareHotwordDetector.java
@@ -30,6 +30,7 @@
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SharedMemory;
+import android.text.TextUtils;
import android.util.Log;
import android.util.Slog;
@@ -86,7 +87,7 @@
@RequiresPermission(RECORD_AUDIO)
@Override
- public boolean startRecognition() throws IllegalDetectorStateException {
+ public boolean startRecognition() {
if (DEBUG) {
Slog.i(TAG, "#startRecognition");
}
@@ -109,7 +110,7 @@
/** TODO: stopRecognition */
@RequiresPermission(RECORD_AUDIO)
@Override
- public boolean stopRecognition() throws IllegalDetectorStateException {
+ public boolean stopRecognition() {
if (DEBUG) {
Slog.i(TAG, "#stopRecognition");
}
@@ -176,11 +177,16 @@
/** Called when the detection fails due to an error. */
@Override
- public void onError(DetectorFailure detectorFailure) {
- Slog.v(TAG, "BinderCallback#onError detectorFailure: " + detectorFailure);
+ public void onHotwordDetectionServiceFailure(
+ HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
+ Slog.v(TAG, "BinderCallback#onHotwordDetectionServiceFailure:"
+ + hotwordDetectionServiceFailure);
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
- mCallback.onFailure(detectorFailure != null ? detectorFailure
- : new UnknownFailure("Error data is null"));
+ if (hotwordDetectionServiceFailure != null) {
+ mCallback.onFailure(hotwordDetectionServiceFailure);
+ } else {
+ mCallback.onUnknownFailure("Error data is null");
+ }
}));
}
@@ -236,11 +242,34 @@
}
@Override
- public void onDetectionFailure(DetectorFailure detectorFailure) throws RemoteException {
- Slog.v(TAG, "onDetectionFailure detectorFailure: " + detectorFailure);
+ public void onHotwordDetectionServiceFailure(
+ HotwordDetectionServiceFailure hotwordDetectionServiceFailure)
+ throws RemoteException {
+ Slog.v(TAG, "onHotwordDetectionServiceFailure: " + hotwordDetectionServiceFailure);
Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
- mCallback.onFailure(detectorFailure != null ? detectorFailure
- : new UnknownFailure("Error data is null"));
+ if (hotwordDetectionServiceFailure != null) {
+ mCallback.onFailure(hotwordDetectionServiceFailure);
+ } else {
+ mCallback.onUnknownFailure("Error data is null");
+ }
+ }));
+ }
+
+ @Override
+ public void onVisualQueryDetectionServiceFailure(
+ VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure)
+ throws RemoteException {
+ // It should never be called here.
+ Slog.w(TAG, "onVisualQueryDetectionServiceFailure: "
+ + visualQueryDetectionServiceFailure);
+ }
+
+ @Override
+ public void onUnknownFailure(String errorMessage) throws RemoteException {
+ Slog.v(TAG, "onUnknownFailure: " + errorMessage);
+ Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
+ mCallback.onUnknownFailure(
+ !TextUtils.isEmpty(errorMessage) ? errorMessage : "Error data is null");
}));
}
diff --git a/core/java/android/service/voice/SoundTriggerFailure.java b/core/java/android/service/voice/SoundTriggerFailure.java
index a431fbc..5560800 100644
--- a/core/java/android/service/voice/SoundTriggerFailure.java
+++ b/core/java/android/service/voice/SoundTriggerFailure.java
@@ -22,6 +22,7 @@
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -35,7 +36,7 @@
* @hide
*/
@SystemApi
-public final class SoundTriggerFailure extends DetectorFailure {
+public final class SoundTriggerFailure implements Parcelable {
/**
* An error code which means an unknown error occurs.
@@ -72,12 +73,19 @@
@Retention(RetentionPolicy.SOURCE)
public @interface SoundTriggerErrorCode {}
+ private int mErrorCode = ERROR_CODE_UNKNOWN;
+ private String mErrorMessage = "Unknown";
+
/**
* @hide
*/
@TestApi
public SoundTriggerFailure(int errorCode, @NonNull String errorMessage) {
- super(ERROR_SOURCE_TYPE_SOUND_TRIGGER, errorCode, errorMessage);
+ if (TextUtils.isEmpty(errorMessage)) {
+ throw new IllegalArgumentException("errorMessage is empty or null.");
+ }
+ mErrorCode = errorCode;
+ mErrorMessage = errorMessage;
}
/**
@@ -85,19 +93,30 @@
*/
@SoundTriggerErrorCode
public int getErrorCode() {
- return super.getErrorCode();
+ return mErrorCode;
}
- @Override
+ /**
+ * Returns the error message.
+ */
+ @NonNull
+ public String getErrorMessage() {
+ return mErrorMessage;
+ }
+
+ /**
+ * Returns the suggested action.
+ */
+ @FailureSuggestedAction.FailureSuggestedActionDef
public int getSuggestedAction() {
- switch (getErrorCode()) {
+ switch (mErrorCode) {
case ERROR_CODE_MODULE_DIED:
case ERROR_CODE_UNEXPECTED_PREEMPTION:
- return SUGGESTED_ACTION_RECREATE_DETECTOR;
+ return FailureSuggestedAction.RECREATE_DETECTOR;
case ERROR_CODE_RECOGNITION_RESUME_FAILED:
- return SUGGESTED_ACTION_RESTART_RECOGNITION;
+ return FailureSuggestedAction.RESTART_RECOGNITION;
default:
- return SUGGESTED_ACTION_NONE;
+ return FailureSuggestedAction.NONE;
}
}
@@ -108,7 +127,14 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
+ dest.writeInt(mErrorCode);
+ dest.writeString8(mErrorMessage);
+ }
+
+ @Override
+ public String toString() {
+ return "SoundTriggerFailure { errorCode = " + mErrorCode + ", errorMessage = "
+ + mErrorMessage + " }";
}
public static final @NonNull Parcelable.Creator<SoundTriggerFailure> CREATOR =
@@ -120,7 +146,7 @@
@Override
public SoundTriggerFailure createFromParcel(@NonNull Parcel in) {
- return (SoundTriggerFailure) DetectorFailure.CREATOR.createFromParcel(in);
+ return new SoundTriggerFailure(in.readInt(), in.readString8());
}
};
}
diff --git a/core/java/android/service/voice/UnknownFailure.aidl b/core/java/android/service/voice/UnknownFailure.aidl
deleted file mode 100644
index cf43cc2..0000000
--- a/core/java/android/service/voice/UnknownFailure.aidl
+++ /dev/null
@@ -1,19 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.voice;
-
-parcelable UnknownFailure;
diff --git a/core/java/android/service/voice/UnknownFailure.java b/core/java/android/service/voice/UnknownFailure.java
deleted file mode 100644
index 2ef2d5f..0000000
--- a/core/java/android/service/voice/UnknownFailure.java
+++ /dev/null
@@ -1,77 +0,0 @@
-/*
- * Copyright (C) 2023 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package android.service.voice;
-
-import android.annotation.NonNull;
-import android.annotation.SystemApi;
-import android.annotation.TestApi;
-import android.os.Parcel;
-import android.os.Parcelable;
-
-/**
- * A class which indicates an unknown error occurs during the detector doing detection. The class
- * is mainly used by the assistant application, the application still can get the suggested action
- * for the unknown error.
- *
- * @hide
- */
-@SystemApi
-public final class UnknownFailure extends DetectorFailure {
-
- /**
- * An error code which means an unknown error occurs.
- *
- * @hide
- */
- public static final int ERROR_CODE_UNKNOWN = 0;
-
- /**
- * @hide
- */
- @TestApi
- public UnknownFailure(@NonNull String errorMessage) {
- super(ERROR_SOURCE_TYPE_UNKNOWN, ERROR_CODE_UNKNOWN, errorMessage);
- }
-
- @Override
- public int getSuggestedAction() {
- return SUGGESTED_ACTION_UNKNOWN;
- }
-
- @Override
- public int describeContents() {
- return 0;
- }
-
- @Override
- public void writeToParcel(@NonNull Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
- }
-
- public static final @NonNull Parcelable.Creator<UnknownFailure> CREATOR =
- new Parcelable.Creator<UnknownFailure>() {
- @Override
- public UnknownFailure[] newArray(int size) {
- return new UnknownFailure[size];
- }
-
- @Override
- public UnknownFailure createFromParcel(@NonNull Parcel in) {
- return (UnknownFailure) DetectorFailure.CREATOR.createFromParcel(in);
- }
- };
-}
diff --git a/core/java/android/service/voice/VisualQueryDetectionServiceFailure.java b/core/java/android/service/voice/VisualQueryDetectionServiceFailure.java
index aa02299..4657e37 100644
--- a/core/java/android/service/voice/VisualQueryDetectionServiceFailure.java
+++ b/core/java/android/service/voice/VisualQueryDetectionServiceFailure.java
@@ -22,6 +22,7 @@
import android.annotation.TestApi;
import android.os.Parcel;
import android.os.Parcelable;
+import android.text.TextUtils;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@@ -33,7 +34,7 @@
* @hide
*/
@SystemApi
-public final class VisualQueryDetectionServiceFailure extends DetectorFailure {
+public final class VisualQueryDetectionServiceFailure implements Parcelable {
/**
* An error code which means an unknown error occurs.
@@ -79,12 +80,19 @@
@Retention(RetentionPolicy.SOURCE)
public @interface VisualQueryDetectionServiceErrorCode {}
+ private int mErrorCode = ERROR_CODE_UNKNOWN;
+ private String mErrorMessage = "Unknown";
+
/**
* @hide
*/
@TestApi
public VisualQueryDetectionServiceFailure(int errorCode, @NonNull String errorMessage) {
- super(ERROR_SOURCE_TYPE_VISUAL_QUERY_DETECTION, errorCode, errorMessage);
+ if (TextUtils.isEmpty(errorMessage)) {
+ throw new IllegalArgumentException("errorMessage is empty or null.");
+ }
+ mErrorCode = errorCode;
+ mErrorMessage = errorMessage;
}
/**
@@ -92,21 +100,32 @@
*/
@VisualQueryDetectionServiceErrorCode
public int getErrorCode() {
- return super.getErrorCode();
+ return mErrorCode;
}
- @Override
+ /**
+ * Returns the error message.
+ */
+ @NonNull
+ public String getErrorMessage() {
+ return mErrorMessage;
+ }
+
+ /**
+ * Returns the suggested action.
+ */
+ @FailureSuggestedAction.FailureSuggestedActionDef
public int getSuggestedAction() {
- switch (getErrorCode()) {
+ switch (mErrorCode) {
case ERROR_CODE_BIND_FAILURE:
case ERROR_CODE_BINDING_DIED:
case ERROR_CODE_ILLEGAL_ATTENTION_STATE:
case ERROR_CODE_REMOTE_EXCEPTION:
- return SUGGESTED_ACTION_RECREATE_DETECTOR;
+ return FailureSuggestedAction.RECREATE_DETECTOR;
case ERROR_CODE_ILLEGAL_STREAMING_STATE:
- return SUGGESTED_ACTION_RESTART_RECOGNITION;
+ return FailureSuggestedAction.RESTART_RECOGNITION;
default:
- return SUGGESTED_ACTION_NONE;
+ return FailureSuggestedAction.NONE;
}
}
@@ -117,7 +136,14 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
- super.writeToParcel(dest, flags);
+ dest.writeInt(mErrorCode);
+ dest.writeString8(mErrorMessage);
+ }
+
+ @Override
+ public String toString() {
+ return "VisualQueryDetectionServiceFailure { errorCode = " + mErrorCode
+ + ", errorMessage = " + mErrorMessage + " }";
}
public static final @NonNull Parcelable.Creator<VisualQueryDetectionServiceFailure> CREATOR =
@@ -129,8 +155,7 @@
@Override
public VisualQueryDetectionServiceFailure createFromParcel(@NonNull Parcel in) {
- DetectorFailure detectorFailure = DetectorFailure.CREATOR.createFromParcel(in);
- return (VisualQueryDetectionServiceFailure) detectorFailure;
+ return new VisualQueryDetectionServiceFailure(in.readInt(), in.readString8());
}
};
}
diff --git a/core/java/android/service/voice/VisualQueryDetector.java b/core/java/android/service/voice/VisualQueryDetector.java
index 7dc0687..b4f5ff1 100644
--- a/core/java/android/service/voice/VisualQueryDetector.java
+++ b/core/java/android/service/voice/VisualQueryDetector.java
@@ -32,6 +32,7 @@
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SharedMemory;
+import android.text.TextUtils;
import android.util.Slog;
import com.android.internal.app.IHotwordRecognitionStatusCallback;
@@ -84,8 +85,7 @@
* @see HotwordDetector#updateState(PersistableBundle, SharedMemory)
*/
public void updateState(@Nullable PersistableBundle options,
- @Nullable SharedMemory sharedMemory) throws
- HotwordDetector.IllegalDetectorStateException {
+ @Nullable SharedMemory sharedMemory) {
mInitializationDelegate.updateState(options, sharedMemory);
}
@@ -104,7 +104,7 @@
* @see HotwordDetector#startRecognition()
*/
@RequiresPermission(allOf = {CAMERA, RECORD_AUDIO})
- public boolean startRecognition() throws HotwordDetector.IllegalDetectorStateException {
+ public boolean startRecognition() {
if (DEBUG) {
Slog.i(TAG, "#startRecognition");
}
@@ -128,7 +128,7 @@
* @see HotwordDetector#stopRecognition()
*/
@RequiresPermission(allOf = {CAMERA, RECORD_AUDIO})
- public boolean stopRecognition() throws HotwordDetector.IllegalDetectorStateException {
+ public boolean stopRecognition() {
if (DEBUG) {
Slog.i(TAG, "#stopRecognition");
}
@@ -217,9 +217,23 @@
void onVisualQueryDetectionServiceRestarted();
/**
- * Called when the detection fails due to an error.
+ * Called when the detection fails due to an error occurs in the
+ * {@link VisualQueryDetectionService}, {@link VisualQueryDetectionServiceFailure} will be
+ * reported to the detector.
+ *
+ * @param visualQueryDetectionServiceFailure It provides the error code, error message and
+ * suggested action.
*/
- void onFailure(@NonNull DetectorFailure detectorFailure);
+ void onFailure(
+ @NonNull VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure);
+
+ /**
+ * Called when the detection fails due to an unknown error occurs, an error message
+ * will be reported to the detector.
+ *
+ * @param errorMessage It provides the error message.
+ */
+ void onUnknownFailure(@NonNull String errorMessage);
}
private class VisualQueryDetectorInitializationDelegate extends AbstractDetector {
@@ -236,13 +250,13 @@
}
@Override
- public boolean stopRecognition() throws IllegalDetectorStateException {
+ public boolean stopRecognition() {
throwIfDetectorIsNoLongerActive();
return true;
}
@Override
- public boolean startRecognition() throws IllegalDetectorStateException {
+ public boolean startRecognition() {
throwIfDetectorIsNoLongerActive();
return true;
}
@@ -251,7 +265,7 @@
public final boolean startRecognition(
@NonNull ParcelFileDescriptor audioStream,
@NonNull AudioFormat audioFormat,
- @Nullable PersistableBundle options) throws IllegalDetectorStateException {
+ @Nullable PersistableBundle options) {
//No-op, not supported by VisualQueryDetector as it should be trusted.
return false;
}
@@ -296,10 +310,17 @@
/** Called when the detection fails due to an error. */
@Override
- public void onDetectionFailure(DetectorFailure detectorFailure) {
- Slog.v(TAG, "BinderCallback#onDetectionFailure");
- Binder.withCleanCallingIdentity(() -> mExecutor.execute(
- () -> mCallback.onFailure(detectorFailure)));
+ public void onVisualQueryDetectionServiceFailure(
+ VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure) {
+ Slog.v(TAG, "BinderCallback#onVisualQueryDetectionServiceFailure: "
+ + visualQueryDetectionServiceFailure);
+ Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
+ if (visualQueryDetectionServiceFailure != null) {
+ mCallback.onFailure(visualQueryDetectionServiceFailure);
+ } else {
+ mCallback.onUnknownFailure("Error data is null");
+ }
+ }));
}
}
@@ -376,7 +397,35 @@
}
@Override
- public void onDetectionFailure(DetectorFailure detectorFailure) throws RemoteException {
+ public void onHotwordDetectionServiceFailure(
+ HotwordDetectionServiceFailure hotwordDetectionServiceFailure)
+ throws RemoteException {
+ // It should never be called here.
+ Slog.w(TAG, "onHotwordDetectionServiceFailure: " + hotwordDetectionServiceFailure);
+ }
+
+ @Override
+ public void onVisualQueryDetectionServiceFailure(
+ VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure)
+ throws RemoteException {
+ Slog.v(TAG, "onVisualQueryDetectionServiceFailure: "
+ + visualQueryDetectionServiceFailure);
+ Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
+ if (visualQueryDetectionServiceFailure != null) {
+ mCallback.onFailure(visualQueryDetectionServiceFailure);
+ } else {
+ mCallback.onUnknownFailure("Error data is null");
+ }
+ }));
+ }
+
+ @Override
+ public void onUnknownFailure(String errorMessage) throws RemoteException {
+ Slog.v(TAG, "onUnknownFailure: " + errorMessage);
+ Binder.withCleanCallingIdentity(() -> mExecutor.execute(() -> {
+ mCallback.onUnknownFailure(
+ !TextUtils.isEmpty(errorMessage) ? errorMessage : "Error data is null");
+ }));
}
}
}
diff --git a/core/java/android/service/wallpaper/WallpaperService.java b/core/java/android/service/wallpaper/WallpaperService.java
index 259012f..0b947fc 100644
--- a/core/java/android/service/wallpaper/WallpaperService.java
+++ b/core/java/android/service/wallpaper/WallpaperService.java
@@ -60,6 +60,7 @@
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
+import android.os.HandlerThread;
import android.os.IBinder;
import android.os.Looper;
import android.os.Message;
@@ -97,6 +98,7 @@
import android.window.ClientWindowFrames;
import android.window.ScreenCapture;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.os.HandlerCaller;
import com.android.internal.view.BaseIWindow;
@@ -104,9 +106,10 @@
import java.io.FileDescriptor;
import java.io.PrintWriter;
-import java.util.Arrays;
+import java.util.HashSet;
import java.util.List;
import java.util.Objects;
+import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.function.Supplier;
@@ -167,11 +170,12 @@
private static final int MSG_REPORT_SHOWN = 10150;
private static final int MSG_UPDATE_DIMMING = 10200;
private static final int MSG_WALLPAPER_FLAGS_CHANGED = 10210;
- private static final List<Float> PROHIBITED_STEPS = Arrays.asList(0f, Float.POSITIVE_INFINITY,
- Float.NEGATIVE_INFINITY);
+ /** limit calls to {@link Engine#onComputeColors} to at most once per second */
private static final int NOTIFY_COLORS_RATE_LIMIT_MS = 1000;
- private static final int PROCESS_LOCAL_COLORS_INTERVAL_MS = 1000;
+
+ /** limit calls to {@link Engine#processLocalColorsInternal} to at most once per 2 seconds */
+ private static final int PROCESS_LOCAL_COLORS_INTERVAL_MS = 2000;
private static final boolean ENABLE_WALLPAPER_DIMMING =
SystemProperties.getBoolean("persist.debug.enable_wallpaper_dimming", true);
@@ -180,6 +184,9 @@
private final ArrayMap<IBinder, IWallpaperEngineWrapper> mActiveEngines = new ArrayMap<>();
+ private Handler mBackgroundHandler;
+ private HandlerThread mBackgroundThread;
+
static final class WallpaperCommand {
String action;
int x;
@@ -198,14 +205,6 @@
*/
public class Engine {
IWallpaperEngineWrapper mIWallpaperEngine;
- final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
- final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
-
- // 2D matrix [x][y] to represent a page of a portion of a window
- EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
- Bitmap mLastScreenshot;
- int mLastWindowPage = -1;
- private boolean mResetWindowPages;
// Copies from mIWallpaperEngine.
HandlerCaller mCaller;
@@ -266,11 +265,34 @@
final Object mLock = new Object();
boolean mOffsetMessageEnqueued;
+
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.P, trackingBug = 115609023)
- float mPendingXOffset;
- float mPendingYOffset;
- float mPendingXOffsetStep;
- float mPendingYOffsetStep;
+ @GuardedBy("mLock")
+ private float mPendingXOffset;
+ @GuardedBy("mLock")
+ private float mPendingYOffset;
+ @GuardedBy("mLock")
+ private float mPendingXOffsetStep;
+ @GuardedBy("mLock")
+ private float mPendingYOffsetStep;
+
+ /**
+ * local color extraction related fields. When a user calls `addLocalColorAreas`
+ */
+ @GuardedBy("mLock")
+ private final ArraySet<RectF> mLocalColorAreas = new ArraySet<>(4);
+
+ @GuardedBy("mLock")
+ private final ArraySet<RectF> mLocalColorsToAdd = new ArraySet<>(4);
+ private long mLastProcessLocalColorsTimestamp;
+ private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
+ private int mPixelCopyCount = 0;
+ // 2D matrix [x][y] to represent a page of a portion of a window
+ @GuardedBy("mLock")
+ private EngineWindowPage[] mWindowPages = new EngineWindowPage[0];
+ private Bitmap mLastScreenshot;
+ private boolean mResetWindowPages;
+
boolean mPendingSync;
MotionEvent mPendingMove;
boolean mIsInAmbientMode;
@@ -279,12 +301,8 @@
private long mLastColorInvalidation;
private final Runnable mNotifyColorsChanged = this::notifyColorsChanged;
- // used to throttle processLocalColors
- private long mLastProcessLocalColorsTimestamp;
- private AtomicBoolean mProcessLocalColorsPending = new AtomicBoolean(false);
private final Supplier<Long> mClockFunction;
private final Handler mHandler;
-
private Display mDisplay;
private Context mDisplayContext;
private int mDisplayState;
@@ -854,7 +872,7 @@
+ "was not established.");
}
mResetWindowPages = true;
- processLocalColors(mPendingXOffset, mPendingXOffsetStep);
+ processLocalColors();
} catch (RemoteException e) {
Log.w(TAG, "Can't notify system because wallpaper connection was lost.", e);
}
@@ -1389,10 +1407,9 @@
mIsCreating = false;
mSurfaceCreated = true;
if (redrawNeeded) {
- resetWindowPages();
mSession.finishDrawing(mWindow, null /* postDrawTransaction */,
Integer.MAX_VALUE);
- processLocalColors(mPendingXOffset, mPendingXOffsetStep);
+ processLocalColors();
}
reposition();
reportEngineShown(shouldWaitForEngineShown());
@@ -1458,7 +1475,7 @@
com.android.internal.R.dimen.config_wallpaperDimAmount);
mWallpaperDimAmount = mDefaultDimAmount;
mPreviousWallpaperDimAmount = mWallpaperDimAmount;
- mDisplayState = mDisplay.getState();
+ mDisplayState = mDisplay.getCommittedState();
if (DEBUG) Log.v(TAG, "onCreate(): " + this);
Trace.beginSection("WPMS.Engine.onCreate");
@@ -1536,7 +1553,7 @@
if (!mDestroyed) {
mVisible = visible;
reportVisibility(false);
- if (mReportedVisible) processLocalColors(mPendingXOffset, mPendingXOffsetStep);
+ if (mReportedVisible) processLocalColors();
} else {
AnimationHandler.requestAnimatorsEnabled(visible, this);
}
@@ -1548,7 +1565,8 @@
return;
}
if (!mDestroyed) {
- mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN : mDisplay.getState();
+ mDisplayState = mDisplay == null ? Display.STATE_UNKNOWN :
+ mDisplay.getCommittedState();
boolean visible = mVisible && mDisplayState != Display.STATE_OFF;
if (DEBUG) {
Log.v(
@@ -1639,14 +1657,14 @@
}
// setup local color extraction data
- processLocalColors(xOffset, xOffsetStep);
+ processLocalColors();
}
/**
* Thread-safe util to call {@link #processLocalColorsInternal} with a minimum interval of
* {@link #PROCESS_LOCAL_COLORS_INTERVAL_MS} between two calls.
*/
- private void processLocalColors(float xOffset, float xOffsetStep) {
+ private void processLocalColors() {
if (mProcessLocalColorsPending.compareAndSet(false, true)) {
final long now = mClockFunction.get();
final long timeSinceLastColorProcess = now - mLastProcessLocalColorsTimestamp;
@@ -1656,80 +1674,98 @@
mHandler.postDelayed(() -> {
mLastProcessLocalColorsTimestamp = now + timeToWait;
mProcessLocalColorsPending.set(false);
- processLocalColorsInternal(xOffset, xOffsetStep);
+ processLocalColorsInternal();
}, timeToWait);
}
}
- private void processLocalColorsInternal(float xOffset, float xOffsetStep) {
- // implemented by the wallpaper
+ /**
+ * Default implementation of the local color extraction.
+ * This will take a screenshot of the whole wallpaper on the main thread.
+ * Then, in a background thread, for each launcher page, for each area that needs color
+ * extraction in this page, creates a sub-bitmap and call {@link WallpaperColors#fromBitmap}
+ * to extract the colors. Every time a launcher page has been processed, call
+ * {@link #notifyLocalColorsChanged} with the color and areas of this page.
+ */
+ private void processLocalColorsInternal() {
if (supportsLocalColorExtraction()) return;
- if (DEBUG) {
- Log.d(TAG, "processLocalColors " + xOffset + " of step "
- + xOffsetStep);
- }
- //below is the default implementation
- if (xOffset % xOffsetStep > MIN_PAGE_ALLOWED_MARGIN
- || !mSurfaceHolder.getSurface().isValid()) return;
- int xCurrentPage;
+ float xOffset;
+ float xOffsetStep;
+ float wallpaperDimAmount;
+ int xPage;
int xPages;
- if (!validStep(xOffsetStep)) {
- if (DEBUG) {
- Log.w(TAG, "invalid offset step " + xOffsetStep);
- }
- xOffset = 0;
- xOffsetStep = 1;
- xCurrentPage = 0;
- xPages = 1;
- } else {
- xPages = Math.round(1 / xOffsetStep) + 1;
- xOffsetStep = (float) 1 / (float) xPages;
- float shrink = (float) (xPages - 1) / (float) xPages;
- xOffset *= shrink;
- xCurrentPage = Math.round(xOffset / xOffsetStep);
- }
- if (DEBUG) {
- Log.d(TAG, "xPages " + xPages + " xPage " + xCurrentPage);
- Log.d(TAG, "xOffsetStep " + xOffsetStep + " xOffset " + xOffset);
- }
-
- float finalXOffsetStep = xOffsetStep;
- float finalXOffset = xOffset;
-
- Trace.beginSection("WallpaperService#processLocalColors");
- resetWindowPages();
- int xPage = xCurrentPage;
+ Set<RectF> areas;
EngineWindowPage current;
- if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) {
- mWindowPages = new EngineWindowPage[xPages];
- initWindowPages(mWindowPages, finalXOffsetStep);
- }
- if (mLocalColorsToAdd.size() != 0) {
- for (RectF colorArea : mLocalColorsToAdd) {
- if (!isValid(colorArea)) continue;
- mLocalColorAreas.add(colorArea);
- int colorPage = getRectFPage(colorArea, finalXOffsetStep);
- EngineWindowPage currentPage = mWindowPages[colorPage];
- currentPage.setLastUpdateTime(0);
- currentPage.removeColor(colorArea);
- }
- mLocalColorsToAdd.clear();
- }
- if (xPage >= mWindowPages.length) {
+
+ synchronized (mLock) {
+ xOffset = mPendingXOffset;
+ xOffsetStep = mPendingXOffsetStep;
+ wallpaperDimAmount = mWallpaperDimAmount;
+
if (DEBUG) {
- Log.e(TAG, "error xPage >= mWindowPages.length page: " + xPage);
- Log.e(TAG, "error on page " + xPage + " out of " + xPages);
- Log.e(TAG,
- "error on xOffsetStep " + finalXOffsetStep
- + " xOffset " + finalXOffset);
+ Log.d(TAG, "processLocalColors " + xOffset + " of step "
+ + xOffsetStep);
}
- xPage = mWindowPages.length - 1;
+ if (xOffset % xOffsetStep > MIN_PAGE_ALLOWED_MARGIN
+ || !mSurfaceHolder.getSurface().isValid()) return;
+ int xCurrentPage;
+ if (!validStep(xOffsetStep)) {
+ if (DEBUG) {
+ Log.w(TAG, "invalid offset step " + xOffsetStep);
+ }
+ xOffset = 0;
+ xOffsetStep = 1;
+ xCurrentPage = 0;
+ xPages = 1;
+ } else {
+ xPages = Math.round(1 / xOffsetStep) + 1;
+ xOffsetStep = (float) 1 / (float) xPages;
+ float shrink = (float) (xPages - 1) / (float) xPages;
+ xOffset *= shrink;
+ xCurrentPage = Math.round(xOffset / xOffsetStep);
+ }
+ if (DEBUG) {
+ Log.d(TAG, "xPages " + xPages + " xPage " + xCurrentPage);
+ Log.d(TAG, "xOffsetStep " + xOffsetStep + " xOffset " + xOffset);
+ }
+
+ float finalXOffsetStep = xOffsetStep;
+ float finalXOffset = xOffset;
+
+ resetWindowPages();
+ xPage = xCurrentPage;
+ if (mWindowPages.length == 0 || (mWindowPages.length != xPages)) {
+ mWindowPages = new EngineWindowPage[xPages];
+ initWindowPages(mWindowPages, finalXOffsetStep);
+ }
+ if (mLocalColorsToAdd.size() != 0) {
+ for (RectF colorArea : mLocalColorsToAdd) {
+ if (!isValid(colorArea)) continue;
+ mLocalColorAreas.add(colorArea);
+ int colorPage = getRectFPage(colorArea, finalXOffsetStep);
+ EngineWindowPage currentPage = mWindowPages[colorPage];
+ currentPage.setLastUpdateTime(0);
+ currentPage.removeColor(colorArea);
+ }
+ mLocalColorsToAdd.clear();
+ }
+ if (xPage >= mWindowPages.length) {
+ if (DEBUG) {
+ Log.e(TAG, "error xPage >= mWindowPages.length page: " + xPage);
+ Log.e(TAG, "error on page " + xPage + " out of " + xPages);
+ Log.e(TAG,
+ "error on xOffsetStep " + finalXOffsetStep
+ + " xOffset " + finalXOffset);
+ }
+ xPage = mWindowPages.length - 1;
+ }
+ current = mWindowPages[xPage];
+ areas = new HashSet<>(current.getAreas());
}
- current = mWindowPages[xPage];
- updatePage(current, xPage, xPages, finalXOffsetStep);
- Trace.endSection();
+ updatePage(current, areas, xPage, xPages, wallpaperDimAmount);
}
+ @GuardedBy("mLock")
private void initWindowPages(EngineWindowPage[] windowPages, float step) {
for (int i = 0; i < windowPages.length; i++) {
windowPages[i] = new EngineWindowPage();
@@ -1746,16 +1782,16 @@
}
}
- void updatePage(EngineWindowPage currentPage, int pageIndx, int numPages,
- float xOffsetStep) {
+ void updatePage(EngineWindowPage currentPage, Set<RectF> areas, int pageIndx, int numPages,
+ float wallpaperDimAmount) {
+
// in case the clock is zero, we start with negative time
long current = SystemClock.elapsedRealtime() - DEFAULT_UPDATE_SCREENSHOT_DURATION;
long lapsed = current - currentPage.getLastUpdateTime();
// Always update the page when the last update time is <= 0
// This is important especially when the device first boots
- if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) {
- return;
- }
+ if (lapsed < DEFAULT_UPDATE_SCREENSHOT_DURATION) return;
+
Surface surface = mSurfaceHolder.getSurface();
if (!surface.isValid()) return;
boolean widthIsLarger = mSurfaceSize.x > mSurfaceSize.y;
@@ -1768,43 +1804,59 @@
Log.e(TAG, "wrong width and height values of bitmap " + width + " " + height);
return;
}
+ final String pixelCopySectionName = "WallpaperService#pixelCopy";
+ final int pixelCopyCount = mPixelCopyCount++;
+ Trace.beginAsyncSection(pixelCopySectionName, pixelCopyCount);
Bitmap screenShot = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
final Bitmap finalScreenShot = screenShot;
- Trace.beginSection("WallpaperService#pixelCopy");
- PixelCopy.request(surface, screenShot, (res) -> {
- Trace.endSection();
- if (DEBUG) Log.d(TAG, "result of pixel copy is " + res);
- if (res != PixelCopy.SUCCESS) {
- Bitmap lastBitmap = currentPage.getBitmap();
- // assign the last bitmap taken for now
- currentPage.setBitmap(mLastScreenshot);
- Bitmap lastScreenshot = mLastScreenshot;
- if (lastScreenshot != null && !lastScreenshot.isRecycled()
- && !Objects.equals(lastBitmap, lastScreenshot)) {
- updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
+ try {
+ // TODO(b/274427458) check if this can be done in the background.
+ PixelCopy.request(surface, screenShot, (res) -> {
+ Trace.endAsyncSection(pixelCopySectionName, pixelCopyCount);
+ if (DEBUG) {
+ Log.d(TAG, "result of pixel copy is: "
+ + (res == PixelCopy.SUCCESS ? "SUCCESS" : "FAILURE"));
}
- } else {
- mLastScreenshot = finalScreenShot;
- // going to hold this lock for a while
- currentPage.setBitmap(finalScreenShot);
- currentPage.setLastUpdateTime(current);
- updatePageColors(currentPage, pageIndx, numPages, xOffsetStep);
- }
- }, mHandler);
-
+ if (res != PixelCopy.SUCCESS) {
+ Bitmap lastBitmap = currentPage.getBitmap();
+ // assign the last bitmap taken for now
+ currentPage.setBitmap(mLastScreenshot);
+ Bitmap lastScreenshot = mLastScreenshot;
+ if (lastScreenshot != null && !Objects.equals(lastBitmap, lastScreenshot)) {
+ updatePageColors(
+ currentPage, areas, pageIndx, numPages, wallpaperDimAmount);
+ }
+ } else {
+ mLastScreenshot = finalScreenShot;
+ currentPage.setBitmap(finalScreenShot);
+ currentPage.setLastUpdateTime(current);
+ updatePageColors(
+ currentPage, areas, pageIndx, numPages, wallpaperDimAmount);
+ }
+ }, mBackgroundHandler);
+ } catch (IllegalArgumentException e) {
+ // this can potentially happen if the surface is invalidated right between the
+ // surface.isValid() check and the PixelCopy operation.
+ // in this case, stop: we'll compute colors on the next processLocalColors call.
+ Log.w(TAG, "Cancelling processLocalColors: exception caught during PixelCopy");
+ }
}
// locked by the passed page
- private void updatePageColors(EngineWindowPage page, int pageIndx, int numPages,
- float xOffsetStep) {
+ private void updatePageColors(EngineWindowPage page, Set<RectF> areas,
+ int pageIndx, int numPages, float wallpaperDimAmount) {
if (page.getBitmap() == null) return;
+ if (!mBackgroundHandler.getLooper().isCurrentThread()) {
+ throw new IllegalStateException(
+ "ProcessLocalColors should be called from the background thread");
+ }
Trace.beginSection("WallpaperService#updatePageColors");
if (DEBUG) {
Log.d(TAG, "updatePageColorsLocked for page " + pageIndx + " with areas "
+ page.getAreas().size() + " and bitmap size of "
+ page.getBitmap().getWidth() + " x " + page.getBitmap().getHeight());
}
- for (RectF area: page.getAreas()) {
+ for (RectF area: areas) {
if (area == null) continue;
RectF subArea = generateSubRect(area, pageIndx, numPages);
Bitmap b = page.getBitmap();
@@ -1814,12 +1866,12 @@
int height = Math.round(b.getHeight() * subArea.height());
Bitmap target;
try {
- target = Bitmap.createBitmap(page.getBitmap(), x, y, width, height);
+ target = Bitmap.createBitmap(b, x, y, width, height);
} catch (Exception e) {
Log.e(TAG, "Error creating page local color bitmap", e);
continue;
}
- WallpaperColors color = WallpaperColors.fromBitmap(target, mWallpaperDimAmount);
+ WallpaperColors color = WallpaperColors.fromBitmap(target, wallpaperDimAmount);
target.recycle();
WallpaperColors currentColor = page.getColors(area);
@@ -1836,12 +1888,14 @@
+ " local color callback for area" + area + " for page " + pageIndx
+ " of " + numPages);
}
- try {
- mConnection.onLocalWallpaperColorsChanged(area, color,
- mDisplayContext.getDisplayId());
- } catch (RemoteException e) {
- Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
- }
+ mHandler.post(() -> {
+ try {
+ mConnection.onLocalWallpaperColorsChanged(area, color,
+ mDisplayContext.getDisplayId());
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling Connection.onLocalWallpaperColorsChanged", e);
+ }
+ });
}
}
Trace.endSection();
@@ -1867,16 +1921,17 @@
return new RectF(left, in.top, right, in.bottom);
}
+ @GuardedBy("mLock")
private void resetWindowPages() {
if (supportsLocalColorExtraction()) return;
if (!mResetWindowPages) return;
mResetWindowPages = false;
- mLastWindowPage = -1;
for (int i = 0; i < mWindowPages.length; i++) {
mWindowPages[i].setLastUpdateTime(0L);
}
}
+ @GuardedBy("mLock")
private int getRectFPage(RectF area, float step) {
if (!isValid(area)) return 0;
if (!validStep(step)) return 0;
@@ -1897,12 +1952,12 @@
if (DEBUG) {
Log.d(TAG, "addLocalColorsAreas adding local color areas " + regions);
}
- mHandler.post(() -> {
- mLocalColorsToAdd.addAll(regions);
- processLocalColors(mPendingXOffset, mPendingYOffset);
+ mBackgroundHandler.post(() -> {
+ synchronized (mLock) {
+ mLocalColorsToAdd.addAll(regions);
+ }
+ processLocalColors();
});
-
-
}
/**
@@ -1912,16 +1967,18 @@
*/
public void removeLocalColorsAreas(@NonNull List<RectF> regions) {
if (supportsLocalColorExtraction()) return;
- mHandler.post(() -> {
- float step = mPendingXOffsetStep;
- mLocalColorsToAdd.removeAll(regions);
- mLocalColorAreas.removeAll(regions);
- if (!validStep(step)) {
- return;
- }
- for (int i = 0; i < mWindowPages.length; i++) {
- for (int j = 0; j < regions.size(); j++) {
- mWindowPages[i].removeArea(regions.get(j));
+ mBackgroundHandler.post(() -> {
+ synchronized (mLock) {
+ float step = mPendingXOffsetStep;
+ mLocalColorsToAdd.removeAll(regions);
+ mLocalColorAreas.removeAll(regions);
+ if (!validStep(step)) {
+ return;
+ }
+ for (int i = 0; i < mWindowPages.length; i++) {
+ for (int j = 0; j < regions.size(); j++) {
+ mWindowPages[i].removeArea(regions.get(j));
+ }
}
}
});
@@ -1939,7 +1996,7 @@
}
private boolean validStep(float step) {
- return !PROHIBITED_STEPS.contains(step) && step > 0. && step <= 1.;
+ return !Float.isNaN(step) && step > 0f && step <= 1f;
}
void doCommand(WallpaperCommand cmd) {
@@ -2578,6 +2635,9 @@
@Override
public void onCreate() {
Trace.beginSection("WPMS.onCreate");
+ mBackgroundThread = new HandlerThread("DefaultWallpaperLocalColorExtractor");
+ mBackgroundThread.start();
+ mBackgroundHandler = new Handler(mBackgroundThread.getLooper());
super.onCreate();
Trace.endSection();
}
@@ -2590,6 +2650,7 @@
engineWrapper.destroy();
}
mActiveEngines.clear();
+ mBackgroundThread.quitSafely();
Trace.endSection();
}
diff --git a/core/java/android/util/FeatureFlagUtils.java b/core/java/android/util/FeatureFlagUtils.java
index 6201b3a..4c6bd67 100644
--- a/core/java/android/util/FeatureFlagUtils.java
+++ b/core/java/android/util/FeatureFlagUtils.java
@@ -234,8 +234,8 @@
DEFAULT_FLAGS.put(SETTINGS_AUDIO_ROUTING, "false");
DEFAULT_FLAGS.put(SETTINGS_FLASH_NOTIFICATIONS, "true");
DEFAULT_FLAGS.put(SETTINGS_SHOW_UDFPS_ENROLL_IN_SETTINGS, "true");
- DEFAULT_FLAGS.put(SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API, "false");
- DEFAULT_FLAGS.put(SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION, "false");
+ DEFAULT_FLAGS.put(SETTINGS_ENABLE_LOCKSCREEN_TRANSFER_API, "true");
+ DEFAULT_FLAGS.put(SETTINGS_REMOTE_DEVICE_CREDENTIAL_VALIDATION, "true");
}
private static final Set<String> PERSISTENT_FLAGS;
diff --git a/core/java/android/util/SparseArray.java b/core/java/android/util/SparseArray.java
index cc83dec..cd03d83 100644
--- a/core/java/android/util/SparseArray.java
+++ b/core/java/android/util/SparseArray.java
@@ -71,7 +71,7 @@
* Creates a new SparseArray containing no mappings.
*/
public SparseArray() {
- this(10);
+ this(0);
}
/**
diff --git a/core/java/android/util/SparseBooleanArray.java b/core/java/android/util/SparseBooleanArray.java
index c145b20..12a9900 100644
--- a/core/java/android/util/SparseBooleanArray.java
+++ b/core/java/android/util/SparseBooleanArray.java
@@ -51,7 +51,7 @@
* Creates a new SparseBooleanArray containing no mappings.
*/
public SparseBooleanArray() {
- this(10);
+ this(0);
}
/**
diff --git a/core/java/android/util/SparseDoubleArray.java b/core/java/android/util/SparseDoubleArray.java
index ee2e3ce..4b0cbe4 100644
--- a/core/java/android/util/SparseDoubleArray.java
+++ b/core/java/android/util/SparseDoubleArray.java
@@ -50,7 +50,7 @@
/** Creates a new SparseDoubleArray containing no mappings. */
public SparseDoubleArray() {
- this(10);
+ this(0);
}
/**
diff --git a/core/java/android/util/SparseIntArray.java b/core/java/android/util/SparseIntArray.java
index d4f6685..0e98c28 100644
--- a/core/java/android/util/SparseIntArray.java
+++ b/core/java/android/util/SparseIntArray.java
@@ -58,7 +58,7 @@
* Creates a new SparseIntArray containing no mappings.
*/
public SparseIntArray() {
- this(10);
+ this(0);
}
/**
diff --git a/core/java/android/util/SparseLongArray.java b/core/java/android/util/SparseLongArray.java
index b739e37..e86b647 100644
--- a/core/java/android/util/SparseLongArray.java
+++ b/core/java/android/util/SparseLongArray.java
@@ -51,7 +51,7 @@
* Creates a new SparseLongArray containing no mappings.
*/
public SparseLongArray() {
- this(10);
+ this(0);
}
/**
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java
index 8c4e90c..c92b1b8 100644
--- a/core/java/android/view/Choreographer.java
+++ b/core/java/android/view/Choreographer.java
@@ -195,7 +195,7 @@
private boolean mDebugPrintNextFrameTimeDelta;
private int mFPSDivisor = 1;
- private DisplayEventReceiver.VsyncEventData mLastVsyncEventData =
+ private final DisplayEventReceiver.VsyncEventData mLastVsyncEventData =
new DisplayEventReceiver.VsyncEventData();
private final FrameData mFrameData = new FrameData();
@@ -857,7 +857,7 @@
mFrameScheduled = false;
mLastFrameTimeNanos = frameTimeNanos;
mLastFrameIntervalNanos = frameIntervalNanos;
- mLastVsyncEventData = vsyncEventData;
+ mLastVsyncEventData.copyFrom(vsyncEventData);
}
AnimationUtils.lockAnimationClock(frameTimeNanos / TimeUtils.NANOS_PER_MS);
@@ -1247,7 +1247,7 @@
private boolean mHavePendingVsync;
private long mTimestampNanos;
private int mFrame;
- private VsyncEventData mLastVsyncEventData = new VsyncEventData();
+ private final VsyncEventData mLastVsyncEventData = new VsyncEventData();
FrameDisplayEventReceiver(Looper looper, int vsyncSource, long layerHandle) {
super(looper, vsyncSource, /* eventRegistration */ 0, layerHandle);
@@ -1287,7 +1287,7 @@
mTimestampNanos = timestampNanos;
mFrame = frame;
- mLastVsyncEventData = vsyncEventData;
+ mLastVsyncEventData.copyFrom(vsyncEventData);
Message msg = Message.obtain(mHandler, this);
msg.setAsynchronous(true);
mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java
index b4675e0..54db34e 100644
--- a/core/java/android/view/DisplayEventReceiver.java
+++ b/core/java/android/view/DisplayEventReceiver.java
@@ -146,7 +146,12 @@
mMessageQueue = null;
}
- static final class VsyncEventData {
+ /**
+ * Class to capture all inputs required for syncing events data.
+ *
+ * @hide
+ */
+ public static final class VsyncEventData {
// The amount of frame timeline choices.
// Must be in sync with VsyncEventData::kFrameTimelinesLength in
// frameworks/native/libs/gui/include/gui/VsyncEventData.h. If they do not match, a runtime
@@ -164,6 +169,12 @@
this.deadline = deadline;
}
+ void copyFrom(FrameTimeline other) {
+ vsyncId = other.vsyncId;
+ expectedPresentationTime = other.expectedPresentationTime;
+ deadline = other.deadline;
+ }
+
// The frame timeline vsync id, used to correlate a frame
// produced by HWUI with the timeline data stored in Surface Flinger.
public long vsyncId = FrameInfo.INVALID_VSYNC_ID;
@@ -203,6 +214,14 @@
this.frameInterval = frameInterval;
}
+ void copyFrom(VsyncEventData other) {
+ preferredFrameTimelineIndex = other.preferredFrameTimelineIndex;
+ frameInterval = other.frameInterval;
+ for (int i = 0; i < frameTimelines.length; i++) {
+ frameTimelines[i].copyFrom(other.frameTimelines[i]);
+ }
+ }
+
public FrameTimeline preferredFrameTimeline() {
return frameTimelines[preferredFrameTimelineIndex];
}
diff --git a/core/java/android/view/IWindowManager.aidl b/core/java/android/view/IWindowManager.aidl
index 209729b..48ae59b 100644
--- a/core/java/android/view/IWindowManager.aidl
+++ b/core/java/android/view/IWindowManager.aidl
@@ -112,14 +112,19 @@
void getInitialDisplaySize(int displayId, out Point size);
@UnsupportedAppUsage
void getBaseDisplaySize(int displayId, out Point size);
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
void setForcedDisplaySize(int displayId, int width, int height);
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
void clearForcedDisplaySize(int displayId);
@UnsupportedAppUsage
int getInitialDisplayDensity(int displayId);
int getBaseDisplayDensity(int displayId);
int getDisplayIdByUniqueId(String uniqueId);
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
void setForcedDisplayDensityForUser(int displayId, int density, int userId);
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
void clearForcedDisplayDensityForUser(int displayId, int userId);
+ @EnforcePermission("WRITE_SECURE_SETTINGS")
void setForcedDisplayScalingMode(int displayId, int mode); // 0 = auto, 1 = disable
// These can only be called when holding the MANAGE_APP_TOKENS permission.
@@ -159,6 +164,7 @@
* @param shellRootLayer The container's layer. See WindowManager#ShellRootLayer.
* @return a SurfaceControl to add things to.
*/
+ @EnforcePermission("MANAGE_APP_TOKENS")
SurfaceControl addShellRoot(int displayId, IWindow client, int shellRootLayer);
/**
@@ -167,6 +173,7 @@
*
* @param target The IWindow that accessibility service interfaces with.
*/
+ @EnforcePermission("MANAGE_APP_TOKENS")
void setShellRootAccessibilityWindow(int displayId, int shellRootLayer, IWindow target);
/**
@@ -197,6 +204,7 @@
void disableKeyguard(IBinder token, String tag, int userId);
/** @deprecated use Activity.setShowWhenLocked instead. */
void reenableKeyguard(IBinder token, int userId);
+ @EnforcePermission("DISABLE_KEYGUARD")
void exitKeyguardSecurely(IOnKeyguardExitResult callback);
@UnsupportedAppUsage
boolean isKeyguardLocked();
@@ -417,6 +425,7 @@
/**
* Called by System UI to enable or disable haptic feedback on the navigation bar buttons.
*/
+ @EnforcePermission("STATUS_BAR")
@UnsupportedAppUsage
void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled);
@@ -504,6 +513,7 @@
/**
* Return the touch region for the current IME window, or an empty region if there is none.
*/
+ @EnforcePermission("RESTRICTED_VR_ACCESS")
Region getCurrentImeTouchRegion();
/**
@@ -713,6 +723,7 @@
* When in multi-window mode, the provided displayWindowInsetsController will control insets
* animations.
*/
+ @EnforcePermission("MANAGE_APP_TOKENS")
void setDisplayWindowInsetsController(
int displayId, in IDisplayWindowInsetsController displayWindowInsetsController);
@@ -720,6 +731,7 @@
* Called when a remote process updates the requested visibilities of insets on a display window
* container.
*/
+ @EnforcePermission("MANAGE_APP_TOKENS")
void updateDisplayWindowRequestedVisibleTypes(int displayId, int requestedVisibleTypes);
/**
diff --git a/core/java/android/view/IWindowSession.aidl b/core/java/android/view/IWindowSession.aidl
index 5810642..83de2a0 100644
--- a/core/java/android/view/IWindowSession.aidl
+++ b/core/java/android/view/IWindowSession.aidl
@@ -110,16 +110,6 @@
int requestedWidth, int requestedHeight, int viewVisibility, int flags, int seq,
int lastSyncSeqId);
- /*
- * Notify the window manager that an application is relaunching and
- * windows should be prepared for replacement.
- *
- * @param appToken The application
- * @param childrenOnly Whether to only prepare child windows for replacement
- * (for example when main windows are being reused via preservation).
- */
- oneway void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly);
-
/**
* Called by a client to report that it ran out of graphics memory.
*/
@@ -304,7 +294,7 @@
* an input channel where the client can receive input.
*/
void grantInputChannel(int displayId, in SurfaceControl surface, in IWindow window,
- in IBinder hostInputToken, int flags, int privateFlags, int type,
+ in IBinder hostInputToken, int flags, int privateFlags, int inputFeatures, int type,
in IBinder windowToken, in IBinder focusGrantToken, String inputHandleName,
out InputChannel outInputChannel);
@@ -312,7 +302,8 @@
* Update the flags on an input channel associated with a particular surface.
*/
oneway void updateInputChannel(in IBinder channelToken, int displayId,
- in SurfaceControl surface, int flags, int privateFlags, in Region region);
+ in SurfaceControl surface, int flags, int privateFlags, int inputFeatures,
+ in Region region);
/**
* Transfer window focus to an embedded window if the calling window has focus.
diff --git a/core/java/android/view/InputDevice.java b/core/java/android/view/InputDevice.java
index 9225cd9..61864d7 100644
--- a/core/java/android/view/InputDevice.java
+++ b/core/java/android/view/InputDevice.java
@@ -1183,8 +1183,10 @@
*/
@NonNull
public LightsManager getLightsManager() {
- if (mLightsManager == null) {
- mLightsManager = InputManager.getInstance().getInputDeviceLightsManager(mId);
+ synchronized (mMotionRanges) {
+ if (mLightsManager == null) {
+ mLightsManager = InputManager.getInstance().getInputDeviceLightsManager(mId);
+ }
}
return mLightsManager;
}
diff --git a/core/java/android/view/InputEvent.java b/core/java/android/view/InputEvent.java
index cb9e746..0b4adae 100644
--- a/core/java/android/view/InputEvent.java
+++ b/core/java/android/view/InputEvent.java
@@ -207,7 +207,7 @@
*
* @hide
*/
- public abstract long getEventTimeNano();
+ public abstract long getEventTimeNanos();
/**
* Marks the input event as being canceled.
diff --git a/core/java/android/view/InputEventConsistencyVerifier.java b/core/java/android/view/InputEventConsistencyVerifier.java
index c0a3cec..5c38a15 100644
--- a/core/java/android/view/InputEventConsistencyVerifier.java
+++ b/core/java/android/view/InputEventConsistencyVerifier.java
@@ -721,7 +721,7 @@
private static void appendEvent(StringBuilder message, int index,
InputEvent event, boolean unhandled) {
- message.append(index).append(": sent at ").append(event.getEventTimeNano());
+ message.append(index).append(": sent at ").append(event.getEventTimeNanos());
message.append(", ");
if (unhandled) {
message.append("(unhandled) ");
diff --git a/core/java/android/view/KeyEvent.java b/core/java/android/view/KeyEvent.java
index ab81345..b6d9400 100644
--- a/core/java/android/view/KeyEvent.java
+++ b/core/java/android/view/KeyEvent.java
@@ -897,13 +897,38 @@
* This key is handled by the framework and is never delivered to applications.
*/
public static final int KEYCODE_RECENT_APPS = 312;
+ /**
+ * Key code constant: A button whose usage can be customized by the user through
+ * the system.
+ * User customizable key #1.
+ */
+ public static final int KEYCODE_MACRO_1 = 313;
+ /**
+ * Key code constant: A button whose usage can be customized by the user through
+ * the system.
+ * User customizable key #2.
+ */
+ public static final int KEYCODE_MACRO_2 = 314;
+ /**
+ * Key code constant: A button whose usage can be customized by the user through
+ * the system.
+ * User customizable key #3.
+ */
+ public static final int KEYCODE_MACRO_3 = 315;
+ /**
+ * Key code constant: A button whose usage can be customized by the user through
+ * the system.
+ * User customizable key #4.
+ */
+ public static final int KEYCODE_MACRO_4 = 316;
+
/**
* Integer value of the last KEYCODE. Increases as new keycodes are added to KeyEvent.
* @hide
*/
@TestApi
- public static final int LAST_KEYCODE = KEYCODE_RECENT_APPS;
+ public static final int LAST_KEYCODE = KEYCODE_MACRO_4;
// NOTE: If you add a new keycode here you must also add it to:
// isSystem()
@@ -2711,7 +2736,7 @@
* @hide
*/
@Override
- public final long getEventTimeNano() {
+ public final long getEventTimeNanos() {
return mEventTime;
}
diff --git a/core/java/android/view/MotionEvent.java b/core/java/android/view/MotionEvent.java
index a71ab8a..3902989 100644
--- a/core/java/android/view/MotionEvent.java
+++ b/core/java/android/view/MotionEvent.java
@@ -2440,13 +2440,31 @@
*
* @hide
*/
- @Override
- @UnsupportedAppUsage
+ @UnsupportedAppUsage(publicAlternatives =
+ "Use {@link #getEventTimeNanos()} public API instead.",
+ maxTargetSdk = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
public final long getEventTimeNano() {
return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT);
}
/**
+ * Retrieve the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base but with
+ * nanosecond precision.
+ * <p>
+ * The value is in nanosecond precision but it may not have nanosecond accuracy.
+ * </p>
+ *
+ * @return Returns the time this event occurred,
+ * in the {@link android.os.SystemClock#uptimeMillis} time base but with
+ * nanosecond precision.
+ */
+ @Override
+ public long getEventTimeNanos() {
+ return nativeGetEventTimeNanos(mNativePtr, HISTORY_CURRENT);
+ }
+
+ /**
* Equivalent to {@link #getX(int)} for pointer index 0 (regardless of the
* pointer identifier).
*
@@ -3104,10 +3122,8 @@
*
* @see #getHistorySize
* @see #getEventTime
- *
- * @hide
*/
- public final long getHistoricalEventTimeNano(int pos) {
+ public long getHistoricalEventTimeNanos(int pos) {
return nativeGetEventTimeNanos(mNativePtr, pos);
}
diff --git a/core/java/android/view/SurfaceView.java b/core/java/android/view/SurfaceView.java
index b46a68c..d8b6b7b 100644
--- a/core/java/android/view/SurfaceView.java
+++ b/core/java/android/view/SurfaceView.java
@@ -851,10 +851,14 @@
}
mParentSurfaceSequenceId = viewRoot.getSurfaceSequenceId();
- if (mViewVisibility) {
- surfaceUpdateTransaction.show(mSurfaceControl);
- } else {
- surfaceUpdateTransaction.hide(mSurfaceControl);
+ // Only control visibility if we're not hardware-accelerated. Otherwise we'll
+ // let renderthread drive since offscreen SurfaceControls should not be visible.
+ if (!isHardwareAccelerated()) {
+ if (mViewVisibility) {
+ surfaceUpdateTransaction.show(mSurfaceControl);
+ } else {
+ surfaceUpdateTransaction.hide(mSurfaceControl);
+ }
}
updateBackgroundVisibility(surfaceUpdateTransaction);
@@ -1417,12 +1421,10 @@
}
private final Rect mRTLastReportedPosition = new Rect();
- private final Point mRTLastReportedSurfaceSize = new Point();
private class SurfaceViewPositionUpdateListener implements RenderNode.PositionUpdateListener {
private final int mRtSurfaceWidth;
private final int mRtSurfaceHeight;
- private boolean mRtFirst = true;
private final SurfaceControl.Transaction mPositionChangedTransaction =
new SurfaceControl.Transaction();
@@ -1433,15 +1435,6 @@
@Override
public void positionChanged(long frameNumber, int left, int top, int right, int bottom) {
- if (!mRtFirst && (mRTLastReportedPosition.left == left
- && mRTLastReportedPosition.top == top
- && mRTLastReportedPosition.right == right
- && mRTLastReportedPosition.bottom == bottom
- && mRTLastReportedSurfaceSize.x == mRtSurfaceWidth
- && mRTLastReportedSurfaceSize.y == mRtSurfaceHeight)) {
- return;
- }
- mRtFirst = false;
try {
if (DEBUG_POSITION) {
Log.d(TAG, String.format(
@@ -1452,8 +1445,8 @@
}
synchronized (mSurfaceControlLock) {
if (mSurfaceControl == null) return;
+
mRTLastReportedPosition.set(left, top, right, bottom);
- mRTLastReportedSurfaceSize.set(mRtSurfaceWidth, mRtSurfaceHeight);
onSetSurfacePositionAndScale(mPositionChangedTransaction, mSurfaceControl,
mRTLastReportedPosition.left /*positionLeft*/,
mRTLastReportedPosition.top /*positionTop*/,
@@ -1461,10 +1454,8 @@
/ (float) mRtSurfaceWidth /*postScaleX*/,
mRTLastReportedPosition.height()
/ (float) mRtSurfaceHeight /*postScaleY*/);
- if (mViewVisibility) {
- // b/131239825
- mPositionChangedTransaction.show(mSurfaceControl);
- }
+
+ mPositionChangedTransaction.show(mSurfaceControl);
}
applyOrMergeTransaction(mPositionChangedTransaction, frameNumber);
} catch (Exception ex) {
@@ -1490,7 +1481,6 @@
System.identityHashCode(this), frameNumber));
}
mRTLastReportedPosition.setEmpty();
- mRTLastReportedSurfaceSize.set(-1, -1);
// positionLost can be called while UI thread is un-paused.
synchronized (mSurfaceControlLock) {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index e063672..01c34f7 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -417,7 +417,8 @@
private boolean mUseBLASTAdapter;
private boolean mForceDisableBLAST;
- private boolean mFastScrollSoundEffectsEnabled;
+ /** lazily-initialized in getAudioManager() */
+ private boolean mFastScrollSoundEffectsEnabled = false;
/**
* Signals that compatibility booleans have been initialized according to
@@ -1028,8 +1029,6 @@
loadSystemProperties();
mImeFocusController = new ImeFocusController(this);
- AudioManager audioManager = mContext.getSystemService(AudioManager.class);
- mFastScrollSoundEffectsEnabled = audioManager.areNavigationRepeatSoundEffectsEnabled();
mScrollCaptureRequestTimeout = SCROLL_CAPTURE_REQUEST_TIMEOUT_MILLIS;
mOnBackInvokedDispatcher = new WindowOnBackInvokedDispatcher(context);
@@ -8344,6 +8343,7 @@
}
if (mAudioManager == null) {
mAudioManager = (AudioManager) mView.getContext().getSystemService(Context.AUDIO_SERVICE);
+ mFastScrollSoundEffectsEnabled = mAudioManager.areNavigationRepeatSoundEffectsEnabled();
}
return mAudioManager;
}
@@ -9175,7 +9175,7 @@
* Represents a pending input event that is waiting in a queue.
*
* Input events are processed in serial order by the timestamp specified by
- * {@link InputEvent#getEventTimeNano()}. In general, the input dispatcher delivers
+ * {@link InputEvent#getEventTimeNanos()}. In general, the input dispatcher delivers
* one input event to the application at a time and waits for the application
* to finish handling it before delivering the next one.
*
@@ -9365,7 +9365,7 @@
if (Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) {
Trace.traceBegin(Trace.TRACE_TAG_VIEW, "deliverInputEvent src=0x"
+ Integer.toHexString(q.mEvent.getSource()) + " eventTimeNano="
- + q.mEvent.getEventTimeNano() + " id=0x"
+ + q.mEvent.getEventTimeNanos() + " id=0x"
+ Integer.toHexString(q.mEvent.getId()));
}
try {
diff --git a/core/java/android/view/WindowManager.java b/core/java/android/view/WindowManager.java
index 35ed88f..cda1f3a 100644
--- a/core/java/android/view/WindowManager.java
+++ b/core/java/android/view/WindowManager.java
@@ -863,10 +863,8 @@
* android:value="true|false"/>
* </application>
* </pre>
- *
- * @hide
*/
- // TODO(b/263984287): Make this public API.
+ // TODO(b/263984287): Add CTS tests.
String PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION =
"android.window.PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION";
@@ -899,8 +897,6 @@
* android:value="false"/>
* </application>
* </pre>
- *
- * @hide
*/
// TODO(b/263984287): Make this public API.
String PROPERTY_COMPAT_ALLOW_SANDBOXING_VIEW_BOUNDS_APIS =
@@ -937,10 +933,8 @@
* android:value="true|false"/>
* </application>
* </pre>
- *
- * @hide
*/
- // TODO(b/263984287): Make this public API.
+ // TODO(b/263984287): Add CTS tests.
String PROPERTY_COMPAT_ENABLE_FAKE_FOCUS = "android.window.PROPERTY_COMPAT_ENABLE_FAKE_FOCUS";
/**
@@ -976,10 +970,8 @@
* android:value="true|false"/>
* </application>
* </pre>
- *
- * @hide
*/
- // TODO(b/263984287): Make this public API.
+ // TODO(b/263984287): Add CTS tests.
String PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION =
"android.window.PROPERTY_CAMERA_COMPAT_ALLOW_FORCE_ROTATION";
@@ -1023,10 +1015,8 @@
* android:value="true|false"/>
* </application>
* </pre>
- *
- * @hide
*/
- // TODO(b/263984287): Make this public API.
+ // TODO(b/263984287): Add CTS tests.
String PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH =
"android.window.PROPERTY_CAMERA_COMPAT_ALLOW_REFRESH";
@@ -1073,17 +1063,28 @@
* android:value="true|false"/>
* </application>
* </pre>
- *
- * @hide
*/
- // TODO(b/263984287): Make this public API.
+ // TODO(b/263984287): Add CTS tests.
String PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE =
"android.window.PROPERTY_CAMERA_COMPAT_ENABLE_REFRESH_VIA_PAUSE";
/**
* Application level {@link android.content.pm.PackageManager.Property PackageManager
* .Property} for an app to inform the system that the app should be excluded from the
- * compatibility override for orientation set by the device manufacturer.
+ * compatibility override for orientation set by the device manufacturer. When the orientation
+ * override is applied it can:
+ * <ul>
+ * <li>Replace the specific orientation requested by the app with another selected by the
+ device manufacturer, e.g. replace undefined requested by the app with portrait.
+ * <li>Always use an orientation selected by the device manufacturer.
+ * <li>Do one of the above but only when camera connection is open.
+ * </ul>
+ *
+ * <p>This property is different from {@link PROPERTY_COMPAT_IGNORE_REQUESTED_ORIENTATION}
+ * (which is used to avoid orientation loops caused by the incorrect use of {@link
+ * android.app.Activity#setRequestedOrientation}) because this property overrides the app to an
+ * orientation selected by the device manufacturer rather than ignoring one of orientation
+ * requests coming from the app while respecting the previous one.
*
* <p>With this property set to {@code true} or unset, device manufacturers can override
* orientation for the app using their discretion to improve display compatibility.
@@ -1099,10 +1100,8 @@
* android:value="true|false"/>
* </application>
* </pre>
- *
- * @hide
*/
- // TODO(b/263984287): Make this public API.
+ // TODO(b/263984287): Add CTS tests.
String PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE =
"android.window.PROPERTY_COMPAT_ALLOW_ORIENTATION_OVERRIDE";
@@ -1144,10 +1143,8 @@
* android:value="true|false"/>
* </application>
* </pre>
- *
- * @hide
*/
- // TODO(b/263984287): Make this public API.
+ // TODO(b/263984287): Add CTS tests.
String PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE =
"android.window.PROPERTY_COMPAT_ALLOW_DISPLAY_ORIENTATION_OVERRIDE";
@@ -2815,7 +2812,7 @@
*
* @hide
*/
- public static final int PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED = 0x00000002;
+ public static final int PRIVATE_FLAG_FORCE_HARDWARE_ACCELERATED = 1 << 1;
/**
* By default, wallpapers are sent new offsets when the wallpaper is scrolled. Wallpapers
@@ -2826,7 +2823,7 @@
*
* @hide
*/
- public static final int PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS = 0x00000004;
+ public static final int PRIVATE_FLAG_WANTS_OFFSET_NOTIFICATIONS = 1 << 2;
/**
* When set {@link LayoutParams#TYPE_APPLICATION_OVERLAY} windows will stay visible, even if
@@ -2835,7 +2832,7 @@
* @hide
*/
@RequiresPermission(permission.SYSTEM_APPLICATION_OVERLAY)
- public static final int PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY = 0x00000008;
+ public static final int PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY = 1 << 3;
/** In a multiuser system if this flag is set and the owner is a system process then this
* window will appear on all user screens. This overrides the default behavior of window
@@ -2845,7 +2842,7 @@
* {@hide} */
@SystemApi
@RequiresPermission(permission.INTERNAL_SYSTEM_WINDOW)
- public static final int SYSTEM_FLAG_SHOW_FOR_ALL_USERS = 0x00000010;
+ public static final int SYSTEM_FLAG_SHOW_FOR_ALL_USERS = 1 << 4;
/**
* Flag to allow this window to have unrestricted gesture exclusion.
@@ -2853,7 +2850,7 @@
* @see View#setSystemGestureExclusionRects(List)
* @hide
*/
- public static final int PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION = 0x00000020;
+ public static final int PRIVATE_FLAG_UNRESTRICTED_GESTURE_EXCLUSION = 1 << 5;
/**
* Never animate position changes of the window.
@@ -2862,20 +2859,20 @@
* {@hide}
*/
@UnsupportedAppUsage
- public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 0x00000040;
+ public static final int PRIVATE_FLAG_NO_MOVE_ANIMATION = 1 << 6;
/** Window flag: special flag to limit the size of the window to be
* original size ([320x480] x density). Used to create window for applications
* running under compatibility mode.
*
* {@hide} */
- public static final int PRIVATE_FLAG_COMPATIBLE_WINDOW = 0x00000080;
+ public static final int PRIVATE_FLAG_COMPATIBLE_WINDOW = 1 << 7;
/** Window flag: a special option intended for system dialogs. When
* this flag is set, the window will demand focus unconditionally when
* it is created.
* {@hide} */
- public static final int PRIVATE_FLAG_SYSTEM_ERROR = 0x00000100;
+ public static final int PRIVATE_FLAG_SYSTEM_ERROR = 1 << 8;
/**
* Flag to indicate that the view hierarchy of the window can only be measured when
@@ -2884,14 +2881,14 @@
* views. This reduces the chances to perform measure.
* {@hide}
*/
- public static final int PRIVATE_FLAG_OPTIMIZE_MEASURE = 0x00000200;
+ public static final int PRIVATE_FLAG_OPTIMIZE_MEASURE = 1 << 9;
/**
* Flag that prevents the wallpaper behind the current window from receiving touch events.
*
* {@hide}
*/
- public static final int PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS = 0x00000800;
+ public static final int PRIVATE_FLAG_DISABLE_WALLPAPER_TOUCH_EVENTS = 1 << 10;
/**
* Flag to force the status bar window to be visible all the time. If the bar is hidden when
@@ -2900,7 +2897,7 @@
*
* {@hide}
*/
- public static final int PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR = 0x00001000;
+ public static final int PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR = 1 << 11;
/**
* Flag to indicate that the window frame should be the requested frame adding the display
@@ -2910,7 +2907,7 @@
*
* {@hide}
*/
- public static final int PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT = 0x00002000;
+ public static final int PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT = 1 << 12;
/**
* Flag that will make window ignore app visibility and instead depend purely on the decor
@@ -2918,39 +2915,28 @@
* drawing after it launches an app.
* @hide
*/
- public static final int PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY = 0x00004000;
-
- /**
- * Flag to indicate that this window is not expected to be replaced across
- * configuration change triggered activity relaunches. In general the WindowManager
- * expects Windows to be replaced after relaunch, and thus it will preserve their surfaces
- * until the replacement is ready to show in order to prevent visual glitch. However
- * some windows, such as PopupWindows expect to be cleared across configuration change,
- * and thus should hint to the WindowManager that it should not wait for a replacement.
- * @hide
- */
- public static final int PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH = 0x00008000;
+ public static final int PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY = 1 << 13;
/**
* Flag to indicate that this child window should always be laid-out in the parent
* frame regardless of the current windowing mode configuration.
* @hide
*/
- public static final int PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME = 0x00010000;
+ public static final int PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME = 1 << 14;
/**
* Flag to indicate that this window is always drawing the status bar background, no matter
* what the other flags are.
* @hide
*/
- public static final int PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS = 0x00020000;
+ public static final int PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS = 1 << 15;
/**
* Flag to indicate that this window needs Sustained Performance Mode if
* the device supports it.
* @hide
*/
- public static final int PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE = 0x00040000;
+ public static final int PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE = 1 << 16;
/**
* Flag to indicate that any window added by an application process that is of type
@@ -2961,7 +2947,7 @@
*/
@SystemApi
@RequiresPermission(permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS)
- public static final int SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 0x00080000;
+ public static final int SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS = 1 << 19;
/**
* Indicates that this window is the rounded corners overlay present on some
@@ -2969,7 +2955,7 @@
* screen magnification, and mirroring.
* @hide
*/
- public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 0x00100000;
+ public static final int PRIVATE_FLAG_IS_ROUNDED_CORNERS_OVERLAY = 1 << 20;
/**
* Flag to indicate that this window will be excluded while computing the magnifiable region
@@ -2983,7 +2969,7 @@
* </p><p>
* @hide
*/
- public static final int PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION = 0x00200000;
+ public static final int PRIVATE_FLAG_EXCLUDE_FROM_SCREEN_MAGNIFICATION = 1 << 21;
/**
* Flag to prevent the window from being magnified by the accessibility magnifier.
@@ -2991,7 +2977,7 @@
* TODO(b/190623172): This is a temporary solution and need to find out another way instead.
* @hide
*/
- public static final int PRIVATE_FLAG_NOT_MAGNIFIABLE = 0x00400000;
+ public static final int PRIVATE_FLAG_NOT_MAGNIFIABLE = 1 << 22;
/**
* Flag to indicate that the status bar window is in a state such that it forces showing
@@ -3000,54 +2986,54 @@
* It only takes effects if this is set by {@link LayoutParams#TYPE_STATUS_BAR}.
* @hide
*/
- public static final int PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION = 0x00800000;
+ public static final int PRIVATE_FLAG_STATUS_FORCE_SHOW_NAVIGATION = 1 << 23;
/**
* Flag to indicate that the window is color space agnostic, and the color can be
* interpreted to any color space.
* @hide
*/
- public static final int PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC = 0x01000000;
+ public static final int PRIVATE_FLAG_COLOR_SPACE_AGNOSTIC = 1 << 24;
/**
* Flag to request creation of a BLAST (Buffer as LayerState) Layer.
* If not specified the client will receive a BufferQueue layer.
* @hide
*/
- public static final int PRIVATE_FLAG_USE_BLAST = 0x02000000;
+ public static final int PRIVATE_FLAG_USE_BLAST = 1 << 25;
/**
* Flag to indicate that the window is controlling the appearance of system bars. So we
* don't need to adjust it by reading its system UI flags for compatibility.
* @hide
*/
- public static final int PRIVATE_FLAG_APPEARANCE_CONTROLLED = 0x04000000;
+ public static final int PRIVATE_FLAG_APPEARANCE_CONTROLLED = 1 << 26;
/**
* Flag to indicate that the window is controlling the behavior of system bars. So we don't
* need to adjust it by reading its window flags or system UI flags for compatibility.
* @hide
*/
- public static final int PRIVATE_FLAG_BEHAVIOR_CONTROLLED = 0x08000000;
+ public static final int PRIVATE_FLAG_BEHAVIOR_CONTROLLED = 1 << 27;
/**
* Flag to indicate that the window is controlling how it fits window insets on its own.
* So we don't need to adjust its attributes for fitting window insets.
* @hide
*/
- public static final int PRIVATE_FLAG_FIT_INSETS_CONTROLLED = 0x10000000;
+ public static final int PRIVATE_FLAG_FIT_INSETS_CONTROLLED = 1 << 28;
/**
* Flag to indicate that the window is a trusted overlay.
* @hide
*/
- public static final int PRIVATE_FLAG_TRUSTED_OVERLAY = 0x20000000;
+ public static final int PRIVATE_FLAG_TRUSTED_OVERLAY = 1 << 29;
/**
* Flag to indicate that the parent frame of a window should be inset by IME.
* @hide
*/
- public static final int PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME = 0x40000000;
+ public static final int PRIVATE_FLAG_INSET_PARENT_FRAME_BY_IME = 1 << 30;
/**
* Flag to indicate that we want to intercept and handle global drag and drop for all users.
@@ -3062,7 +3048,7 @@
* @hide
*/
@RequiresPermission(permission.MANAGE_ACTIVITY_TASKS)
- public static final int PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP = 0x80000000;
+ public static final int PRIVATE_FLAG_INTERCEPT_GLOBAL_DRAG_AND_DROP = 1 << 31;
/**
* An internal annotation for flags that can be specified to {@link #softInputMode}.
@@ -3093,7 +3079,6 @@
PRIVATE_FLAG_FORCE_SHOW_STATUS_BAR,
PRIVATE_FLAG_LAYOUT_SIZE_EXTENDED_BY_CUTOUT,
PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY,
- PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH,
PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME,
PRIVATE_FLAG_FORCE_DRAW_BAR_BACKGROUNDS,
PRIVATE_FLAG_SUSTAINED_PERFORMANCE_MODE,
@@ -3169,10 +3154,6 @@
equals = PRIVATE_FLAG_FORCE_DECOR_VIEW_VISIBILITY,
name = "FORCE_DECOR_VIEW_VISIBILITY"),
@ViewDebug.FlagToString(
- mask = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH,
- equals = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH,
- name = "WILL_NOT_REPLACE_ON_RELAUNCH"),
- @ViewDebug.FlagToString(
mask = PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME,
equals = PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME,
name = "LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME"),
@@ -3635,9 +3616,20 @@
/**
* The preferred refresh rate for the window.
* <p>
- * This must be one of the supported refresh rates obtained for the display(s) the window
- * is on. The selected refresh rate will be applied to the display's default mode.
+ * Before API 34, this must be one of the supported refresh rates obtained
+ * for the display(s) the window is on. The selected refresh rate will be
+ * applied to the display's default mode.
* <p>
+ * Starting API 34, this value is not limited to the supported refresh rates
+ * obtained from the display(s) for the window: it can be any refresh rate
+ * the window intends to run at. Any refresh rate can be provided as the
+ * preferred window refresh rate. The OS will select the refresh rate that
+ * best matches the {@link #preferredRefreshRate}.
+ * <p>
+ * Setting this value is the equivalent of calling {@link Surface#setFrameRate} with (
+ * preferred_frame_rate,
+ * {@link Surface#FRAME_RATE_COMPATIBILITY_DEFAULT},
+ * {@link Surface#CHANGE_FRAME_RATE_ONLY_IF_SEAMLESS}).
* This should be used in favor of {@link LayoutParams#preferredDisplayModeId} for
* applications that want to specify the refresh rate, but do not want to specify a
* preference for any other displayMode properties (e.g., resolution).
diff --git a/core/java/android/view/WindowlessWindowManager.java b/core/java/android/view/WindowlessWindowManager.java
index b157ea0..0560caf 100644
--- a/core/java/android/view/WindowlessWindowManager.java
+++ b/core/java/android/view/WindowlessWindowManager.java
@@ -139,7 +139,7 @@
try {
mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
state.mSurfaceControl, state.mParams.flags, state.mParams.privateFlags,
- state.mInputRegion);
+ state.mParams.inputFeatures, state.mInputRegion);
} catch (RemoteException e) {
Log.e(TAG, "Failed to update surface input channel: ", e);
}
@@ -189,12 +189,13 @@
mRealWm.grantInputChannel(displayId,
new SurfaceControl(sc, "WindowlessWindowManager.addToDisplay"),
window, mHostInputToken,
- attrs.flags, attrs.privateFlags, attrs.type, attrs.token,
- mFocusGrantToken, attrs.getTitle().toString(), outInputChannel);
+ attrs.flags, attrs.privateFlags, attrs.inputFeatures, attrs.type,
+ attrs.token, mFocusGrantToken, attrs.getTitle().toString(),
+ outInputChannel);
} else {
mRealWm.grantInputChannel(displayId, sc, window, mHostInputToken, attrs.flags,
- attrs.privateFlags, attrs.type, attrs.token, mFocusGrantToken,
- attrs.getTitle().toString(), outInputChannel);
+ attrs.privateFlags, attrs.inputFeatures, attrs.type, attrs.token,
+ mFocusGrantToken, attrs.getTitle().toString(), outInputChannel);
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to grant input to surface: ", e);
@@ -381,16 +382,19 @@
outMergedConfiguration.setConfiguration(mConfiguration, mConfiguration);
}
- if ((attrChanges & WindowManager.LayoutParams.FLAGS_CHANGED) != 0
- && state.mInputChannelToken != null) {
+ final int inputChangeMask = WindowManager.LayoutParams.FLAGS_CHANGED
+ | WindowManager.LayoutParams.INPUT_FEATURES_CHANGED;
+ if ((attrChanges & inputChangeMask) != 0 && state.mInputChannelToken != null) {
try {
- if(mRealWm instanceof IWindowSession.Stub) {
+ if (mRealWm instanceof IWindowSession.Stub) {
mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId,
new SurfaceControl(sc, "WindowlessWindowManager.relayout"),
- attrs.flags, attrs.privateFlags, state.mInputRegion);
+ attrs.flags, attrs.privateFlags, attrs.inputFeatures,
+ state.mInputRegion);
} else {
mRealWm.updateInputChannel(state.mInputChannelToken, state.mDisplayId, sc,
- attrs.flags, attrs.privateFlags, state.mInputRegion);
+ attrs.flags, attrs.privateFlags, attrs.inputFeatures,
+ state.mInputRegion);
}
} catch (RemoteException e) {
Log.e(TAG, "Failed to update surface input channel: ", e);
@@ -415,10 +419,6 @@
}
@Override
- public void prepareToReplaceWindows(android.os.IBinder appToken, boolean childrenOnly) {
- }
-
- @Override
public boolean outOfMemory(android.view.IWindow window) {
return false;
}
@@ -564,14 +564,14 @@
@Override
public void grantInputChannel(int displayId, SurfaceControl surface, IWindow window,
- IBinder hostInputToken, int flags, int privateFlags, int type,
+ IBinder hostInputToken, int flags, int privateFlags, int inputFeatures, int type,
IBinder windowToken, IBinder focusGrantToken, String inputHandleName,
InputChannel outInputChannel) {
}
@Override
public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
- int flags, int privateFlags, Region region) {
+ int flags, int privateFlags, int inputFeatures, Region region) {
}
@Override
diff --git a/core/java/android/view/autofill/AutofillManager.java b/core/java/android/view/autofill/AutofillManager.java
index 0deaa76..508c20a 100644
--- a/core/java/android/view/autofill/AutofillManager.java
+++ b/core/java/android/view/autofill/AutofillManager.java
@@ -16,6 +16,7 @@
package android.view.autofill;
+import static android.Manifest.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS;
import static android.service.autofill.FillRequest.FLAG_IME_SHOWING;
import static android.service.autofill.FillRequest.FLAG_MANUAL_REQUEST;
import static android.service.autofill.FillRequest.FLAG_PASSWORD_INPUT_TYPE;
@@ -34,6 +35,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.RequiresFeature;
+import android.annotation.RequiresPermission;
import android.annotation.SystemApi;
import android.annotation.SystemService;
import android.annotation.TestApi;
@@ -1641,7 +1643,7 @@
mForAugmentedAutofillOnly = false;
}
- if ((flags & FLAG_SUPPORTS_FILL_DIALOG) != 0) {
+ if ((flags & FLAG_SUPPORTS_FILL_DIALOG) != 0 && view != null) {
flags |= FLAG_RESET_FILL_DIALOG_STATE;
}
@@ -2223,8 +2225,14 @@
* @param executor specifies the thread upon which the callbacks will be invoked.
* @param callback which handles autofill request to provide client's suggestions.
*/
+ @RequiresPermission(PROVIDE_OWN_AUTOFILL_SUGGESTIONS)
public void setAutofillRequestCallback(@NonNull @CallbackExecutor Executor executor,
@NonNull AutofillRequestCallback callback) {
+ if (mContext.checkSelfPermission(PROVIDE_OWN_AUTOFILL_SUGGESTIONS)
+ != PackageManager.PERMISSION_GRANTED) {
+ throw new SecurityException("Requires USE_APP_AUTOFILL permission!");
+ }
+
synchronized (mLock) {
mRequestCallbackExecutor = executor;
mAutofillRequestCallback = callback;
@@ -2940,8 +2948,10 @@
mFillableIds = new ArraySet<>(fillableIds.length);
}
for (AutofillId id : fillableIds) {
- id.resetSessionId();
- mFillableIds.add(id);
+ if (id != null) {
+ id.resetSessionId();
+ mFillableIds.add(id);
+ }
}
}
@@ -2966,8 +2976,10 @@
}
if (trackedIds != null) {
for (AutofillId id : trackedIds) {
- id.resetSessionId();
- allFillableIds.add(id);
+ if (id != null) {
+ id.resetSessionId();
+ allFillableIds.add(id);
+ }
}
}
diff --git a/core/java/android/view/inputmethod/CancellableHandwritingGesture.java b/core/java/android/view/inputmethod/CancellableHandwritingGesture.java
new file mode 100644
index 0000000..3e7974b
--- /dev/null
+++ b/core/java/android/view/inputmethod/CancellableHandwritingGesture.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+import android.annotation.NonNull;
+import android.annotation.TestApi;
+import android.os.CancellationSignal;
+import android.os.CancellationSignalBeamer;
+import android.os.IBinder;
+
+/**
+ * A {@link HandwritingGesture} that can be {@link CancellationSignal#cancel() cancelled}.
+ * @hide
+ */
+@TestApi
+public abstract class CancellableHandwritingGesture extends HandwritingGesture {
+ CancellationSignal mCancellationSignal;
+
+ IBinder mCancellationSignalToken;
+
+ /**
+ * Set {@link CancellationSignal} for testing only.
+ * @hide
+ */
+ @TestApi
+ public void setCancellationSignal(@NonNull CancellationSignal cancellationSignal) {
+ mCancellationSignal = cancellationSignal;
+ }
+
+ CancellationSignal getCancellationSignal() {
+ return mCancellationSignal;
+ }
+
+ void unbeamCancellationSignal(CancellationSignalBeamer.Receiver receiver) {
+ mCancellationSignal = receiver.unbeam(mCancellationSignalToken);
+ mCancellationSignalToken = null;
+ }
+
+}
diff --git a/core/java/android/view/inputmethod/InsertModeGesture.java b/core/java/android/view/inputmethod/InsertModeGesture.java
index 6b9d7fb..1fc56de 100644
--- a/core/java/android/view/inputmethod/InsertModeGesture.java
+++ b/core/java/android/view/inputmethod/InsertModeGesture.java
@@ -20,6 +20,7 @@
import android.annotation.SuppressLint;
import android.graphics.PointF;
import android.os.CancellationSignal;
+import android.os.CancellationSignalBeamer;
import android.os.Parcel;
import android.os.Parcelable;
import android.widget.TextView;
@@ -39,10 +40,9 @@
* {@link CancellationSignal#setOnCancelListener(CancellationSignal.OnCancelListener)} obtained from
* {@link #getCancellationSignal()}.
*/
-public final class InsertModeGesture extends HandwritingGesture implements Parcelable {
+public final class InsertModeGesture extends CancellableHandwritingGesture implements Parcelable {
private PointF mPoint;
- private CancellationSignal mCancellationSignal;
private InsertModeGesture(PointF point, String fallbackText,
CancellationSignal cancellationSignal) {
@@ -56,6 +56,7 @@
mType = GESTURE_TYPE_INSERT_MODE;
mFallbackText = source.readString8();
mPoint = source.readTypedObject(PointF.CREATOR);
+ mCancellationSignalToken = source.readStrongBinder();
}
/**
@@ -64,6 +65,7 @@
* {@link CancellationSignal#cancel()} and toolkit can receive cancel using
* {@link CancellationSignal#setOnCancelListener(CancellationSignal.OnCancelListener)}.
*/
+ @Override
@NonNull
public CancellationSignal getCancellationSignal() {
return mCancellationSignal;
@@ -183,5 +185,6 @@
public void writeToParcel(@NonNull Parcel dest, int flags) {
dest.writeString8(mFallbackText);
dest.writeTypedObject(mPoint, flags);
+ dest.writeStrongBinder(CancellationSignalBeamer.Sender.beamFromScope(mCancellationSignal));
}
}
diff --git a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
index 6f8b422..eb91d08 100644
--- a/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
+++ b/core/java/android/view/inputmethod/RemoteInputConnectionImpl.java
@@ -31,8 +31,9 @@
import android.graphics.RectF;
import android.os.Bundle;
import android.os.CancellationSignal;
+import android.os.CancellationSignalBeamer;
import android.os.Handler;
-import android.os.ICancellationSignal;
+import android.os.IBinder;
import android.os.Looper;
import android.os.ResultReceiver;
import android.os.Trace;
@@ -179,6 +180,8 @@
private final AtomicBoolean mHasPendingImmediateCursorAnchorInfoUpdate =
new AtomicBoolean(false);
+ private CancellationSignalBeamer.Receiver mBeamer;
+
RemoteInputConnectionImpl(@NonNull Looper looper,
@NonNull InputConnection inputConnection,
@NonNull InputMethodManager inputMethodManager, @Nullable View servedView) {
@@ -422,6 +425,22 @@
}
@Override
+ public void cancelCancellationSignal(IBinder token) {
+ if (mBeamer == null) {
+ return;
+ }
+ mBeamer.cancel(token);
+ }
+
+ @Override
+ public void forgetCancellationSignal(IBinder token) {
+ if (mBeamer == null) {
+ return;
+ }
+ mBeamer.forget(token);
+ }
+
+ @Override
public String toString() {
return "RemoteInputConnectionImpl{"
+ "connection=" + getInputConnection()
@@ -988,6 +1007,22 @@
public void performHandwritingGesture(
InputConnectionCommandHeader header, ParcelableHandwritingGesture gestureContainer,
ResultReceiver resultReceiver) {
+ final HandwritingGesture gesture = gestureContainer.get();
+ if (gesture instanceof CancellableHandwritingGesture) {
+ // For cancellable gestures, unbeam and save the CancellationSignal.
+ CancellableHandwritingGesture cancellableGesture =
+ (CancellableHandwritingGesture) gesture;
+ cancellableGesture.unbeamCancellationSignal(getCancellationSignalBeamer());
+ if (cancellableGesture.getCancellationSignal() != null
+ && cancellableGesture.getCancellationSignal().isCanceled()) {
+ // Send result for canceled operations.
+ if (resultReceiver != null) {
+ resultReceiver.send(
+ InputConnection.HANDWRITING_GESTURE_RESULT_CANCELLED, null);
+ }
+ return;
+ }
+ }
dispatchWithTracing("performHandwritingGesture", () -> {
if (header.mSessionId != mCurrentSessionId.get()) {
if (resultReceiver != null) {
@@ -1009,7 +1044,7 @@
// TODO(210039666): implement Cleaner to return HANDWRITING_GESTURE_RESULT_UNKNOWN if
// editor doesn't return any type.
ic.performHandwritingGesture(
- gestureContainer.get(),
+ gesture,
resultReceiver != null ? Runnable::run : null,
resultReceiver != null
? (resultCode) -> resultReceiver.send(resultCode, null /* resultData */)
@@ -1021,10 +1056,11 @@
@Override
public void previewHandwritingGesture(
InputConnectionCommandHeader header, ParcelableHandwritingGesture gestureContainer,
- ICancellationSignal transport) {
+ IBinder cancellationSignalToken) {
+ final CancellationSignal cancellationSignal =
+ cancellationSignalToken != null
+ ? getCancellationSignalBeamer().unbeam(cancellationSignalToken) : null;
- // TODO(b/254727073): Implement CancellationSignal receiver
- final CancellationSignal cancellationSignal = CancellationSignal.fromTransport(transport);
// Previews always use PreviewableHandwritingGesture but if incorrectly wrong class is
// passed, ClassCastException will be sent back to caller.
final PreviewableHandwritingGesture gesture =
@@ -1045,6 +1081,14 @@
});
}
+ private CancellationSignalBeamer.Receiver getCancellationSignalBeamer() {
+ if (mBeamer != null) {
+ return mBeamer;
+ }
+ mBeamer = new CancellationSignalBeamer.Receiver(true /* cancelOnSenderDeath */);
+ return mBeamer;
+ }
+
@Dispatching(cancellable = true)
@Override
public void requestCursorUpdates(InputConnectionCommandHeader header, int cursorUpdateMode,
diff --git a/core/java/android/widget/OWNERS b/core/java/android/widget/OWNERS
index 02dafd4..7f0a651 100644
--- a/core/java/android/widget/OWNERS
+++ b/core/java/android/widget/OWNERS
@@ -13,3 +13,5 @@
per-file SpellChecker.java = file:../view/inputmethod/OWNERS
per-file RemoteViews* = file:../appwidget/OWNERS
+
+per-file Toast.java = juliacr@google.com, jeffdq@google.com
diff --git a/core/java/android/widget/PopupWindow.java b/core/java/android/widget/PopupWindow.java
index c1ec168..d54addb 100644
--- a/core/java/android/widget/PopupWindow.java
+++ b/core/java/android/widget/PopupWindow.java
@@ -19,7 +19,6 @@
import static android.view.ViewGroup.LayoutParams.MATCH_PARENT;
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -1644,8 +1643,7 @@
p.width = mLastWidth = mWidth;
}
- p.privateFlags = PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH
- | PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
+ p.privateFlags = PRIVATE_FLAG_LAYOUT_CHILD_WINDOW_IN_PARENT_FRAME;
// Used for debugging.
p.setTitle("PopupWindow:" + Integer.toHexString(hashCode()));
diff --git a/core/java/android/widget/Toast.java b/core/java/android/widget/Toast.java
index ca57c84..fceee4e 100644
--- a/core/java/android/widget/Toast.java
+++ b/core/java/android/widget/Toast.java
@@ -189,6 +189,9 @@
/**
* Show the view for the specified duration.
+ *
+ * <p>Note that toasts being sent from the background are rate limited, so avoid sending such
+ * toasts in quick succession.
*/
public void show() {
if (Compatibility.isChangeEnabled(CHANGE_TEXT_TOASTS_IN_THE_SYSTEM)) {
diff --git a/core/java/android/window/ITaskOrganizerController.aidl b/core/java/android/window/ITaskOrganizerController.aidl
index 0032b9c..e10f7c8 100644
--- a/core/java/android/window/ITaskOrganizerController.aidl
+++ b/core/java/android/window/ITaskOrganizerController.aidl
@@ -73,11 +73,17 @@
/**
* Controls whether ignore orientation request logic in {@link
- * com.android.server.wm.DisplayArea} is disabled at runtime.
+ * com.android.server.wm.DisplayArea} is disabled at runtime and how to optionally map some
+ * requested orientations to others.
*
* @param isDisabled when {@code true}, the system always ignores the value of {@link
* com.android.server.wm.DisplayArea#getIgnoreOrientationRequest} and app
* requested orientation is respected.
+ * @param fromOrientations The orientations we want to map to the correspondent orientations
+ * in toOrientation.
+ * @param toOrientations The orientations we map to the ones in fromOrientations at the same
+ * index
*/
- void setIsIgnoreOrientationRequestDisabled(boolean isDisabled);
+ void setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled,
+ in int[] fromOrientations, in int[] toOrientations);
}
diff --git a/core/java/android/window/TaskConstants.java b/core/java/android/window/TaskConstants.java
index c403840..3a04198 100644
--- a/core/java/android/window/TaskConstants.java
+++ b/core/java/android/window/TaskConstants.java
@@ -80,14 +80,6 @@
public static final int TASK_CHILD_LAYER_TASK_OVERLAY = 5 * TASK_CHILD_LAYER_REGION_SIZE;
/**
- * Legacy machanism to force an activity to the top of the task (i.e. for work profile
- * comfirmation).
- * @hide
- */
- public static final int TASK_CHILD_LAYER_TASK_OVERLAY_ACTIVITIES =
- 6 * TASK_CHILD_LAYER_REGION_SIZE;
-
- /**
* Z-orders of task child layers other than activities, task fragments and layers interleaved
* with them, e.g. IME windows. [-10000, 10000) is reserved for these layers.
* @hide
@@ -99,8 +91,7 @@
TASK_CHILD_LAYER_LETTERBOX_EDUCATION,
TASK_CHILD_LAYER_WINDOW_DECORATIONS,
TASK_CHILD_LAYER_RECENTS_ANIMATION_PIP_OVERLAY,
- TASK_CHILD_LAYER_TASK_OVERLAY,
- TASK_CHILD_LAYER_TASK_OVERLAY_ACTIVITIES
+ TASK_CHILD_LAYER_TASK_OVERLAY
})
public @interface TaskChildLayer {}
}
diff --git a/core/java/android/window/TaskOrganizer.java b/core/java/android/window/TaskOrganizer.java
index d4728c1..2913faf 100644
--- a/core/java/android/window/TaskOrganizer.java
+++ b/core/java/android/window/TaskOrganizer.java
@@ -267,17 +267,24 @@
/**
* Controls whether ignore orientation request logic in {@link
- * com.android.server.wm.DisplayArea} is disabled at runtime.
+ * com.android.server.wm.DisplayArea} is disabled at runtime and how to optionally map some
+ * requested orientation to others.
*
- * @param isDisabled when {@code true}, the system always ignores the value of {@link
- * com.android.server.wm.DisplayArea#getIgnoreOrientationRequest} and app
- * requested orientation is respected.
+ * @param isIgnoreOrientationRequestDisabled when {@code true}, the system always ignores the
+ * value of {@link com.android.server.wm.DisplayArea#getIgnoreOrientationRequest}
+ * and app requested orientation is respected.
+ * @param fromOrientations The orientations we want to map to the correspondent orientations
+ * in toOrientation.
+ * @param toOrientations The orientations we map to the ones in fromOrientations at the same
+ * index
* @hide
*/
@RequiresPermission(android.Manifest.permission.MANAGE_ACTIVITY_TASKS)
- public void setIsIgnoreOrientationRequestDisabled(boolean isDisabled) {
+ public void setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled,
+ @Nullable int[] fromOrientations, @Nullable int[] toOrientations) {
try {
- mTaskOrganizerController.setIsIgnoreOrientationRequestDisabled(isDisabled);
+ mTaskOrganizerController.setOrientationRequestPolicy(isIgnoreOrientationRequestDisabled,
+ fromOrientations, toOrientations);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/core/java/com/android/internal/app/IAppOpsService.aidl b/core/java/com/android/internal/app/IAppOpsService.aidl
index 88447da..d63611f 100644
--- a/core/java/com/android/internal/app/IAppOpsService.aidl
+++ b/core/java/com/android/internal/app/IAppOpsService.aidl
@@ -81,12 +81,19 @@
void getHistoricalOpsFromDiskRaw(int uid, String packageName, String attributionTag,
in List<String> ops, int historyFlags, int filter, long beginTimeMillis,
long endTimeMillis, int flags, in RemoteCallback callback);
+ @EnforcePermission("MANAGE_APPOPS")
void offsetHistory(long duration);
+ @EnforcePermission("MANAGE_APPOPS")
void setHistoryParameters(int mode, long baseSnapshotInterval, int compressionStep);
+ @EnforcePermission("MANAGE_APPOPS")
void addHistoricalOps(in AppOpsManager.HistoricalOps ops);
+ @EnforcePermission("MANAGE_APPOPS")
void resetHistoryParameters();
+ @EnforcePermission("MANAGE_APPOPS")
void resetPackageOpsNoHistory(String packageName);
+ @EnforcePermission("MANAGE_APPOPS")
void clearHistory();
+ @EnforcePermission("MANAGE_APPOPS")
void rebootHistory(long offlineDurationMillis);
List<AppOpsManager.PackageOps> getUidOps(int uid, in int[] ops);
void setUidMode(int code, int uid, int mode);
diff --git a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
index 813febf..ad0d1a4 100644
--- a/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
+++ b/core/java/com/android/internal/app/IHotwordRecognitionStatusCallback.aidl
@@ -17,9 +17,10 @@
package com.android.internal.app;
import android.hardware.soundtrigger.SoundTrigger;
-import android.service.voice.DetectorFailure;
import android.service.voice.HotwordDetectedResult;
+import android.service.voice.HotwordDetectionServiceFailure;
import android.service.voice.HotwordRejectedResult;
+import android.service.voice.VisualQueryDetectionServiceFailure;
/**
* @hide
@@ -63,11 +64,31 @@
void onError(int status);
/**
- * Called when the detection fails due to an error.
+ * Called when the detection fails due to an error occurs in the
+ * {@link HotwordDetectionService}.
*
- * @param detectorFailure It provides the error code, error message and suggested action.
+ * @param hotwordDetectionServiceFailure It provides the error code, error message and
+ * suggested action.
*/
- void onDetectionFailure(in DetectorFailure detectorFailure);
+ void onHotwordDetectionServiceFailure(
+ in HotwordDetectionServiceFailure hotwordDetectionServiceFailure);
+
+ /**
+ * Called when the detection fails due to an error occurs in the
+ * {@link VisualQueryDetectionService}.
+ *
+ * @param visualQueryDetectionServiceFailure It provides the error code, error message and
+ * suggested action.
+ */
+ void onVisualQueryDetectionServiceFailure(
+ in VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure);
+
+ /**
+ * Called when the detection fails due to an unknown error occurs.
+ *
+ * @param errorMessage It provides the error message.
+ */
+ void onUnknownFailure(in String errorMessage);
/**
* Called when the recognition is paused temporarily for some reason.
diff --git a/core/java/com/android/internal/app/OWNERS b/core/java/com/android/internal/app/OWNERS
index 0d02683..a1d571f 100644
--- a/core/java/com/android/internal/app/OWNERS
+++ b/core/java/com/android/internal/app/OWNERS
@@ -1,4 +1,6 @@
per-file *AppOp* = file:/core/java/android/permission/OWNERS
+per-file UnlaunchableAppActivity.java = file:/core/java/android/app/admin/WorkProfile_OWNERS
+per-file IntentForwarderActivity.java = file:/core/java/android/app/admin/WorkProfile_OWNERS
per-file *Resolver* = file:/packages/SystemUI/OWNERS
per-file *Chooser* = file:/packages/SystemUI/OWNERS
per-file SimpleIconFactory.java = file:/packages/SystemUI/OWNERS
diff --git a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
index 9fae211..2b08a55 100644
--- a/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
+++ b/core/java/com/android/internal/config/sysui/SystemUiSystemPropertiesFlags.java
@@ -74,6 +74,9 @@
public static final Flag OTP_REDACTION =
devFlag("persist.sysui.notification.otp_redaction");
+ /** Gating the removal of sorting-notifications-by-interruptiveness. */
+ public static final Flag NO_SORT_BY_INTERRUPTIVENESS =
+ devFlag("persist.sysui.notification.no_sort_by_interruptiveness");
}
//// == End of flags. Everything below this line is the implementation. == ////
diff --git a/core/java/com/android/internal/expresslog/Counter.java b/core/java/com/android/internal/expresslog/Counter.java
index afdbdc8..4a46d91 100644
--- a/core/java/com/android/internal/expresslog/Counter.java
+++ b/core/java/com/android/internal/expresslog/Counter.java
@@ -36,6 +36,16 @@
}
/**
+ * Increments Telemetry Express Counter metric by 1
+ * @param metricId to log, no-op if metricId is not defined in the TeX catalog
+ * @param uid used as a dimension for the count metric
+ * @hide
+ */
+ public static void logIncrementWithUid(@NonNull String metricId, int uid) {
+ logIncrementWithUid(metricId, uid, 1);
+ }
+
+ /**
* Increments Telemetry Express Counter metric by arbitrary value
* @param metricId to log, no-op if metricId is not defined in the TeX catalog
* @param amount to increment counter
@@ -45,4 +55,17 @@
final long metricIdHash = Utils.hashString(metricId);
FrameworkStatsLog.write(FrameworkStatsLog.EXPRESS_EVENT_REPORTED, metricIdHash, amount);
}
+
+ /**
+ * Increments Telemetry Express Counter metric by arbitrary value
+ * @param metricId to log, no-op if metricId is not defined in the TeX catalog
+ * @param uid used as a dimension for the count metric
+ * @param amount to increment counter
+ * @hide
+ */
+ public static void logIncrementWithUid(@NonNull String metricId, int uid, long amount) {
+ final long metricIdHash = Utils.hashString(metricId);
+ FrameworkStatsLog.write(
+ FrameworkStatsLog.EXPRESS_UID_EVENT_REPORTED, metricIdHash, amount, uid);
+ }
}
diff --git a/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl b/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl
index b375936..baaf99a 100644
--- a/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl
+++ b/core/java/com/android/internal/inputmethod/IRemoteInputConnection.aidl
@@ -18,6 +18,7 @@
import android.graphics.RectF;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.ICancellationSignal;
import android.os.ResultReceiver;
import android.view.KeyEvent;
@@ -94,7 +95,7 @@
in ParcelableHandwritingGesture gesture, in ResultReceiver resultReceiver);
void previewHandwritingGesture(in InputConnectionCommandHeader header,
- in ParcelableHandwritingGesture gesture, in ICancellationSignal transport);
+ in ParcelableHandwritingGesture gesture, in IBinder cancellationSignal);
void setComposingRegion(in InputConnectionCommandHeader header, int start, int end);
@@ -124,4 +125,8 @@
void replaceText(in InputConnectionCommandHeader header, int start, int end, CharSequence text,
int newCursorPosition,in TextAttribute textAttribute);
+
+ void cancelCancellationSignal(in IBinder token);
+ void forgetCancellationSignal(in IBinder token);
+
}
diff --git a/core/java/com/android/internal/jank/EventLogTags.logtags b/core/java/com/android/internal/jank/EventLogTags.logtags
index ad47b81..66ee131 100644
--- a/core/java/com/android/internal/jank/EventLogTags.logtags
+++ b/core/java/com/android/internal/jank/EventLogTags.logtags
@@ -3,7 +3,7 @@
option java_package com.android.internal.jank;
# Marks a request to start tracing a CUJ. Doesn't mean the request was executed.
-37001 jank_cuj_events_begin_request (CUJ Type|1|5),(Unix Time Ns|2|3),(Elapsed Time Ns|2|3),(Uptime Ns|2|3)
+37001 jank_cuj_events_begin_request (CUJ Type|1|5),(Unix Time Ns|2|3),(Elapsed Time Ns|2|3),(Uptime Ns|2|3),(Tag|3)
# Marks a request to end tracing a CUJ. Doesn't mean the request was executed.
37002 jank_cuj_events_end_request (CUJ Type|1|5),(Unix Time Ns|2|3),(Elapsed Time Ns|2|3),(Uptime Time Ns|2|3)
# Marks a request to cancel tracing a CUJ. Doesn't mean the request was executed.
diff --git a/core/java/com/android/internal/jank/InteractionJankMonitor.java b/core/java/com/android/internal/jank/InteractionJankMonitor.java
index 7ae63b1..6344568 100644
--- a/core/java/com/android/internal/jank/InteractionJankMonitor.java
+++ b/core/java/com/android/internal/jank/InteractionJankMonitor.java
@@ -18,6 +18,7 @@
import static android.Manifest.permission.READ_DEVICE_CONFIG;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
+import static android.provider.DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR;
import static com.android.internal.jank.FrameTracker.REASON_CANCEL_NORMAL;
import static com.android.internal.jank.FrameTracker.REASON_CANCEL_TIMEOUT;
@@ -448,17 +449,7 @@
mEnabled = DEFAULT_ENABLED;
final Context context = ActivityThread.currentApplication();
- if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) == PERMISSION_GRANTED) {
- // Post initialization to the background in case we're running on the main thread.
- mWorker.getThreadHandler().post(
- () -> mPropertiesChangedListener.onPropertiesChanged(
- DeviceConfig.getProperties(
- DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR)));
- DeviceConfig.addOnPropertiesChangedListener(
- DeviceConfig.NAMESPACE_INTERACTION_JANK_MONITOR,
- new HandlerExecutor(mWorker.getThreadHandler()),
- mPropertiesChangedListener);
- } else {
+ if (context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG) != PERMISSION_GRANTED) {
if (DEBUG) {
Log.d(TAG, "Initialized the InteractionJankMonitor."
+ " (No READ_DEVICE_CONFIG permission to change configs)"
@@ -467,7 +458,25 @@
+ ", frameTimeThreshold=" + mTraceThresholdFrameTimeMillis
+ ", package=" + context.getPackageName());
}
+ return;
}
+
+ // Post initialization to the background in case we're running on the main thread.
+ mWorker.getThreadHandler().post(
+ () -> {
+ try {
+ mPropertiesChangedListener.onPropertiesChanged(
+ DeviceConfig.getProperties(NAMESPACE_INTERACTION_JANK_MONITOR));
+ DeviceConfig.addOnPropertiesChangedListener(
+ NAMESPACE_INTERACTION_JANK_MONITOR,
+ new HandlerExecutor(mWorker.getThreadHandler()),
+ mPropertiesChangedListener);
+ } catch (SecurityException ex) {
+ Log.d(TAG, "Can't get properties: READ_DEVICE_CONFIG granted="
+ + context.checkCallingOrSelfPermission(READ_DEVICE_CONFIG)
+ + ", package=" + context.getPackageName());
+ }
+ });
}
/**
@@ -581,7 +590,7 @@
final Configuration config = builder.build();
postEventLogToWorkerThread((unixNanos, elapsedNanos, realtimeNanos) -> {
EventLogTags.writeJankCujEventsBeginRequest(
- config.mCujType, unixNanos, elapsedNanos, realtimeNanos);
+ config.mCujType, unixNanos, elapsedNanos, realtimeNanos, config.mTag);
});
final TrackerResult result = new TrackerResult();
final boolean success = config.getHandler().runWithScissors(
diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java
index 076e4e1..85cb15b 100644
--- a/core/java/com/android/internal/os/ZygoteInit.java
+++ b/core/java/com/android/internal/os/ZygoteInit.java
@@ -185,8 +185,13 @@
private static void preloadSharedLibraries() {
Log.i(TAG, "Preloading shared libraries...");
System.loadLibrary("android");
- System.loadLibrary("compiler_rt");
System.loadLibrary("jnigraphics");
+
+ // TODO(b/206676167): This library is only used for renderscript today. When renderscript is
+ // removed, this load can be removed as well.
+ if (!SystemProperties.getBoolean("config.disable_renderscript", false)) {
+ System.loadLibrary("compiler_rt");
+ }
}
native private static void nativePreloadAppProcessHALs();
@@ -716,7 +721,8 @@
} catch (ErrnoException ex) {
throw new RuntimeException("Failed to capget()", ex);
}
- capabilities &= ((long) data[0].effective) | (((long) data[1].effective) << 32);
+ capabilities &= Integer.toUnsignedLong(data[0].effective) |
+ (Integer.toUnsignedLong(data[1].effective) << 32);
/* Hardcoded command line to start the system server */
String[] args = {
diff --git a/core/java/com/android/internal/os/anr/AnrLatencyTracker.java b/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
index 6a61656..096d1cd 100644
--- a/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
+++ b/core/java/com/android/internal/os/anr/AnrLatencyTracker.java
@@ -137,14 +137,14 @@
close();
}
- /** Records the start of ActivityManagerService#dumpStackTraces. */
+ /** Records the start of StackTracesDumpHelper#dumpStackTraces. */
public void dumpStackTracesStarted() {
mDumpStackTracesStartUptime = getUptimeMillis();
Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER,
"dumpStackTraces()");
}
- /** Records the end of ActivityManagerService#dumpStackTraces. */
+ /** Records the end of StackTracesDumpHelper#dumpStackTraces. */
public void dumpStackTracesEnded() {
Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
}
@@ -328,7 +328,7 @@
anrSkipped("appNotResponding");
}
- /** Records a skipped ANR in ActivityManagerService#dumpStackTraces. */
+ /** Records a skipped ANR in StackTracesDumpHelper#dumpStackTraces. */
public void anrSkippedDumpStackTraces() {
anrSkipped("dumpStackTraces");
}
diff --git a/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS b/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
new file mode 100644
index 0000000..7755000
--- /dev/null
+++ b/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
@@ -0,0 +1,3 @@
+# TODO(b/274465475): Migrate LatencyTracker testing to its own module
+marcinoc@google.com
+ilkos@google.com
diff --git a/core/java/com/android/internal/util/LatencyTracker.java b/core/java/com/android/internal/util/LatencyTracker.java
index c808d92..c144503 100644
--- a/core/java/com/android/internal/util/LatencyTracker.java
+++ b/core/java/com/android/internal/util/LatencyTracker.java
@@ -49,6 +49,7 @@
import static com.android.internal.util.LatencyTracker.ActionProperties.TRACE_THRESHOLD_SUFFIX;
import android.Manifest;
+import android.annotation.ElapsedRealtimeLong;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -56,7 +57,6 @@
import android.app.ActivityThread;
import android.content.Context;
import android.os.Build;
-import android.os.ConditionVariable;
import android.os.SystemClock;
import android.os.Trace;
import android.provider.DeviceConfig;
@@ -80,7 +80,7 @@
* Class to track various latencies in SystemUI. It then writes the latency to statsd and also
* outputs it to logcat so these latencies can be captured by tests and then used for dashboards.
* <p>
- * This is currently only in Keyguard so it can be shared between SystemUI and Keyguard, but
+ * This is currently only in Keyguard. It can be shared between SystemUI and Keyguard, but
* eventually we'd want to merge these two packages together so Keyguard can use common classes
* that are shared with SystemUI.
*/
@@ -298,8 +298,6 @@
UIACTION_LATENCY_REPORTED__ACTION__ACTION_SMARTSPACE_DOORBELL,
};
- private static LatencyTracker sLatencyTracker;
-
private final Object mLock = new Object();
@GuardedBy("mLock")
private final SparseArray<Session> mSessions = new SparseArray<>();
@@ -307,20 +305,21 @@
private final SparseArray<ActionProperties> mActionPropertiesMap = new SparseArray<>();
@GuardedBy("mLock")
private boolean mEnabled;
- @VisibleForTesting
- public final ConditionVariable mDeviceConfigPropertiesUpdated = new ConditionVariable();
- public static LatencyTracker getInstance(Context context) {
- if (sLatencyTracker == null) {
- synchronized (LatencyTracker.class) {
- if (sLatencyTracker == null) {
- sLatencyTracker = new LatencyTracker();
- }
- }
- }
- return sLatencyTracker;
+ // Wrapping this in a holder class achieves lazy loading behavior
+ private static final class SLatencyTrackerHolder {
+ private static final LatencyTracker sLatencyTracker = new LatencyTracker();
}
+ public static LatencyTracker getInstance(Context context) {
+ return SLatencyTrackerHolder.sLatencyTracker;
+ }
+
+ /**
+ * Constructor for LatencyTracker
+ *
+ * <p>This constructor is only visible for test classes to inject their own consumer callbacks
+ */
@RequiresPermission(Manifest.permission.READ_DEVICE_CONFIG)
@VisibleForTesting
public LatencyTracker() {
@@ -362,11 +361,8 @@
properties.getInt(actionName + TRACE_THRESHOLD_SUFFIX,
legacyActionTraceThreshold)));
}
- if (DEBUG) {
- Log.d(TAG, "updated action properties: " + mActionPropertiesMap);
- }
+ onDeviceConfigPropertiesUpdated(mActionPropertiesMap);
}
- mDeviceConfigPropertiesUpdated.open();
}
/**
@@ -492,7 +488,7 @@
*/
public void onActionStart(@Action int action, String tag) {
synchronized (mLock) {
- if (!isEnabled()) {
+ if (!isEnabled(action)) {
return;
}
// skip if the action is already instrumenting.
@@ -516,7 +512,7 @@
*/
public void onActionEnd(@Action int action) {
synchronized (mLock) {
- if (!isEnabled()) {
+ if (!isEnabled(action)) {
return;
}
Session session = mSessions.get(action);
@@ -555,6 +551,24 @@
}
/**
+ * Testing API to get the time when a given action was started.
+ *
+ * @param action Action which to retrieve start time from
+ * @return Elapsed realtime timestamp when the action started. -1 if the action is not active.
+ * @hide
+ */
+ @VisibleForTesting
+ @ElapsedRealtimeLong
+ public long getActiveActionStartTime(@Action int action) {
+ synchronized (mLock) {
+ if (mSessions.contains(action)) {
+ return mSessions.get(action).mStartRtc;
+ }
+ return -1;
+ }
+ }
+
+ /**
* Logs an action that has started and ended. This needs to be called from the main thread.
*
* @param action The action to end. One of the ACTION_* values.
@@ -564,6 +578,9 @@
boolean shouldSample;
int traceThreshold;
synchronized (mLock) {
+ if (!isEnabled(action)) {
+ return;
+ }
ActionProperties actionProperties = mActionPropertiesMap.get(action);
if (actionProperties == null) {
return;
@@ -574,28 +591,24 @@
traceThreshold = actionProperties.getTraceThreshold();
}
- if (traceThreshold > 0 && duration >= traceThreshold) {
- PerfettoTrigger.trigger(getTraceTriggerNameForAction(action));
+ boolean shouldTriggerPerfettoTrace = traceThreshold > 0 && duration >= traceThreshold;
+
+ if (DEBUG) {
+ Log.i(TAG, "logAction: " + getNameOfAction(STATSD_ACTION[action])
+ + " duration=" + duration
+ + " shouldSample=" + shouldSample
+ + " shouldTriggerPerfettoTrace=" + shouldTriggerPerfettoTrace);
}
- logActionDeprecated(action, duration, shouldSample);
- }
-
- /**
- * Logs an action that has started and ended. This needs to be called from the main thread.
- *
- * @param action The action to end. One of the ACTION_* values.
- * @param duration The duration of the action in ms.
- * @param writeToStatsLog Whether to write the measured latency to FrameworkStatsLog.
- */
- public static void logActionDeprecated(
- @Action int action, int duration, boolean writeToStatsLog) {
- Log.i(TAG, getNameOfAction(STATSD_ACTION[action]) + " latency=" + duration);
EventLog.writeEvent(EventLogTags.SYSUI_LATENCY, action, duration);
-
- if (writeToStatsLog) {
- FrameworkStatsLog.write(
- FrameworkStatsLog.UI_ACTION_LATENCY_REPORTED, STATSD_ACTION[action], duration);
+ if (shouldTriggerPerfettoTrace) {
+ onTriggerPerfetto(getTraceTriggerNameForAction(action));
+ }
+ if (shouldSample) {
+ onLogToFrameworkStats(
+ new FrameworkStatsLogEvent(action, FrameworkStatsLog.UI_ACTION_LATENCY_REPORTED,
+ STATSD_ACTION[action], duration)
+ );
}
}
@@ -626,23 +639,27 @@
void begin(@NonNull Runnable timeoutAction) {
mStartRtc = SystemClock.elapsedRealtime();
- Trace.asyncTraceBegin(TRACE_TAG_APP, traceName(), 0);
+ Trace.asyncTraceForTrackBegin(TRACE_TAG_APP, traceName(), traceName(), 0);
// start counting timeout.
- mTimeoutRunnable = timeoutAction;
+ mTimeoutRunnable = () -> {
+ Trace.instantForTrack(TRACE_TAG_APP, traceName(), "timeout");
+ timeoutAction.run();
+ };
BackgroundThread.getHandler()
.postDelayed(mTimeoutRunnable, TimeUnit.SECONDS.toMillis(15));
}
void end() {
mEndRtc = SystemClock.elapsedRealtime();
- Trace.asyncTraceEnd(TRACE_TAG_APP, traceName(), 0);
+ Trace.asyncTraceForTrackEnd(TRACE_TAG_APP, traceName(), 0);
BackgroundThread.getHandler().removeCallbacks(mTimeoutRunnable);
mTimeoutRunnable = null;
}
void cancel() {
- Trace.asyncTraceEnd(TRACE_TAG_APP, traceName(), 0);
+ Trace.instantForTrack(TRACE_TAG_APP, traceName(), "cancel");
+ Trace.asyncTraceForTrackEnd(TRACE_TAG_APP, traceName(), 0);
BackgroundThread.getHandler().removeCallbacks(mTimeoutRunnable);
mTimeoutRunnable = null;
}
@@ -653,10 +670,10 @@
}
@VisibleForTesting
- static class ActionProperties {
+ public static class ActionProperties {
static final String ENABLE_SUFFIX = "_enable";
static final String SAMPLE_INTERVAL_SUFFIX = "_sample_interval";
- // TODO: migrate all usages of the legacy trace theshold property
+ // TODO: migrate all usages of the legacy trace threshold property
static final String LEGACY_TRACE_THRESHOLD_SUFFIX = "";
static final String TRACE_THRESHOLD_SUFFIX = "_trace_threshold";
@@ -666,7 +683,8 @@
private final int mSamplingInterval;
private final int mTraceThreshold;
- ActionProperties(
+ @VisibleForTesting
+ public ActionProperties(
@Action int action,
boolean enabled,
int samplingInterval,
@@ -679,20 +697,24 @@
this.mTraceThreshold = traceThreshold;
}
+ @VisibleForTesting
@Action
- int getAction() {
+ public int getAction() {
return mAction;
}
- boolean isEnabled() {
+ @VisibleForTesting
+ public boolean isEnabled() {
return mEnabled;
}
- int getSamplingInterval() {
+ @VisibleForTesting
+ public int getSamplingInterval() {
return mSamplingInterval;
}
- int getTraceThreshold() {
+ @VisibleForTesting
+ public int getTraceThreshold() {
return mTraceThreshold;
}
@@ -705,5 +727,103 @@
+ ", mTraceThreshold=" + mTraceThreshold
+ "}";
}
+
+ @Override
+ public boolean equals(@Nullable Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (o == null) {
+ return false;
+ }
+ if (!(o instanceof ActionProperties)) {
+ return false;
+ }
+ ActionProperties that = (ActionProperties) o;
+ return mAction == that.mAction
+ && mEnabled == that.mEnabled
+ && mSamplingInterval == that.mSamplingInterval
+ && mTraceThreshold == that.mTraceThreshold;
+ }
+
+ @Override
+ public int hashCode() {
+ int _hash = 1;
+ _hash = 31 * _hash + mAction;
+ _hash = 31 * _hash + Boolean.hashCode(mEnabled);
+ _hash = 31 * _hash + mSamplingInterval;
+ _hash = 31 * _hash + mTraceThreshold;
+ return _hash;
+ }
+ }
+
+ /**
+ * Testing method intended to be overridden to determine when the LatencyTracker's device
+ * properties are updated.
+ */
+ @VisibleForTesting
+ public void onDeviceConfigPropertiesUpdated(SparseArray<ActionProperties> actionProperties) {
+ if (DEBUG) {
+ Log.d(TAG, "onDeviceConfigPropertiesUpdated: " + actionProperties);
+ }
+ }
+
+ /**
+ * Testing class intended to be overridden to determine when LatencyTracker triggers perfetto.
+ */
+ @VisibleForTesting
+ public void onTriggerPerfetto(String triggerName) {
+ if (DEBUG) {
+ Log.i(TAG, "onTriggerPerfetto: triggerName=" + triggerName);
+ }
+ PerfettoTrigger.trigger(triggerName);
+ }
+
+ /**
+ * Testing method intended to be overridden to determine when LatencyTracker writes to
+ * FrameworkStatsLog.
+ */
+ @VisibleForTesting
+ public void onLogToFrameworkStats(FrameworkStatsLogEvent event) {
+ if (DEBUG) {
+ Log.i(TAG, "onLogToFrameworkStats: event=" + event);
+ }
+ FrameworkStatsLog.write(event.logCode, event.statsdAction, event.durationMillis);
+ }
+
+ /**
+ * Testing class intended to reject what should be written to the {@link FrameworkStatsLog}
+ *
+ * <p>This class is used in {@link #onLogToFrameworkStats(FrameworkStatsLogEvent)} for test code
+ * to observer when and what information is being logged by {@link LatencyTracker}
+ */
+ @VisibleForTesting
+ public static class FrameworkStatsLogEvent {
+
+ @VisibleForTesting
+ public final int action;
+ @VisibleForTesting
+ public final int logCode;
+ @VisibleForTesting
+ public final int statsdAction;
+ @VisibleForTesting
+ public final int durationMillis;
+
+ private FrameworkStatsLogEvent(int action, int logCode, int statsdAction,
+ int durationMillis) {
+ this.action = action;
+ this.logCode = logCode;
+ this.statsdAction = statsdAction;
+ this.durationMillis = durationMillis;
+ }
+
+ @Override
+ public String toString() {
+ return "FrameworkStatsLogEvent{"
+ + " logCode=" + logCode
+ + ", statsdAction=" + statsdAction
+ + ", durationMillis=" + durationMillis
+ + "}";
+ }
}
}
diff --git a/core/java/com/android/internal/util/OWNERS b/core/java/com/android/internal/util/OWNERS
index 1808bd5..9be8ea7 100644
--- a/core/java/com/android/internal/util/OWNERS
+++ b/core/java/com/android/internal/util/OWNERS
@@ -6,3 +6,4 @@
per-file State* = jchalard@google.com, lorenzo@google.com, satk@google.com
per-file *Dump* = file:/core/java/com/android/internal/util/dump/OWNERS
per-file *Screenshot* = file:/packages/SystemUI/src/com/android/systemui/screenshot/OWNERS
+per-file *LatencyTracker* = file:/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
diff --git a/core/java/com/android/internal/util/ScreenshotHelper.java b/core/java/com/android/internal/util/ScreenshotHelper.java
index 3a393b6..69d3d6a 100644
--- a/core/java/com/android/internal/util/ScreenshotHelper.java
+++ b/core/java/com/android/internal/util/ScreenshotHelper.java
@@ -195,6 +195,8 @@
UserHandle.CURRENT)) {
mScreenshotConnection = conn;
handler.postDelayed(mScreenshotTimeout, timeoutMs);
+ } else {
+ mContext.unbindService(conn);
}
} else {
Messenger messenger = new Messenger(mScreenshotService);
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 739055e..0c3ff6c 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -169,21 +169,25 @@
gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameInterval,
vsyncEventData.frameInterval);
- jobjectArray frameTimelinesObj = reinterpret_cast<jobjectArray>(
- env->GetObjectField(vsyncEventDataObj.get(),
- gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo
- .frameTimelines));
+ ScopedLocalRef<jobjectArray>
+ frameTimelinesObj(env,
+ reinterpret_cast<jobjectArray>(
+ env->GetObjectField(vsyncEventDataObj.get(),
+ gDisplayEventReceiverClassInfo
+ .vsyncEventDataClassInfo
+ .frameTimelines)));
for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
VsyncEventData::FrameTimeline& frameTimeline = vsyncEventData.frameTimelines[i];
- jobject frameTimelineObj = env->GetObjectArrayElement(frameTimelinesObj, i);
- env->SetLongField(frameTimelineObj,
+ ScopedLocalRef<jobject>
+ frameTimelineObj(env, env->GetObjectArrayElement(frameTimelinesObj.get(), i));
+ env->SetLongField(frameTimelineObj.get(),
gDisplayEventReceiverClassInfo.frameTimelineClassInfo.vsyncId,
frameTimeline.vsyncId);
- env->SetLongField(frameTimelineObj,
+ env->SetLongField(frameTimelineObj.get(),
gDisplayEventReceiverClassInfo.frameTimelineClassInfo
.expectedPresentationTime,
frameTimeline.expectedPresentationTime);
- env->SetLongField(frameTimelineObj,
+ env->SetLongField(frameTimelineObj.get(),
gDisplayEventReceiverClassInfo.frameTimelineClassInfo.deadline,
frameTimeline.deadlineTimestamp);
}
diff --git a/core/proto/android/server/windowmanagertransitiontrace.proto b/core/proto/android/server/windowmanagertransitiontrace.proto
index ab87384..9e53a91 100644
--- a/core/proto/android/server/windowmanagertransitiontrace.proto
+++ b/core/proto/android/server/windowmanagertransitiontrace.proto
@@ -36,8 +36,10 @@
MAGIC_NUMBER_H = 0x45434152; /* RACE (little-endian ASCII) */
}
- required fixed64 magic_number = 1; /* Must be the first field, set to value in MagicNumber */
- repeated Transition sent_transitions = 2;
+ // Must be the first field, set to value in MagicNumber
+ required fixed64 magic_number = 1;
+ // Transitions that don't have a finish time are considered aborted
+ repeated Transition finished_transitions = 2;
// Additional debugging info only collected and dumped when explicitly requested to trace
repeated TransitionState transition_states = 3;
@@ -50,7 +52,9 @@
required uint64 finish_transaction_id = 3;
required int64 create_time_ns = 4;
required int64 send_time_ns = 5;
- repeated Target targets = 6;
+ optional int64 finish_time_ns = 6; // consider aborted if not provided
+ required int32 type = 7;
+ repeated Target targets = 8;
}
message Target {
diff --git a/core/res/AndroidManifest.xml b/core/res/AndroidManifest.xml
index 479ea4e..5b43d62 100644
--- a/core/res/AndroidManifest.xml
+++ b/core/res/AndroidManifest.xml
@@ -824,6 +824,9 @@
<protected-broadcast android:name="android.companion.virtual.action.VIRTUAL_DEVICE_REMOVED" />
<protected-broadcast android:name="com.android.internal.intent.action.FLASH_NOTIFICATION_START_PREVIEW" />
<protected-broadcast android:name="com.android.internal.intent.action.FLASH_NOTIFICATION_STOP_PREVIEW" />
+ <protected-broadcast android:name="android.app.admin.action.DEVICE_FINANCING_STATE_CHANGED" />
+ <protected-broadcast android:name="android.app.admin.action.DEVICE_POLICY_SET_RESULT" />
+ <protected-broadcast android:name="android.app.admin.action.DEVICE_POLICY_CHANGED" />
<!-- ====================================================================== -->
<!-- RUNTIME PERMISSIONS -->
@@ -4035,8 +4038,7 @@
android:description="@string/permdesc_setWallpaperHints"
android:protectionLevel="normal" />
- <!-- Allow the app to read the system wallpaper image without
- holding the READ_EXTERNAL_STORAGE permission.
+ <!-- Allow the app to read the system and lock wallpaper images.
<p>Not for use by third-party applications.
@hide
@SystemApi
@@ -4480,6 +4482,12 @@
<permission android:name="android.permission.PROVIDE_DEFAULT_ENABLED_CREDENTIAL_SERVICE"
android:protectionLevel="signature|privileged" />
+ <!-- Allows specifying candidate credential providers to be queried in Credential Manager
+ get flows, or to be preferred as a default in the Credential Manager create flows.
+ <p>Protection level: normal -->
+ <permission android:name="android.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS"
+ android:protectionLevel="normal" />
+
<!-- Allows a browser to invoke credential manager APIs on behalf of another RP.
<p>Protection level: normal -->
<permission android:name="android.permission.CREDENTIAL_MANAGER_SET_ORIGIN"
@@ -5303,12 +5311,12 @@
{@link android.Manifest.permission#USE_EXACT_ALARM} once it targets API
{@link android.os.Build.VERSION_CODES#TIRAMISU}. All apps using exact alarms for secondary
features (which should still be user facing) should continue using this permission.
- <p>Protection level: appop
+ <p>Protection level: signature|privileged|appop
-->
<permission android:name="android.permission.SCHEDULE_EXACT_ALARM"
android:label="@string/permlab_schedule_exact_alarm"
android:description="@string/permdesc_schedule_exact_alarm"
- android:protectionLevel="normal|appop"/>
+ android:protectionLevel="signature|privileged|appop"/>
<!-- Allows apps to use exact alarms just like with {@link
android.Manifest.permission#SCHEDULE_EXACT_ALARM} but without needing to request this
@@ -5421,6 +5429,15 @@
<permission android:name="android.permission.INSTALL_DPC_PACKAGES"
android:protectionLevel="signature|role" />
+ <!-- @SystemApi Allows an application to read resolved paths to the APKs (Base and any splits)
+ of a session based install.
+ <p>Not for use by third-party applications.
+ @hide
+ -->
+ <permission android:name="android.permission.READ_INSTALLED_SESSION_PATHS"
+ android:protectionLevel="signature|installer" />
+ <uses-permission android:name="android.permission.READ_INSTALLED_SESSION_PATHS" />
+
<!-- Allows an application to use System Data Loaders.
<p>Not for use by third-party applications.
@hide
@@ -7433,6 +7450,13 @@
<permission android:name="android.permission.EXECUTE_APP_ACTION"
android:protectionLevel="internal|role" />
+ <!-- Allows an application to display its suggestions using the autofill framework.
+ <p>For now, this permission is only granted to the Browser application.
+ <p>Protection level: internal|role
+ -->
+ <permission android:name="android.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS"
+ android:protectionLevel="internal|role" />
+
<!-- @SystemApi Allows an application to create virtual devices in VirtualDeviceManager.
@hide -->
<permission android:name="android.permission.CREATE_VIRTUAL_DEVICE"
diff --git a/core/res/TEST_MAPPING b/core/res/TEST_MAPPING
index 9185bae..4d09076 100644
--- a/core/res/TEST_MAPPING
+++ b/core/res/TEST_MAPPING
@@ -1,13 +1,13 @@
{
"presubmit": [
{
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.PermissionPolicyTest#platformPermissionPolicyIsUnaltered"
+ "include-filter": "android.permissionpolicy.cts.PermissionPolicyTest#platformPermissionPolicyIsUnaltered"
},
{
- "include-filter": "android.permission2.cts.RuntimePermissionProperties"
+ "include-filter": "android.permissionpolicy.cts.RuntimePermissionProperties"
}
]
}
diff --git a/core/res/res/layout/notification_expand_button.xml b/core/res/res/layout/notification_expand_button.xml
index e752431..8eae064 100644
--- a/core/res/res/layout/notification_expand_button.xml
+++ b/core/res/res/layout/notification_expand_button.xml
@@ -19,23 +19,28 @@
android:id="@+id/expand_button"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_header_height"
android:layout_gravity="top|end"
android:contentDescription="@string/expand_button_content_description_collapsed"
- android:padding="16dp"
+ android:paddingHorizontal="16dp"
>
<LinearLayout
android:id="@+id/expand_button_pill"
android:layout_width="wrap_content"
- android:layout_height="@dimen/notification_expand_button_pill_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_expand_button_pill_height"
android:orientation="horizontal"
android:background="@drawable/expand_button_pill_bg"
+ android:gravity="center_vertical"
+ android:layout_gravity="center_vertical"
>
<TextView
android:id="@+id/expand_button_number"
android:layout_width="wrap_content"
- android:layout_height="@dimen/notification_expand_button_pill_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_expand_button_pill_height"
android:textAppearance="@style/TextAppearance.DeviceDefault.Notification.Info"
android:gravity="center_vertical"
android:paddingStart="8dp"
diff --git a/core/res/res/layout/notification_template_material_base.xml b/core/res/res/layout/notification_template_material_base.xml
index fd787f6..16a8bb7 100644
--- a/core/res/res/layout/notification_template_material_base.xml
+++ b/core/res/res/layout/notification_template_material_base.xml
@@ -79,7 +79,8 @@
<NotificationTopLineView
android:id="@+id/notification_top_line"
android:layout_width="wrap_content"
- android:layout_height="@dimen/notification_headerless_line_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_headerless_line_height"
android:clipChildren="false"
android:theme="@style/Theme.DeviceDefault.Notification"
>
diff --git a/core/res/res/layout/notification_template_material_call.xml b/core/res/res/layout/notification_template_material_call.xml
index 1b3bd26..76bcc96 100644
--- a/core/res/res/layout/notification_template_material_call.xml
+++ b/core/res/res/layout/notification_template_material_call.xml
@@ -29,7 +29,8 @@
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="88dp"
+ android:layout_height="wrap_content"
+ android:minHeight="88dp"
android:orientation="horizontal"
>
@@ -41,6 +42,7 @@
android:layout_marginStart="@dimen/conversation_content_start"
android:orientation="vertical"
android:minHeight="68dp"
+ android:paddingBottom="@dimen/notification_headerless_margin_twoline"
>
<include
@@ -49,7 +51,10 @@
android:layout_height="wrap_content"
/>
- <include layout="@layout/notification_template_text" />
+ <include layout="@layout/notification_template_text"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_text_height"
+ />
</LinearLayout>
diff --git a/core/res/res/layout/notification_template_material_media.xml b/core/res/res/layout/notification_template_material_media.xml
index 95ddc2e..df32d30 100644
--- a/core/res/res/layout/notification_template_material_media.xml
+++ b/core/res/res/layout/notification_template_material_media.xml
@@ -19,7 +19,8 @@
android:id="@+id/status_bar_latest_event_content"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
- android:layout_height="@dimen/notification_min_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_min_height"
android:tag="media"
>
@@ -77,7 +78,8 @@
<NotificationTopLineView
android:id="@+id/notification_top_line"
android:layout_width="wrap_content"
- android:layout_height="@dimen/notification_headerless_line_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_headerless_line_height"
android:clipChildren="false"
android:theme="@style/Theme.DeviceDefault.Notification"
>
diff --git a/core/res/res/layout/notification_template_material_messaging.xml b/core/res/res/layout/notification_template_material_messaging.xml
index bef1d0b..3e82bd1 100644
--- a/core/res/res/layout/notification_template_material_messaging.xml
+++ b/core/res/res/layout/notification_template_material_messaging.xml
@@ -102,7 +102,8 @@
<NotificationTopLineView
android:id="@+id/notification_top_line"
android:layout_width="wrap_content"
- android:layout_height="@dimen/notification_headerless_line_height"
+ android:layout_height="wrap_content"
+ android:minHeight="@dimen/notification_headerless_line_height"
android:layout_marginStart="@dimen/notification_content_margin_start"
android:clipChildren="false"
android:theme="@style/Theme.DeviceDefault.Notification"
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index f78844f..262fb6f 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi-oproepe"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Af"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Bel oor Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Bel oor mobiele netwerk"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Kies invoermetode"</string>
<string name="show_ime" msgid="6406112007347443383">"Hou dit op die skerm terwyl fisieke sleutelbord aktief is"</string>
<string name="hardware" msgid="1800597768237606953">"Wys virtuele sleutelbord"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Stel <xliff:g id="DEVICE_NAME">%s</xliff:g> op"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Stel fisieke sleutelborde op"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tik om taal en uitleg te kies"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Gehoortoestelle"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aangeskakel."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Het volumesleutels ingehou. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> is afgeskakel"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Los die volumesleutels. Druk en hou albei volumesleutels weer 3 sekondes lank in om <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aan te skakel."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Kies \'n kenmerk om te gebruik wanneer jy op die toeganklikheidknoppie tik:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Kies \'n kenmerk om te gebruik saam met die toeganklikheidgebaar (swiep met twee vingers op van die onderkant van die skerm af):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Kies \'n kenmerk om te gebruik saam met die toeganklikheidgebaar (swiep met drie vingers op van die onderkant van die skerm af):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruik tans albei skerms om inhoud te wys"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Toestel is te warm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dubbelskerm is nie beskikbaar nie omdat jou foon tans te warm word"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Skakel af"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> is opgestel"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Sleutelborduitleg is gestel op <xliff:g id="LAYOUT_1">%s</xliff:g>. Tik om te verander."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Sleutelborduitleg is gestel op <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Tik om te verander."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Sleutelborduitleg is gestel op <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Tik om te verander."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Sleutelborduitleg is gestel op <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> … Tik om dit te verander."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fisieke sleutelborde is opgestel"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tik om sleutelborde te bekyk"</string>
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 12c25eb..aa01323 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"የWi-Fi ጥሪ"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ጠፍቷል"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"በ Wi-Fi በኩል ደውል"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"ከተንቀሳቃሽ ስልክ አውታረ መረብ በኩል ደውል"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"የግቤት ስልት ምረጥ"</string>
<string name="show_ime" msgid="6406112007347443383">"አካላዊ የቁልፍ ሰሌዳ ገቢር ሆኖ ሳለ በማያ ገጽ ላይ አቆየው"</string>
<string name="hardware" msgid="1800597768237606953">"ምናባዊ የቁልፍ ሰሌዳን አሳይ"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>ን ያዋቅሩ"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"አካላዊ የቁልፍ ሰሌዳዎችን ያዋቅሩ"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ቋንቋ እና አቀማመጥን ለመምረጥ መታ ያድርጉ"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"የመስሚያ መሣሪያዎች"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> በርቷል።"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"የድምፅ ቁልፎችን ይዟል። <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ጠፍተዋል።"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"የድምጽ መጠን ቁልፎቹን ይልቀቁ። <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ን ለማብራት ሁለቱንም የድምጽ መጠን ቁልፎች በድጋሚ ለ3 ሰከንዶች ተጭነው ይያዙ።"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"የተደራሽነት አዝራርን መታ በሚያደርጉበት ጊዜ ጥቅም ላይ የሚውለውን ባሕሪ ይምረጡ፦"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ከተደራሽነት ጣት ምልክት ጋር የሚጠቀሙበት ባሕሪ ይምረጡ (በሁለት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ከተደራሽነት ጣት ምልክት ጋር አብረው የሚጠቀሙበት ባሕሪ ይምረጡ (በሦስት ጣቶች ከማያ ገጹ ግርጌ ወደ ላይ ይጥረጉ)፦"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ይዘትን ለማሳየት ሁለቱንም ማሳያዎች እየተጠቀመ ነው"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"መሣሪያ በጣም ሞቋል"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ስልክዎ በጣም እየሞቀ ስለሆነ ባለሁለት ማያ ገጽ አይገኝም"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"አጥፋ"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ተዋቅሯል"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"የቁልፍ ሰሌዳ ወደ <xliff:g id="LAYOUT_1">%s</xliff:g> ተቀናብሯል። ለመለወጥ መታ ያድርጉ።"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"የቁልፍ ሰሌዳ አቀማመጥ ወደ <xliff:g id="LAYOUT_1">%1$s</xliff:g>፣ <xliff:g id="LAYOUT_2">%2$s</xliff:g> ተቀናብሯል። ለመለወጥ መታ ያድርጉ።"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"የቁልፍ ሰሌዳ አቀማመጥ ወደ <xliff:g id="LAYOUT_1">%1$s</xliff:g>፣ <xliff:g id="LAYOUT_2">%2$s</xliff:g>፣ <xliff:g id="LAYOUT_3">%3$s</xliff:g> ተቀናብሯል። ለመለወጥ መታ ያድርጉ።"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"የቁልፍ ሰሌዳ አቀማመጥ ወደ <xliff:g id="LAYOUT_1">%1$s</xliff:g>፣ <xliff:g id="LAYOUT_2">%2$s</xliff:g>፣ <xliff:g id="LAYOUT_3">%3$s</xliff:g> ተቀናብሯል… ለመቀጠል መታ ያድርጉ።"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"የተዋቀሩ አካላዊ የቁልፍ ሰሌዳዎች"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"የቁልፍ ሰሌዳዎችን ለማየት መታ ያድርጉ"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index 6443401..ce47a3e 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -144,6 +144,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"الاتصال عبر WiFi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"غير مفعّل"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"الاتصال عبر Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"الاتصال عبر شبكة الجوّال"</string>
@@ -1397,10 +1399,8 @@
<string name="select_input_method" msgid="3971267998568587025">"اختيار أسلوب الإدخال"</string>
<string name="show_ime" msgid="6406112007347443383">"استمرار عرضها على الشاشة أثناء نشاط لوحة المفاتيح الفعلية"</string>
<string name="hardware" msgid="1800597768237606953">"إظهار لوحة المفاتيح الافتراضية"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"إعداد <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"إعداد لوحات المفاتيح الخارجية"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"انقر لاختيار لغة وتنسيق"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789 أ ب ت ث ج ح خ د ذ ر ز س ش ص ض ط ظ ع غ ف ق ك ل م ن ه و ي"</string>
@@ -1725,8 +1725,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"سماعات الأذن الطبية"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم تفعيل <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"تم الضغط مع الاستمرار على مفتاحَي التحكّم في مستوى الصوت. تم إيقاف <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ارفع إصبعَيك عن مفتاحَي مستوى الصوت. لتفعيل خدمة \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"، اضغط مع الاستمرار على كلا مفتاحَي مستوى الصوت مجددًا لمدة 3 ثوانٍ."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"يمكنك اختيار إحدى الميزات لاستخدامها عند النقر على زر أدوات تمكين الوصول:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"يمكنك اختيار إحدى الميزات لاستخدامها مع إيماءة أدوات تمكين الوصول (مرّر سريعًا إلى الأعلى من أسفل الشاشة باستخدام إصبعين):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"يمكنك اختيار إحدى الميزات التالية لاستخدامها مع إيماءة أدوات تمكين الوصول (مرّر سريعًا إلى الأعلى من أسفل الشاشة باستخدام ثلاثة أصابع):"</string>
@@ -2330,19 +2329,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"يستخدم \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" كلتا الشاشتين لعرض المحتوى."</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"الجهاز ساخن للغاية"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ميزة \"استخدام الشاشتين\" غير متاحة لأن هاتفك ساخن للغاية."</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"إيقاف"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"تم ضبط \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\""</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"تم ضبط تنسيق لوحة المفاتيح على <xliff:g id="LAYOUT_1">%s</xliff:g>. انقر لتغيير الإعدادات."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"تم ضبط تنسيق لوحة المفاتيح على <xliff:g id="LAYOUT_1">%1$s</xliff:g> و<xliff:g id="LAYOUT_2">%2$s</xliff:g>. انقر لتغيير الإعدادات."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"تم ضبط تنسيق لوحة المفاتيح على <xliff:g id="LAYOUT_1">%1$s</xliff:g> و<xliff:g id="LAYOUT_2">%2$s</xliff:g> و<xliff:g id="LAYOUT_3">%3$s</xliff:g>. انقر لتغيير الإعدادات."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"تم ضبط تنسيق لوحة المفاتيح على <xliff:g id="LAYOUT_1">%1$s</xliff:g> و<xliff:g id="LAYOUT_2">%2$s</xliff:g> و<xliff:g id="LAYOUT_3">%3$s</xliff:g>… انقر لتغييره."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"تم إعداد لوحات المفاتيح الخارجية"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"انقر لعرض لوحات المفاتيح."</string>
</resources>
diff --git a/core/res/res/values-as/strings.xml b/core/res/res/values-as/strings.xml
index 3d1a7b3..07a578b 100644
--- a/core/res/res/values-as/strings.xml
+++ b/core/res/res/values-as/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"ৱাই-ফাই"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"ৱাই-ফাই কলিং"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"অফ হৈ আছে"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"ৱাই-ফাইৰ জৰিয়তে কল কৰক"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"ম’বাইল নেটৱৰ্কৰ জৰিয়তে কল কৰক"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ইনপুট পদ্ধতি বাছনি কৰক"</string>
<string name="show_ime" msgid="6406112007347443383">"কায়িক কীব’ৰ্ড সক্ৰিয় হৈ থাকোঁতে ইয়াক স্ক্ৰীনত ৰাখক"</string>
<string name="hardware" msgid="1800597768237606953">"ভাৰ্শ্বুৱল কীব\'ৰ্ড দেখুৱাওক"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> কনফিগাৰ কৰক"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ভৌতিক কীব’ৰ্ড কনফিগাৰ কৰক"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ভাষা আৰু চানেকি বাছনি কৰিবলৈ ইয়াত টিপক"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"শুনাৰ ডিভাইচ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কীসমূহ ধৰি ৰাখক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰা হ\'ল।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধৰি ৰাখিছিল। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অফ কৰা হ\'ল।"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম কী এৰি দিয়ক। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> অন কৰিবলৈ, দুয়োটা ভলিউম কী পুনৰ ৩ ছেকেণ্ডৰ বাবে টিপি হেঁচি ৰাখক।"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"আপুনি সাধ্য-সুবিধাৰ বুটামটো টিপিলে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"সাধ্য-সুবিধাৰ নির্দেশৰ জৰিয়তে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক (দুটা আঙুলিৰে স্ক্রীনখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"সাধ্য-সুবিধাৰ নির্দেশৰ জৰিয়তে ব্যৱহাৰ কৰিবলৈ এটা সুবিধা বাছনি কৰক (তিনিটা আঙুলিৰে স্ক্রীনখনৰ একেবাৰে তলিৰ পৰা ওপৰলৈ ছোৱাইপ কৰক):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ সমল দেখুৱাবলৈ দুয়োখন ডিছপ্লে’ ব্যৱহাৰ কৰি আছে"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ডিভাইচটো অতি বেছি গৰম হৈছে"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"আপোনাৰ ফ’নটো অতি বেছি গৰম হোৱাৰ বাবে ডুৱেল স্ক্ৰীন উপলব্ধ নহয়"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"অফ কৰক"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> কনফিগাৰ কৰা হৈছে"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"কীব’ৰ্ডৰ লে’আউট <xliff:g id="LAYOUT_1">%s</xliff:g> হিচাপে ছেট কৰা হৈছে। সলনি কৰিবলৈ টিপক।"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"কীব’ৰ্ডৰ লে’আউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> হিচাপে ছেট কৰা হৈছে। সলনি কৰিবলৈ টিপক।"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"কীব’ৰ্ডৰ লে’আউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> হিচাপে ছেট কৰা হৈছে। সলনি কৰিবলৈ টিপক।"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"কীব’ৰ্ডৰ লে’আউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> হিচাপে ছেট কৰা হৈছে… সলনি কৰিবলৈ টিপক।"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ভৌতিক কীব’ৰ্ড কনফিগাৰ কৰা হৈছে"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"কীব’ৰ্ড চাবলৈ টিপক"</string>
</resources>
diff --git a/core/res/res/values-az/strings.xml b/core/res/res/values-az/strings.xml
index c8443b9..a843c7c 100644
--- a/core/res/res/values-az/strings.xml
+++ b/core/res/res/values-az/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi Zəngi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Deaktiv"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi ilə zəng edin"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Mobil şəbəkə ilə zəng edin"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Daxiletmə metodunu seçin"</string>
<string name="show_ime" msgid="6406112007347443383">"Fiziki klaviatura aktiv olanda görünsün"</string>
<string name="hardware" msgid="1800597768237606953">"Virtual klaviaturanı göstərin"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> cihazını konfiqurasiya edin"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fiziki klaviaturaları konfiqurasiya edin"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dil və tərtibatı seçmək üçün tıklayın"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCÇDEƏFGĞHXIİJKQLMNOÖPRSŞTUÜVYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCÇDEƏFGĞHİIJKLMNOÖPQRSŞTUÜVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Eşitmə cihazları"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Səs səviyyəsi düymələrinə basıb saxlayın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktiv edildi."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Səs səviyyəsi düymələrinə basılaraq saxlanıb. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> deaktiv edilib."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Səs düymələrini buraxın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xidmətini aktiv etmək üçün hər iki səs düyməsinə yenidən 3 saniyə basıb saxlayın."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Xüsusi imkanlar düyməsinə toxunanda istədiyiniz funksiyanı seçin:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Əlçatımlılıq jesti (iki barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə edəcəyiniz funksiyanı seçin:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Əlçatımlılıq jesti (üç barmağınızla ekranın aşağısından yuxarı doğru sürüşdürün) ilə istifadə edəcəyiniz funksiyanı seçin:"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> məzmunu göstərmək üçün hər iki displeydən istifadə edir"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Cihaz çox isinib"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Telefonunuz çox isindiyi üçün İkili Ekran əlçatan deyil"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Deaktiv edin"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> konfiqurasiya edilib"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Klaviatura düzəni <xliff:g id="LAYOUT_1">%s</xliff:g> kimi ayarlanıb. Dəyişmək üçün toxunun."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Klaviatura düzəni <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> kimi ayarlanıb. Dəyişmək üçün toxunun."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Klaviatura düzəni <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> kimi ayarlanıb. Dəyişmək üçün toxunun."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klaviatura düzəni <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> kimi ayarlanıb… Dəyişmək üçün toxunun."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fiziki klaviaturalar konfiqurasiya edilib"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klaviaturalara baxmaq üçün toxunun"</string>
</resources>
diff --git a/core/res/res/values-b+sr+Latn/strings.xml b/core/res/res/values-b+sr+Latn/strings.xml
index a5575e6..7b99842 100644
--- a/core/res/res/values-b+sr+Latn/strings.xml
+++ b/core/res/res/values-b+sr+Latn/strings.xml
@@ -141,6 +141,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Pozivanje preko WiFi-a"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Isključeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Pozivanje preko WiFi-a"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Poziv preko mobilne mreže"</string>
@@ -1394,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Izbor metoda unosa"</string>
<string name="show_ime" msgid="6406112007347443383">"Zadržava se na ekranu dok je fizička tastatura aktivna"</string>
<string name="hardware" msgid="1800597768237606953">"Prikaži virtuelnu tastaturu"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurišite uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurišite fizičke tastature"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite da biste izabrali jezik i raspored"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tastere za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tastere za jačinu zvuka. Da biste uključili <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite oba tastera za jačinu zvuka 3 sekunde."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću dva prsta prevucite nagore od dna ekrana):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite funkciju koja će se koristiti pomoću pokreta za pristupačnost (pomoću tri prsta prevucite nagore od dna ekrana):"</string>
@@ -2327,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> koristi oba ekrana za prikazivanje sadržaja"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Uređaj je previše zagrejan"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvojni ekran je nedostupan jer je telefon previše zagrejan"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Isključi"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g> je konfigurisan"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Raspored tastature je podešen na <xliff:g id="LAYOUT_1">%s</xliff:g>. Dodirnite da biste to promenili."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Raspored tastature je podešen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Dodirnite da biste to promenili."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Raspored tastature je podešen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Dodirnite da biste to promenili."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Raspored tastature je podešen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Dodirnite da biste promenili."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizičke tastature su konfigurisane"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Dodirnite da biste videli tastature"</string>
</resources>
diff --git a/core/res/res/values-be/strings.xml b/core/res/res/values-be/strings.xml
index 9c17d06..080bf2c 100644
--- a/core/res/res/values-be/strings.xml
+++ b/core/res/res/values-be/strings.xml
@@ -142,6 +142,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi-тэлефанія"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWi-Fi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Выкл."</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Выклікаць праз Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Выклікаць праз мабільную сетку"</string>
@@ -1395,10 +1397,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Выберыце метад уводу"</string>
<string name="show_ime" msgid="6406112007347443383">"Захоўваць яе на экране ў той час, калі фізічная клавіятура актыўная"</string>
<string name="hardware" msgid="1800597768237606953">"Паказаць віртуальную клавіятуру"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Наладзьце прыладу \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\""</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Наладзьце фізічныя клавіятуры"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Дакраніцеся, каб выбраць мову і раскладку"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" АБВГДЕЁЖЗІЙКЛМНОПРСТУЎФХЦЧШ\'ЫЬЭЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1723,8 +1723,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слыхавыя апараты"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Клавішы гучнасці ўтрымліваліся націснутымі. Уключана служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Клавішы гучнасці ўтрымліваліся націснутымі. Служба \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" выключана."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Адпусціце клавішы гучнасці. Каб уключыць сэрвіс \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\", націсніце абедзве клавішы гучнасці яшчэ раз і ўтрымлівайце іх на працягу 3 секунд."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Выберыце функцыю, якую будзеце выкарыстоўваць пры націску кнопкі спецыяльных магчымасцей:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Выберыце функцыю, якую будзеце выкарыстоўваць з жэстам спецыяльных магчымасцей (правесці двума пальцамі па экране знізу ўверх):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Выберыце функцыю, якую будзеце выкарыстоўваць з жэстам спецыяльных магчымасцей (правесці трыма пальцамі па экране знізу ўверх):"</string>
@@ -2328,19 +2327,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" выкарыстоўвае абодва экраны для паказу змесціва"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Прылада моцна нагрэлася"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Функцыя \"Двайны экран\" недаступная, бо тэлефон моцна награваецца"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Выключыць"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Прылада \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\" наладжана"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Раскладка клавіятуры наладжана для мовы \"<xliff:g id="LAYOUT_1">%s</xliff:g>\". Націсніце, каб змяніць."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Раскладка клавіятуры наладжана для наступных моў: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Націсніце, каб змяніць."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Раскладка клавіятуры наладжана для наступных моў: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Націсніце, каб змяніць."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Раскладка клавіятуры наладжана для наступных моў: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Націсніце, каб змяніць."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Фізічныя клавіятуры наладжаны"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Націсніце, каб праглядзець клавіятуры"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index a07e04e..b2abe40 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Обаждания през Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Изключено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Обаждане през Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Обаждане през мобилна мрежа"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Избор на метод на въвеждане"</string>
<string name="show_ime" msgid="6406112007347443383">"Показване на екрана, докато физическата клавиатура е активна"</string>
<string name="hardware" msgid="1800597768237606953">"Показване на вирт. клавиатура"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Конфигуриране на <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Конфигуриране на физически клавиатури"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Докоснете, за да изберете език и подредба"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слухови апарати"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е включена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Задържахте бутоните за силата на звука. Услугата <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е изключена."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Освободете бутоните за силата на звука. За да включите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, отново натиснете двата бутона за силата на звука и задръжте за 3 секунди."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изберете функция, която да използвате, когато докоснете бутона за достъпност:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Изберете коя функция да се използва с жеста за достъпност (прекарване на два пръста нагоре от долната част на екрана):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Изберете коя функция да се използва с жеста за достъпност (прекарване на три пръста нагоре от долната част на екрана):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Приложението <xliff:g id="APP_NAME">%1$s</xliff:g> използва и двата екрана, за да показва съдържание"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Устройството е твърде топло"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Функцията за двоен екран не е налице, защото телефонът ви е твърде топъл"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Изключване"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Устройството <xliff:g id="DEVICE_NAME">%s</xliff:g> е конфигурирано"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"За клавиатурната подредба е зададен <xliff:g id="LAYOUT_1">%s</xliff:g>. Докоснете за промяна."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"За клавиатурната подредба са зададени <xliff:g id="LAYOUT_1">%1$s</xliff:g> и <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Докоснете за промяна."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"За клавиатурната подредба са зададени <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> и <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Докоснете за промяна."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"За клавиатурната подредба са зададени <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> и <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Докоснете за промяна."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физическите клавиатури са конфигурирани"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Докоснете за преглед на клавиатурите"</string>
</resources>
diff --git a/core/res/res/values-bn/strings.xml b/core/res/res/values-bn/strings.xml
index d6af185..64448fd0 100644
--- a/core/res/res/values-bn/strings.xml
+++ b/core/res/res/values-bn/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"ওয়াই-ফাই"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"ওয়াই-ফাই কলিং"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"ওয়াই ফাই কল"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"বন্ধ আছে"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"ওয়াই-ফাইয়ের মাধ্যমে কল করুন"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"মোবাইল নেটওয়ার্কের মাধ্যমে কল করুন"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ইনপুট পদ্ধতি বেছে নিন"</string>
<string name="show_ime" msgid="6406112007347443383">"ফিজিক্যাল কীবোর্ড সক্রিয় থাকার সময় এটিকে স্ক্রীনে রাখুন"</string>
<string name="hardware" msgid="1800597768237606953">"ভার্চুয়াল কীবোর্ড দেখুন"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> কনফিগার করুন"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ফিজিক্যাল কীবোর্ড কনফিগার করুন"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ভাষা এবং লেআউট বেছে নিন আলতো চাপ দিন"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"হিয়ারিং ডিভাইস"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করা হয়েছে।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ভলিউম কী ধরে ছিলেন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> বন্ধ করা হয়েছে।"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ভলিউম \'কী\' রিলিজ করুন। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> চালু করুন, দু\'টি ভলিউম \'কী\' আবার প্রেস করে ৩ সেকেন্ড ধরে রাখুন।"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"অ্যাক্সেসিবিলিটি বোতামে ট্যাপ করে আপনি যে ফিচার ব্যবহার করতে চান সেটি বেছে নিন:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"অ্যাক্সেসিবিলিটি জেসচারের (দুটি আঙ্গুল দিয়ে স্ক্রিনের নিচে থেকে উপরের দিকে সোয়াইপ করুন) সাহায্যে আপনি যে ফিচার ব্যবহার করতে চান সেটি বেছে নিন:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"অ্যাক্সেসিবিলিটি জেসচারের (তিনটি আঙ্গুল দিয়ে স্ক্রিনের নিচে থেকে উপরের দিকে সোয়াইপ করুন) সাহায্যে আপনি যে ফিচার ব্যবহার করতে চান সেটি বেছে নিন:"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"কন্টেন্ট দেখানোর জন্য <xliff:g id="APP_NAME">%1$s</xliff:g> দুটি ডিসপ্লে ব্যবহার করছে"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ডিভাইস খুব গরম হয়ে গেছে"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"আপনার ফোন খুব বেশি গরম হয়ে যাচ্ছে বলে \'ডুয়াল স্ক্রিন\' উপলভ্য নেই"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"বন্ধ করুন"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> কনফিগার করা হয়েছে"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%s</xliff:g>-এ সেট করা আছে। পরিবর্তন করতে ট্যাপ করুন।"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>-এ সেট করা আছে। পরিবর্তন করতে ট্যাপ করুন।"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>-এ সেট করা আছে। পরিবর্তন করতে ট্যাপ করুন।"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"কীবোর্ড লেআউট <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>-এ সেট করা আছে… পরিবর্তন করতে ট্যাপ করুন।"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ফিজিক্যাল কীবোর্ড কনফিগার করা হয়েছে"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"কীবোর্ড দেখতে ট্যাপ করুন"</string>
</resources>
diff --git a/core/res/res/values-bs/strings.xml b/core/res/res/values-bs/strings.xml
index 8aaa6ae..1a702aa 100644
--- a/core/res/res/values-bs/strings.xml
+++ b/core/res/res/values-bs/strings.xml
@@ -141,6 +141,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Pozivanje putem WIFi-ja"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Wi-Fi poziv"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Isključeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Poziv putem WiFi-ja"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Poziv putem mobilne mreže"</string>
@@ -1394,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Odaberite način unosa"</string>
<string name="show_ime" msgid="6406112007347443383">"Prikaži na ekranu dok je fizička tastatura aktivna"</string>
<string name="hardware" msgid="1800597768237606953">"Prikaz virtuelne tastature"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurirajte uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurirajte fizičke tastature"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite za odabir jezika i rasporeda"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je uključena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za jačinu zvuka. Usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je isključena."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za jačinu zvuka. Da uključite uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za jačinu zvuka 3 sekunde."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Odaberite funkciju koja će se koristiti kada dodirnete dugme Pristupačnost:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite funkciju koju ćete koristiti kada izvedete pokret za pristupačnost (s dva prsta prevucite prema gore s dna ekrana):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite funkciju koju ćete koristiti kada izvedete pokret za pristupačnost (s tri prsta prevucite prema gore s dna ekrana):"</string>
@@ -2327,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> koristi oba ekrana za prikazivanje sadržaja"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Uređaj je previše zagrijan"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dupli ekran nije dostupan je se telefon previše zagrijava"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Isključi"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g> je konfiguriran"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Raspored tastature je postavljen na <xliff:g id="LAYOUT_1">%s</xliff:g>. Dodirnite da promijenite."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Raspored tastature je postavljen na <xliff:g id="LAYOUT_1">%1$s</xliff:g> i <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Dodirnite da promijenite."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Raspored tastature je postavljen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> i <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Dodirnite da promijenite."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Raspored tastature je postavljen na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Dodirnite da promijenite."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizičke tastature su konfigurirane"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Dodirnite da pregledate tastature"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 5145cbb..1fe8f61 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -141,6 +141,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi‑Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Trucades per Wi‑Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desactivat"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Trucades per Wi‑Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Trucades per la xarxa mòbil"</string>
@@ -1394,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Selecciona un mètode d\'introducció"</string>
<string name="show_ime" msgid="6406112007347443383">"Mantén-lo en pantalla mentre el teclat físic està actiu"</string>
<string name="hardware" msgid="1800597768237606953">"Mostra el teclat virtual"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura els teclats físics"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toca per seleccionar l\'idioma i la disposició"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1517,7 +1517,7 @@
<string name="next_button_label" msgid="6040209156399907780">"Següent"</string>
<string name="skip_button_label" msgid="3566599811326688389">"Omet"</string>
<string name="no_matches" msgid="6472699895759164599">"No s\'ha trobat cap coincidència"</string>
- <string name="find_on_page" msgid="5400537367077438198">"Troba-ho a la pàgina"</string>
+ <string name="find_on_page" msgid="5400537367077438198">"Cerca a la pàgina"</string>
<string name="matches_found" msgid="2296462299979507689">"{count,plural, =1{# coincidència}many{# de {total}}other{# de {total}}}"</string>
<string name="action_mode_done" msgid="2536182504764803222">"Fet"</string>
<string name="progress_erasing" msgid="6891435992721028004">"S\'està esborrant l\'emmagatzematge compartit…"</string>
@@ -1722,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Audiòfons"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S\'han mantingut premudes les tecles de volum. S\'ha activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S\'han mantingut premudes les tecles de volum. S\'ha desactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Deixa anar les tecles de volum. Per activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, torna a mantenir premudes totes dues tecles de volum durant 3 segons."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Tria la funció que vols utilitzar quan toquis el botó d\'accessibilitat:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Tria la funció que vols utilitzar amb el gest d\'accessibilitat (llisca cap amunt amb dos dits des de la part inferior de la pantalla):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Tria la funció que vols utilitzar amb el gest d\'accessibilitat (fes lliscar tres dits cap amunt des de la part inferior de la pantalla):"</string>
@@ -1923,7 +1922,7 @@
<string name="usb_midi_peripheral_manufacturer_name" msgid="7557148557088787741">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="2836276258480904434">"Port perifèric USB"</string>
<string name="floating_toolbar_open_overflow_description" msgid="2260297653578167367">"Més opcions"</string>
- <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"Tanca el menú addicional"</string>
+ <string name="floating_toolbar_close_overflow_description" msgid="3949818077708138098">"Tanca el menú de desbordament"</string>
<string name="maximize_button_text" msgid="4258922519914732645">"Maximitza"</string>
<string name="close_button_text" msgid="10603510034455258">"Tanca"</string>
<string name="notification_messaging_title_template" msgid="772857526770251989">"<xliff:g id="CONVERSATION_TITLE">%1$s</xliff:g>: <xliff:g id="SENDER_NAME">%2$s</xliff:g>"</string>
@@ -2327,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> està utilitzant les dues pantalles per mostrar contingut"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"El dispositiu està massa calent"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"La pantalla dual no està disponible perquè el telèfon està massa calent"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactiva"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configurat"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Disseny del teclat definit en <xliff:g id="LAYOUT_1">%s</xliff:g>. Toca per canviar-ho."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Disseny del teclat definit en <xliff:g id="LAYOUT_1">%1$s</xliff:g> i <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Toca per canviar-ho."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Disseny del teclat definit en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> i <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Toca per canviar-ho."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Disseny del teclat definit en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toca per canviar-ho."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclats físic configurats"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toca per veure els teclats"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 4aa1192..0ed1dd8 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -142,6 +142,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Volání přes WiFi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Vypnuto"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Volání přes Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Volání přes mobilní síť"</string>
@@ -1395,10 +1397,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Vybrat metodu zadávání"</string>
<string name="show_ime" msgid="6406112007347443383">"Ponechat na obrazovce, když je aktivní fyzická klávesnice"</string>
<string name="hardware" msgid="1800597768237606953">"Zobrazit virtuální klávesnici"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Nakonfigurujte zařízení <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Nakonfigurujte fyzické klávesnice"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Klepnutím vyberte jazyk a rozvržení"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789AÁBCČDĎEÉĚFGHCHIÍJKLMNŇOÓPQRŘSŠTŤUÚVWXYÝZŽ"</string>
@@ -1723,8 +1723,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Naslouchátka"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Byla podržena tlačítka hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> byla vypnuta."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvolněte tlačítka hlasitosti. Pokud chcete zapnout službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znovu tři sekundy podržte obě tlačítka hlasitosti."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Určete, jakou funkci aktivujete klepnutím na tlačítko přístupnosti:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Určete, jakou funkci aktivujete pomocí gesta přístupnosti (přejetí dvěma prsty ze spodní části obrazovky nahoru):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Určete, jakou funkci aktivujete pomocí gesta přístupnosti (přejetí třemi prsty ze spodní části obrazovky nahoru):"</string>
@@ -2328,19 +2327,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> používá k zobrazení obsahu oba displeje"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Zařízení je příliš horké"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvojitá obrazovka není k dispozici, protože se telefon příliš zahřívá"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Vypnout"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Zařízení <xliff:g id="DEVICE_NAME">%s</xliff:g> je nakonfigurováno"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Rozložení klávesnice je nastaveno na <xliff:g id="LAYOUT_1">%s</xliff:g>. Klepnutím jej změníte."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Rozložení klávesnice je nastaveno na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Klepnutím jej změníte."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Rozložení klávesnice je nastaveno na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Klepnutím jej změníte."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Rozložení klávesnice je nastaveno na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Klepnutím jej změníte."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fyzické klávesnice byly nakonfigurovány"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klepnutím zobrazíte klávesnice"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index 44abefb..3bb53d4 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi-opkald"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Fra"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Ring via Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Ring via mobilnetværk"</string>
@@ -1151,7 +1153,7 @@
<string name="selectTextMode" msgid="3225108910999318778">"Markér tekst"</string>
<string name="undo" msgid="3175318090002654673">"Fortryd"</string>
<string name="redo" msgid="7231448494008532233">"Annuller fortryd"</string>
- <string name="autofill" msgid="511224882647795296">"AutoFyld"</string>
+ <string name="autofill" msgid="511224882647795296">"Autofyld"</string>
<string name="textSelectionCABTitle" msgid="5151441579532476940">"Tekstmarkering"</string>
<string name="addToDictionary" msgid="8041821113480950096">"Føj til ordbog"</string>
<string name="deleteText" msgid="4200807474529938112">"Slet"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Vælg inputmetode"</string>
<string name="show_ime" msgid="6406112007347443383">"Behold den på skærmen, mens det fysiske tastatur er aktivt"</string>
<string name="hardware" msgid="1800597768237606953">"Vis virtuelt tastatur"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurer <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurer fysiske tastaturer"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tryk for at vælge sprog og layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Høreapparater"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er aktiveret."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lydstyrkeknapperne blev holdt nede. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er deaktiveret."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slip lydstyrkeknapperne. Du kan aktivere <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ved at holde begge lydstyrkeknapper nede igen i 3 sekunder."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Vælg, hvilken funktion du vil bruge, når du trykker på knappen til hjælpefunktioner:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med to fingre):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Vælg, hvilken funktion du vil bruge, når du laver bevægelsen for hjælpefunktioner (stryger opad fra bunden af skærmen med tre fingre):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruger begge skærme til at vise indhold"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Enheden er for varm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dobbeltskærm er ikke tilgængelig, fordi din telefon er for varm"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Deaktiver"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> er konfigureret"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Tastaturlayoutet er angivet som <xliff:g id="LAYOUT_1">%s</xliff:g>. Tryk for at ændre dette."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Tastaturlayoutet er angivet som <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Tryk for at ændre dette."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Tastaturlayoutet er angivet som <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Tryk for at ændre dette."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tastaturlayoutet er angivet som <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tryk for at ændre dette."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fysiske tastaturer er konfigureret"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tryk for at se tastaturer"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 2f485bb..8530755 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WLAN"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WLAN-Telefonie"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Aus"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Anruf über WLAN"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Über Mobilfunknetz anrufen"</string>
@@ -1255,7 +1257,7 @@
<string name="android_upgrading_starting_apps" msgid="6206161195076057075">"Apps werden gestartet..."</string>
<string name="android_upgrading_complete" msgid="409800058018374746">"Start wird abgeschlossen..."</string>
<string name="fp_power_button_enrollment_message" msgid="5648173517663246140">"Du hast die Ein-/Aus-Taste gedrückt — damit wird der Bildschirm ausgeschaltet.\n\nTippe die Taste leicht an, um deinen Fingerabdruck einzurichten."</string>
- <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Zum Beenden der Einrichtung Bildschirm deaktivieren"</string>
+ <string name="fp_power_button_enrollment_title" msgid="6976841690455338563">"Zum Beenden Bildschirm deaktivieren"</string>
<string name="fp_power_button_enrollment_button_text" msgid="3199783266386029200">"Deaktivieren"</string>
<string name="fp_power_button_bp_title" msgid="5585506104526820067">"Mit der Fingerabdruckprüfung fortfahren?"</string>
<string name="fp_power_button_bp_message" msgid="2983163038168903393">"Du hast die Ein-/Aus-Taste gedrückt — damit wird der Bildschirm ausgeschaltet.\n\nTippe die Taste leicht an, um mit deinem Fingerabdruck deine Identität zu bestätigen."</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Eingabemethode wählen"</string>
<string name="show_ime" msgid="6406112007347443383">"Bildschirmtastatur auch dann anzeigen, wenn physische Tastatur aktiv ist"</string>
<string name="hardware" msgid="1800597768237606953">"Virtuelle Tastatur einblenden"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> konfigurieren"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Physische Tastaturen konfigurieren"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Zum Auswählen von Sprache und Layout tippen"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hörgeräte"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist aktiviert."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Lautstärketasten wurden gedrückt gehalten. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ist deaktiviert."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lass die Lautstärketasten los. Halte zum Aktivieren von <xliff:g id="SERVICE_NAME">%1$s</xliff:g> beide Lautstärketasten noch einmal 3 Sekunden lang gedrückt."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Wähle eine Funktion aus, die verwendet wird, wenn du auf die Schaltfläche \"Bedienungshilfen\" tippst:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Wähle die Funktion aus, die mit der Touch-Geste für die Bedienungshilfen verwendet werden soll (mit zwei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Wähle eine Funktion aus, die mit der Touch-Geste für die Bedienungshilfen verwendet werden soll (mit drei Fingern vom unteren Bildschirmrand nach oben wischen):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> nutzt zum Anzeigen von Inhalten beide Displays"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Gerät ist zu warm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen ist nicht verfügbar, weil dein Smartphone zu warm ist"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Deaktivieren"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> konfiguriert"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Tastaturlayout festgelegt auf <xliff:g id="LAYOUT_1">%s</xliff:g>. Zum Ändern tippen."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Tastaturlayout festgelegt auf <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Zum Ändern tippen."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Tastaturlayout festgelegt auf <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Zum Ändern tippen."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tastaturlayout festgelegt auf <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Zum Ändern tippen."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Physische Tastaturen konfiguriert"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Zum Ansehen der Tastaturen tippen"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index 34d7188..28b269b 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Κλήση Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Κλήση μέσω Wi-Fi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Ανενεργό"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Κλήση μέσω Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Κλήση μέσω δικτύου κινητής τηλεφωνίας"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Επιλογή μεθόδου εισόδου"</string>
<string name="show_ime" msgid="6406112007347443383">"Να παραμένει στην οθόνη όταν είναι ενεργό το κανονικό πληκτρολόγιο"</string>
<string name="hardware" msgid="1800597768237606953">"Εμφάνιση εικονικού πληκτρολ."</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Διαμόρφωση <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Διαμόρφωση φυσικών πληκτρολογίων"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Πατήστε για να επιλέξετε γλώσσα και διάταξη"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Συσκευές ακοής"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ενεργοποιήθηκε."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Τα πλήκτρα έντασης είναι πατημένα. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>: απενεργοποιημένο"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Αφήστε τα κουμπιά έντασης ήχου. Για να ενεργοποιήσετε την υπηρεσία <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, πατήστε ξανά παρατεταμένα και τα δύο κουμπιά έντασης ήχου για τρία δευτερόλεπτα."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται κατά το πάτημα του κουμπιού προσβασιμότητας:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με δύο δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Επιλέξτε μια λειτουργία που θα χρησιμοποιείται με την κίνηση προσβασιμότητας (σύρετε με τρία δάχτυλα προς τα επάνω από το κάτω μέρος της οθόνης):"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> χρησιμοποιεί και τις δύο οθόνες για να εμφανίζει περιεχόμενο"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Η θερμοκρασία της συσκευής είναι πολύ υψηλή"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Η λειτουργία διπλής οθόνης δεν είναι διαθέσιμη επειδή η θερμοκρασία του τηλεφώνου αυξάνεται υπερβολικά"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Απενεργοποίηση"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Η συσκευή <xliff:g id="DEVICE_NAME">%s</xliff:g> διαμορφώθηκε"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Η διάταξη πληκτρολογίου ορίστηκε σε <xliff:g id="LAYOUT_1">%s</xliff:g>. Πατήστε για αλλαγή."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Η διάταξη πληκτρολογίου ορίστηκε σε <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Πατήστε για αλλαγή."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Η διάταξη πληκτρολογίου ορίστηκε σε <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Πατήστε για αλλαγή."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Η διάταξη πληκτρολογίου ορίστηκε σε <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Πατήστε για αλλαγή."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Τα φυσικά πληκτρολόγια διαμορφώθηκαν"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Πατήστε για να δείτε πληκτρολόγια"</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index c83e2a7..4996e4f 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi Calling"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Wi-Fi Call"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Call over Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Call over mobile network"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Choose input method"</string>
<string name="show_ime" msgid="6406112007347443383">"Keep it on screen while physical keyboard is active"</string>
<string name="hardware" msgid="1800597768237606953">"Show virtual keyboard"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure physical keyboards"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tap to select language and layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the Accessibility button:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using both displays to show content"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Device is too warm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen is unavailable because your phone is getting too warm"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Turn off"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configured"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Keyboard layout set to <xliff:g id="LAYOUT_1">%s</xliff:g>. Tap to change."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Tap to change."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Tap to change."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tap to change."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Physical keyboards configured"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tap to view keyboards"</string>
</resources>
diff --git a/core/res/res/values-en-rCA/strings.xml b/core/res/res/values-en-rCA/strings.xml
index ff34dca..597569c 100644
--- a/core/res/res/values-en-rCA/strings.xml
+++ b/core/res/res/values-en-rCA/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi Calling"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"WiFi Call"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Call over Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Call over mobile network"</string>
@@ -2323,6 +2324,12 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using both displays to show content"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Device is too warm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen is unavailable because your phone is getting too warm"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Turn off"</string>
<string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configured"</string>
<string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Keyboard layout set to <xliff:g id="LAYOUT_1">%s</xliff:g>. Tap to change."</string>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 3fc4540..76fdcef 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi Calling"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Wi-Fi Call"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Call over Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Call over mobile network"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Choose input method"</string>
<string name="show_ime" msgid="6406112007347443383">"Keep it on screen while physical keyboard is active"</string>
<string name="hardware" msgid="1800597768237606953">"Show virtual keyboard"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure physical keyboards"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tap to select language and layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the Accessibility button:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using both displays to show content"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Device is too warm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen is unavailable because your phone is getting too warm"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Turn off"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configured"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Keyboard layout set to <xliff:g id="LAYOUT_1">%s</xliff:g>. Tap to change."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Tap to change."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Tap to change."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tap to change."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Physical keyboards configured"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tap to view keyboards"</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 93d45c7..45afefc 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi Calling"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Wi-Fi Call"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Call over Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Call over mobile network"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Choose input method"</string>
<string name="show_ime" msgid="6406112007347443383">"Keep it on screen while physical keyboard is active"</string>
<string name="hardware" msgid="1800597768237606953">"Show virtual keyboard"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure physical keyboards"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tap to select language and layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hearing devices"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned on."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Held volume keys. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> turned off."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Release the volume keys. To turn on <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, press and hold both volume keys again for three seconds."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choose a feature to use when you tap the Accessibility button:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with two fingers):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choose a feature to use with the accessibility gesture (swipe up from the bottom of the screen with three fingers):"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using both displays to show content"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Device is too warm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen is unavailable because your phone is getting too warm"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Turn off"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configured"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Keyboard layout set to <xliff:g id="LAYOUT_1">%s</xliff:g>. Tap to change."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Tap to change."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Tap to change."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Keyboard layout set to <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tap to change."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Physical keyboards configured"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tap to view keyboards"</string>
</resources>
diff --git a/core/res/res/values-en-rXC/strings.xml b/core/res/res/values-en-rXC/strings.xml
index d55ee16..6c57327 100644
--- a/core/res/res/values-en-rXC/strings.xml
+++ b/core/res/res/values-en-rXC/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi Calling"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"WiFi Call"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Call over Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Call over mobile network"</string>
@@ -2323,6 +2324,12 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> is using both displays to show content"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Device is too warm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dual Screen is unavailable because your phone is getting too warm"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Turn off"</string>
<string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configured"</string>
<string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Keyboard layout set to <xliff:g id="LAYOUT_1">%s</xliff:g>. Tap to change."</string>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index f32279a..d2c12e4 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -141,6 +141,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Llamada por Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Llamada por Wi-Fi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desactivada"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Llamar mediante Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Llamar mediante red móvil"</string>
@@ -1394,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Selecciona el método de entrada"</string>
<string name="show_ime" msgid="6406112007347443383">"Mientras el teclado físico está activo"</string>
<string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura teclados físicos"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Presiona para seleccionar el idioma y el diseño"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dispositivos auditivos"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Como mantuviste presionadas las teclas de volumen, se activó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se presionaron las teclas de volumen. Se desactivó <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, vuelve a mantener presionadas las teclas de volumen durante 3 segundos."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Elige una función para usar cuando pulses el botón accesibilidad:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Elige la función que se usará cuando realices el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Elige la función que se usará cuando realices el gesto de accesibilidad (deslizar tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
@@ -2327,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando ambas pantallas para mostrar contenido"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"El dispositivo está muy caliente"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"La Pantalla dual no está disponible porque el teléfono se está calentando demasiado"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactivar"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Se configuró <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%s</xliff:g>. Presiona para cambiar esta opción."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g> y <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Presiona para cambiar esta opción."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño de teclado establecido en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Presiona para cambiar esta opción."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Presiona para ver los teclados"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index ffc018f..b221b9e 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -141,6 +141,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi‑Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Llamada por Wi‑Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWiFi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desactivado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Llamar a través de la red Wi‑Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Llamar a través de la red móvil"</string>
@@ -1394,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Selecciona un método de entrada"</string>
<string name="show_ime" msgid="6406112007347443383">"Mientras el teclado físico está activo"</string>
<string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura teclados físicos"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toca para seleccionar el idioma y el diseño"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dispositivos auditivos"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Al mantener pulsadas las teclas de volumen, se ha activado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Se han mantenido pulsadas las teclas de volumen. Se ha desactivado <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Suelta las teclas de volumen. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantén pulsadas las dos teclas de volumen de nuevo durante 3 segundos."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Selecciona la función que se utilizará cuando toques el botón de accesibilidad:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Elige la función que se utilizará con el gesto de accesibilidad (deslizar dos dedos hacia arriba desde la parte inferior de la pantalla):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Elige la función que se utilizará con el gesto de accesibilidad (deslizar tres dedos hacia arriba desde la parte inferior de la pantalla):"</string>
@@ -2327,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> está usando ambas pantallas para mostrar contenido"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"El dispositivo está demasiado caliente"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Cámara Dual no está disponible porque el teléfono se está calentando demasiado"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactivar"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Se ha configurado <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%s</xliff:g>. Toca para cambiarlo."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g> y <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Toca para cambiarlo."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> y <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Toca para cambiarlo."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Diseño del teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toca para cambiarlo."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toca para ver los teclados"</string>
</resources>
diff --git a/core/res/res/values-et/strings.xml b/core/res/res/values-et/strings.xml
index d84db73..f4f3c4d 100644
--- a/core/res/res/values-et/strings.xml
+++ b/core/res/res/values-et/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi-kõned"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Väljas"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Helista WiFi kaudu"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Helista mobiilsidevõrgu kaudu"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Valige sisestusmeetod"</string>
<string name="show_ime" msgid="6406112007347443383">"Hoia seda ekraanil, kui füüsiline klaviatuur on aktiivne"</string>
<string name="hardware" msgid="1800597768237606953">"Virtuaalse klaviatuuri kuvam."</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Seadistage <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Seadistage füüsilised klaviatuurid"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Puudutage keele ja paigutuse valimiseks"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSŠZŽTUVWÕÄÖÜXY"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Kuuldeseadmed"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati sisse."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Helitugevuse klahve hoiti all. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> lülitati välja."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vabastage helitugevuse klahvid. Teenuse <xliff:g id="SERVICE_NAME">%1$s</xliff:g> sisselülitamiseks vajutage uuesti mõlemat helitugevuse klahvi ja hoidke neid 3 sekundit all."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Valige, millist funktsiooni kasutada, kui vajutate juurdepääsetavuse nuppu:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Valige, millist funktsiooni juurdepääsetavuse liigutusega (kahe sõrmega ekraanikuval alt üles pühkimine) kasutada:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Valige, millist funktsiooni juurdepääsetavuse liigutusega (kolme sõrmega ekraanikuval alt üles pühkimine) kasutada:"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> kasutab sisu kuvamiseks mõlemat ekraani"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Seade on liiga kuum"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Kahe ekraani režiim pole saadaval, kuna teie telefon läheb liiga kuumaks"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Lülita välja"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> on seadistatud"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Klaviatuuripaigutuseks on määratud <xliff:g id="LAYOUT_1">%s</xliff:g>. Puudutage muutmiseks."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Klaviatuuripaigutuseks on määratud <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Puudutage muutmiseks."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Klaviatuuripaigutuseks on määratud <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Puudutage muutmiseks."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klaviatuuripaigutuseks on määratud <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> … puudutage muutmiseks."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Füüsilised klaviatuurid on seadistatud"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Puudutage klaviatuuride vaatamiseks"</string>
</resources>
diff --git a/core/res/res/values-eu/strings.xml b/core/res/res/values-eu/strings.xml
index e7aabd8..3ca55e2 100644
--- a/core/res/res/values-eu/strings.xml
+++ b/core/res/res/values-eu/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wifia"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi bidezko deiak"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desaktibatuta"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Deitu wifi bidez"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Deitu sare mugikorraren bidez"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Aukeratu idazketa-metodoa"</string>
<string name="show_ime" msgid="6406112007347443383">"Erakutsi pantailan teklatu fisikoa aktibo dagoen bitartean"</string>
<string name="hardware" msgid="1800597768237606953">"Erakutsi teklatu birtuala"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfiguratu <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfiguratu teklatu fisikoak"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Hizkuntza eta diseinua hautatzeko, sakatu hau"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Audifonoak"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatu egin da."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bolumen-botoiak sakatuta eduki direnez, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desaktibatu egin da."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Askatu bolumen-botoiak. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> aktibatzeko, eduki sakatuta berriro bi bolumen-botoiak hiru segundoz."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Aukeratu zein eginbide erabili nahi duzun Erabilerraztasuna botoia sakatzean:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Aukeratu zein eginbide erabili nahi duzun erabilerraztasun-keinuarekin (hau da, bi hatz pantailaren behealdetik gora pasatzean):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Aukeratu zein eginbide erabili nahi duzun erabilerraztasun-keinuarekin (hau da, hiru hatz pantailaren behealdetik gora pasatzean):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> bi pantailak erabiltzen ari da edukia erakusteko"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Gailua beroegi dago"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Bi pantailako modua ez dago erabilgarri telefonoa berotzen ari delako"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desaktibatu"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Konfiguratu da <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Ezarri da <xliff:g id="LAYOUT_1">%s</xliff:g> gisa teklatuaren diseinua. Diseinu hori aldatzeko, sakatu hau."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Ezarri da <xliff:g id="LAYOUT_1">%1$s</xliff:g> eta <xliff:g id="LAYOUT_2">%2$s</xliff:g> gisa teklatuaren diseinua. Diseinu hori aldatzeko, sakatu hau."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Ezarri da <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> eta <xliff:g id="LAYOUT_3">%3$s</xliff:g> gisa teklatuaren diseinua. Diseinu hori aldatzeko, sakatu hau."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ezarri da <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> eta <xliff:g id="LAYOUT_3">%3$s</xliff:g> gisa teklatuaren diseinua… Diseinu hori aldatzeko, sakatu hau."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Konfiguratu dira teklatu fisikoak"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Sakatu hau teklatuak ikusteko"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 4b98194..5473cec 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"تماس ازطریق WiFi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"خاموش"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"تماس ازطریق Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"تماس ازطریق شبکه تلفن همراه"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"انتخاب روش ورودی"</string>
<string name="show_ime" msgid="6406112007347443383">"وقتی صفحهکلید فیزیکی فعال است این ویرایشگر را روی صفحه نگهمیدارد"</string>
<string name="hardware" msgid="1800597768237606953">"نمایش صفحهکلید مجازی"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"پیکربندی <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"پیکربندی صفحهکلیدهای فیزیکی"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"برای انتخاب زبان و چیدمان ضربه بزنید"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"دستگاههای کمکشنوایی"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> روشن شد."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"کلیدهای میزان صدا پایین نگه داشته شد. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> خاموش شد."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"کلیدهای میزان صدا را رها کنید. برای روشن کردن <xliff:g id="SERVICE_NAME">%1$s</xliff:g>، هر دو کلید میزان صدا را مجدداً بهمدت ۳ ثانیه فشار دهید و نگه دارید."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ویژگی را انتخاب کنید که هنگام ضربه زدن روی دکمه دسترسپذیری استفاده میشود:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ویژگی را برای استفاده با اشاره دسترسپذیری انتخاب کنید (با دو انگشت صفحه را از پایین تند بهبالا بکشید):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ویزگی را برای استفاده با اشاره دسترسپذیری انتخاب کنید (با سه انگشت صفحه را از پایین تند بهبالا بکشید):"</string>
@@ -2058,7 +2057,7 @@
<string name="mmcc_imsi_unknown_in_hlr_msim_template" msgid="3688508325248599657">"سیمکارت <xliff:g id="SIMNUMBER">%d</xliff:g> مجوز لازم را ندارد"</string>
<string name="mmcc_illegal_ms_msim_template" msgid="832644375774599327">"سیمکارت <xliff:g id="SIMNUMBER">%d</xliff:g> مجاز نیست"</string>
<string name="mmcc_illegal_me_msim_template" msgid="4802735138861422802">"سیمکارت <xliff:g id="SIMNUMBER">%d</xliff:g> مجاز نیست"</string>
- <string name="popup_window_default_title" msgid="6907717596694826919">"پنجره بازشو"</string>
+ <string name="popup_window_default_title" msgid="6907717596694826919">"پنجره بالاپر"</string>
<string name="slice_more_content" msgid="3377367737876888459">"+ <xliff:g id="NUMBER">%1$d</xliff:g>"</string>
<string name="shortcut_restored_on_lower_version" msgid="9206301954024286063">"نسخه برنامه تنزل داده شده است یا با این میانبر سازگار نیست"</string>
<string name="shortcut_restore_not_supported" msgid="4763198938588468400">"نمیتوان میانبر را بازیابی کرد زیرا برنامه از پشتیبانگیری و بازیابی پشتیبانی نمیکند"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> از هر دو نمایشگر برای نمایش محتوا استفاده میکند"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"دستگاه بیشازحد گرم شده است"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"«صفحه دوتایی» دردسترس نیست زیرا تلفن بیشازحد گرم شده است"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"خاموش کردن"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> پیکربندی شد"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"طرحبندی صفحهکلید روی <xliff:g id="LAYOUT_1">%s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"طرحبندی صفحهکلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"طرحبندی صفحهکلید روی <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> تنظیم شد. برای تغییر دادن، ضربه بزنید."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"صفحهکلید روی این طرحبندیها تنظیم شد: <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g>… برای تغییر ضربه بزنید"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"صفحهکلیدهای فیزیکی پیکربندی شدند"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"برای مشاهده صفحهکلیدها ضربه بزنید"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 487082d..9ec3fba 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi-puhelut"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Ei päällä"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Soita Wi-Fin kautta"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Soita mobiiliverkon kautta"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Valitse syöttötapa"</string>
<string name="show_ime" msgid="6406112007347443383">"Pidä näytöllä, kun fyysinen näppäimistö on aktiivinen"</string>
<string name="hardware" msgid="1800597768237606953">"Näytä virtuaalinen näppäimistö"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Määritä <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Määritä fyysiset näppäimistöt"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Valitse kieli ja asettelu koskettamalla."</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZÅÄÖ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Kuulolaitteet"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin päälle."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Äänenvoimakkuuspainikkeita painettiin pitkään. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> laitettiin pois päältä."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Vapauta äänenvoimakkuuspainikkeet. Laita <xliff:g id="SERVICE_NAME">%1$s</xliff:g> päälle painamalla äänenvoimakkuuspainikkeita uudelleen kolmen sekunnin ajan."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Valitse ominaisuus, jonka esteettömyyspainike aktivoi:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Valitse ominaisuus, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kahdella sormella):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Valitse ominaisuus, jota käytetään esteettömyyseleellä (pyyhkäise näytön alalaidasta ylös kolmella sormella):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> käyttää molempia näyttöjä sisällön näyttämiseen"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Laite on liian lämmin"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Kaksoisnäyttö ei ole käytettävissä, koska puhelin on liian lämmin"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Laita pois päältä"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> määritetty"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Näppäimistöasetteluksi valittu <xliff:g id="LAYOUT_1">%s</xliff:g>. Muuta asetuksia napauttamalla."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Näppäimistöasetteluksi valittu <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Muuta asetuksia napauttamalla."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Näppäimistöasetteluksi valittu <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Muuta asetuksia napauttamalla."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Näppäimistöasetteluksi valittu <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Muuta asetuksia napauttamalla."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fyysiset näppäimistöt määritetty"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Katso näppäimistöt napauttamalla"</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index f0d5528..04597fa 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -141,6 +141,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Appels Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"Voix par Wi-Fi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Désactivé"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Appels par Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Appels sur réseau cellulaire"</string>
@@ -1394,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Sélectionnez le mode de saisie"</string>
<string name="show_ime" msgid="6406112007347443383">"Afficher lorsque le clavier physique est activé"</string>
<string name="hardware" msgid="1800597768237606953">"Afficher le clavier virtuel"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configurer <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configurer les claviers physiques"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Touchez pour sélectionner la langue et la configuration du clavier"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Appareils auditifs"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume maintenues enfoncées. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume maintenues enfoncées. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les touches de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, maintenez les deux touches de volume enfoncées pendant 3 secondes."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choisissez une fonctionnalité à utiliser lorsque vous touchez le bouton d\'accessibilité :"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choisissez une fonctionnalité à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer l\'écran de bas en haut avec deux doigts) :"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choisissez une fonctionnalité à utiliser lorsque vous utilisez le geste d\'accessibilité (balayer l\'écran de bas en haut avec trois doigts) :"</string>
@@ -2327,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> utilise les deux écrans pour afficher le contenu"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"L\'appareil est trop chaud"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Le double écran n\'est pas accessible, car votre téléphone est trop chaud"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Désactiver"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> est configuré"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Disposition du clavier définie à <xliff:g id="LAYOUT_1">%s</xliff:g>. Touchez pour modifier."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Disposition du clavier définie à <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Touchez pour modifier."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Disposition du clavier définie à <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Touchez pour modifier."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Disposition du clavier définie à <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Touchez pour modifier."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Claviers physiques configurés"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Touchez pour afficher les claviers"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 60c61fb..ff74083 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -141,6 +141,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Appels Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWiFi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Désactivé"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Appel via le Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Appel via le réseau mobile"</string>
@@ -1394,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Sélectionnez le mode de saisie"</string>
<string name="show_ime" msgid="6406112007347443383">"Afficher le clavier virtuel même lorsque le clavier physique est actif"</string>
<string name="hardware" msgid="1800597768237606953">"Afficher le clavier virtuel"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configurer <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configurez les claviers physiques"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Appuyer pour sélectionner la langue et la disposition"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Prothèses auditives"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> activé."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Touches de volume appuyées de manière prolongée. Service <xliff:g id="SERVICE_NAME">%1$s</xliff:g> désactivé."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Relâchez les boutons de volume. Pour activer <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, appuyez de nouveau sur les deux boutons de volume pendant trois secondes."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Choisissez une fonctionnalité à utiliser lorsque vous appuyez sur le bouton Accessibilité :"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Choisissez une fonctionnalité à utiliser avec le geste d\'accessibilité (balayez l\'écran de bas en haut avec deux doigts) :"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Choisissez une fonctionnalité à utiliser avec le geste d\'accessibilité (balayer l\'écran de bas en haut avec trois doigts) :"</string>
@@ -2327,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> utilise les deux écrans pour afficher du contenu"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"L\'appareil est trop chaud"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Double écran n\'est pas disponible, car votre téléphone surchauffe"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Désactiver"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> configuré"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Disposition du clavier définie sur <xliff:g id="LAYOUT_1">%s</xliff:g>. Appuyez pour la modifier."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Disposition du clavier définie sur <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Appuyez pour la modifier."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Disposition du clavier définie sur <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Appuyez pour la modifier."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Disposition du clavier définie sur <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Appuyez pour la modifier."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Claviers physiques configurés"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Appuyez pour voir les claviers"</string>
</resources>
diff --git a/core/res/res/values-gl/strings.xml b/core/res/res/values-gl/strings.xml
index 8d1aac3..1f86aa5 100644
--- a/core/res/res/values-gl/strings.xml
+++ b/core/res/res/values-gl/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wifi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Chamadas por wifi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desactivado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Chama por wifi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Chama pola rede de telefonía móbil"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Escoller método de introdución de texto"</string>
<string name="show_ime" msgid="6406112007347443383">"Móstrase na pantalla mentres o teclado físico estea activo"</string>
<string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura o teclado (<xliff:g id="DEVICE_NAME">%s</xliff:g>)"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura os teclados físicos"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toca para seleccionar o idioma e o deseño"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNÑOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dispositivos auditivos"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume premidas. Activouse o servizo <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume premidas. Desactivouse <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solta as teclas de volume. Para activar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, mantenas premidas de novo durante 3 segundos."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolle a función que queres utilizar cando toques o botón Accesibilidade:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolle a función que queres usar co xesto de accesibilidade (pasa dous dedos cara arriba desde a parte inferior da pantalla):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolle a función que queres usar co xesto de accesibilidade (pasa tres dedos cara arriba desde a parte inferior da pantalla):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"A aplicación <xliff:g id="APP_NAME">%1$s</xliff:g> está usando ambas as pantallas para mostrar contido"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"O dispositivo está demasiado quente"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A pantalla dual non está dispoñible porque o teléfono está quentando demasiado"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desactivar"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Configurouse o teclado (<xliff:g id="DEVICE_NAME">%s</xliff:g>)"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"O deseño do teclado estableceuse en <xliff:g id="LAYOUT_1">%s</xliff:g>. Toca para cambialo."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"O deseño do teclado estableceuse en <xliff:g id="LAYOUT_1">%1$s</xliff:g> e <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Toca para cambialo."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"O deseño do teclado estableceuse en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> e <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Toca para cambialo."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"O deseño do teclado estableceuse en <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toca para cambialo."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Configuráronse varios teclados físicos"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toca para ver os teclados"</string>
</resources>
diff --git a/core/res/res/values-gu/strings.xml b/core/res/res/values-gu/strings.xml
index 687ad2f..1122ce7 100644
--- a/core/res/res/values-gu/strings.xml
+++ b/core/res/res/values-gu/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"વાઇ-ફાઇ"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"વાઇ-ફાઇ કૉલિંગ"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"બંધ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"વાઇ-ફાઇ પરથી કૉલ કરો"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"મોબાઇલ નેટવર્ક પરથી કૉલ કરો"</string>
@@ -1356,7 +1358,7 @@
<string name="no_permissions" msgid="5729199278862516390">"કોઈ પરવાનગીઓ જરૂરી નથી"</string>
<string name="perm_costs_money" msgid="749054595022779685">"આનાથી તમારા પૈસા ખર્ચ થઈ શકે છે"</string>
<string name="dlg_ok" msgid="5103447663504839312">"ઓકે"</string>
- <string name="usb_charging_notification_title" msgid="1674124518282666955">"આ ડિવાઇસને USB મારફતે ચાર્જ કરી રહ્યાં છીએ"</string>
+ <string name="usb_charging_notification_title" msgid="1674124518282666955">"આ ડિવાઇસને USB મારફતે ચાર્જ કરી રહ્યાં છીએ."</string>
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"કનેક્ટેડ ઉપકરણને USB મારફતે ચાર્જ કરી રહ્યાં છીએ"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB ફાઇલ ટ્રાન્સફર ચાલુ છે"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB મારફતે PTP ચાલુ કર્યું"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ઇનપુટ પદ્ધતિ પસંદ કરો"</string>
<string name="show_ime" msgid="6406112007347443383">"જ્યારે ભૌતિક કીબોર્ડ સક્રિય હોય ત્યારે તેને સ્ક્રીન પર રાખો"</string>
<string name="hardware" msgid="1800597768237606953">"વર્ચ્યુઅલ કીબોર્ડ બતાવો"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>ની ગોઠવણી કરો"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ભૌતિક કીબોર્ડની ગોઠવણી કરો"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ભાષા અને લેઆઉટ પસંદ કરવા માટે ટૅપ કરો"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"સાંભળવામાં સહાય કરતા ડિવાઇસ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ચાલુ કરી."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"વૉલ્યૂમ કી દબાવી રાખો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> બંધ કરી."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"વૉલ્યૂમ કી છોડી દો. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ને ચાલુ કરવા માટે, 3 સેકન્ડ માટે બન્ને વૉલ્યૂમ કીને ફરીથી દબાવી રાખો."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"જ્યારે તમે ઍક્સેસિબિલિટી બટન પર ટૅપ કરો, ત્યારે ઉપયોગ કરવાની સુવિધા પસંદ કરો:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સુવિધા પસંદ કરો (બે આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ઍક્સેસિબિલિટી સંકેત સાથે ઉપયોગ કરવાની સુવિધા પસંદ કરો (ત્રણ આંગળીઓ વડે સ્ક્રીનના નીચેના ભાગથી ઉપરની તરફ સ્વાઇપ કરવા માટે):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"કન્ટેન્ટ બતાવવા માટે <xliff:g id="APP_NAME">%1$s</xliff:g> બન્ને ડિસ્પ્લેનો ઉપયોગ કરી રહી છે"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ડિવાઇસ ખૂબ જ ગરમ છે"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ડ્યૂઅલ સ્ક્રીન અનુપલબ્ધ છે કારણ કે તમારો ફોન ખૂબ જ ગરમ થઈ રહ્યો છે"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"બંધ કરો"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g>ની ગોઠવણી કરવામાં આવી છે"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"કીબોર્ડનું લેઆઉટ <xliff:g id="LAYOUT_1">%s</xliff:g> પર સેટ કરવામાં આવ્યું છે. બદલવા માટે ટૅપ કરો."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"કીબોર્ડનું લેઆઉટ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> પર સેટ કરવામાં આવ્યું છે. બદલવા માટે ટૅપ કરો."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"કીબોર્ડનું લેઆઉટ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> પર સેટ કરવામાં આવ્યું છે. બદલવા માટે ટૅપ કરો."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"કીબોર્ડનું લેઆઉટ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> પર સેટ કરવામાં આવ્યું છે… બદલવા માટે ટૅપ કરો."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ભૌતિક કીબોર્ડની ગોઠવણી કરવામાં આવી છે"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"કીબોર્ડ જોવા માટે ટૅપ કરો"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index c0df6ca..2fe9a29 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"वाई-फ़ाई"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"वाई-फ़ाई कॉलिंग"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"बंद"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"वाई-फ़ाई के ज़रिए कॉल करें"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"मोबाइल नेटवर्क के ज़रिए कॉल"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"इनपुट का तरीका चुनें"</string>
<string name="show_ime" msgid="6406112007347443383">"सामान्य कीबोर्ड के सक्रिय होने के दौरान इसे स्क्रीन पर बनाए रखें"</string>
<string name="hardware" msgid="1800597768237606953">"वर्चुअल कीबोर्ड दिखाएं"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> को कॉन्फ़िगर करें"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"फ़िज़िकल कीबोर्ड को कॉन्फ़िगर करें"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"भाषा और लेआउट चुनने के लिए टैप करें"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"सुनने में मदद करने वाले डिवाइस"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को चालू कर दिया गया."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"आवाज़ कम-ज़्यादा करने वाले दोनों बटन दबाकर रखें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> को बंद कर दिया गया."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"आवाज़ बटन को छोड़ें. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> की सुविधा चालू करने के लिए, आवाज़ वाले दोनों बटन तीन सेकंड तक दबाकर रखें."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"सुलभता बटन पर टैप करके, इस्तेमाल करने के लिए सुविधा चुनें:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"सुलभता वाले हाथ के जेस्चर (हाव-भाव) के साथ इस्तेमाल करने के लिए सुविधा चुनें (दो उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"सुलभता वाले हाथ के जेस्चर (हाव-भाव) के साथ इस्तेमाल करने के लिए सुविधा चुनें (तीन उंगलियों से स्क्रीन पर सबसे नीचे से ऊपर की ओर स्वाइप करें):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>, कॉन्टेंट दिखाने के लिए दोनों डिसप्ले का इस्तेमाल कर रहा है"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"आपका फ़ोन बहुत गर्म हो गया है"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ड्यूअल स्क्रीन की सुविधा अभी उपलब्ध नहीं है, क्योंकि आपका फ़ोन बहुत गर्म हो रहा है"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"बंद करें"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> कॉन्फ़िगर किया गया"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"कीबोर्ड का लेआउट <xliff:g id="LAYOUT_1">%s</xliff:g> पर सेट कर दिया गया है. बदलने के लिए टैप करें."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"कीबोर्ड का लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> पर सेट कर दिया गया है. बदलने के लिए टैप करें."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"कीबोर्ड का लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> पर सेट कर दिया गया है. बदलने के लिए टैप करें."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"कीबोर्ड का लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… पर सेट कर दिया गया है. इसे बदलने के लिए टैप करें."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"फ़िज़िकल कीबोर्ड कॉन्फ़िगर किए गए"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"कीबोर्ड देखने के लिए टैप करें"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index 56220ce..5bdbd1e 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -141,6 +141,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi pozivi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Wi-Fi poziv"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Isključeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Pozivi putem Wi-Fija"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Pozivi putem mobilne mreže"</string>
@@ -1394,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Odabir načina unosa"</string>
<string name="show_ime" msgid="6406112007347443383">"Zadrži na zaslonu dok je fizička tipkovnica aktivna"</string>
<string name="hardware" msgid="1800597768237606953">"Prikaži virtualnu tipkovnicu"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurirajte uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurirajte fizičke tipkovnice"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dodirnite da biste odabrali jezik i raspored"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni uređaji"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Držali ste tipke za glasnoću. Uključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Držali ste tipke za glasnoću. Isključila se usluga <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Pustite tipke za glasnoću. Da biste uključili uslugu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ponovo pritisnite i zadržite obje tipke za glasnoću tri sekunde."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Odaberite značajku koju ćete upotrebljavati kada dodirnete gumb za Pristupačnost:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Odaberite za koju će se značajku upotrebljavati pokret pristupačnosti (prelazak s dva prsta prema gore od dna zaslona):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Odaberite za koju će se značajku upotrebljavati pokret pristupačnosti (prelazak s tri prsta prema gore od dna zaslona):"</string>
@@ -2327,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> upotrebljava oba zaslona za prikazivanje sadržaja"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Uređaj se pregrijao"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvostruki zaslon nije podržan jer se vaš telefon pregrijao"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Isključi"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Konfiguriran je uređaj <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Raspored tipkovnice postavljen je na <xliff:g id="LAYOUT_1">%s</xliff:g>. Dodirnite da biste ga promijenili."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Raspored tipkovnice postavljen je na <xliff:g id="LAYOUT_1">%1$s</xliff:g> i <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Dodirnite da biste ga promijenili."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Raspored tipkovnice postavljen je na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> i <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Dodirnite da biste ga promijenili."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Raspored tipkovnice postavljen je na <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Dodirnite da biste ga promijenili."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizičke su tipkovnice konfigurirane"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Dodirnite da bi se prikazale tipkovnice"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 4d781d9..6f996e5 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi-hívás"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Ki"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Hívás Wi-Fi-hálózaton"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Hívás mobilhálózaton"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Beviteli mód kiválasztása"</string>
<string name="show_ime" msgid="6406112007347443383">"Maradjon a képernyőn, amíg a billentyűzet aktív"</string>
<string name="hardware" msgid="1800597768237606953">"Virtuális billentyűzet"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"A(z) <xliff:g id="DEVICE_NAME">%s</xliff:g> beállítása"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fizikai billentyűzetek beállítása"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Koppintson a nyelv és a billentyűzetkiosztás kiválasztásához"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hallásjavító eszközök"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolva."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Nyomva tartotta a hangerőgombokat. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kikapcsolva."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Engedje fel a hangerőszabályzó gombokat. A(z) <xliff:g id="SERVICE_NAME">%1$s</xliff:g> bekapcsolásához tartsa újra lenyomva a hangerőszabályzó gombokat három másodpercig."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Válassza ki a Kisegítő lehetőségek gombra koppintáskor használni kívánt funkciót:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Válassza ki a kisegítő kézmozdulattal (felfelé csúsztatás két ujjal a képernyő aljáról) használni kívánt funkciót:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Válassza ki a kisegítő kézmozdulattal (felfelé csúsztatás három ujjal a képernyő aljáról) használni kívánt funkciót:"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> mindkét kijelzőt használja a tartalmak megjelenítésére"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Az eszköz túl meleg"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A Két képernyő funkció nem áll rendelkezésre, mert a telefon melegedni kezdett"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Kikapcsolás"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> beállítva"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"A billentyűzetkiosztás a következőre van beállítva: <xliff:g id="LAYOUT_1">%s</xliff:g>. A módosításhoz koppintson."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"A billentyűzetkiosztás a következőkre van beállítva: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. A módosításhoz koppintson."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"A billentyűzetkiosztás a következőkre van beállítva: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. A módosításhoz koppintson."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"A billentyűzetkiosztás a következőkre van beállítva: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… A módosításhoz koppintson."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizikai billentyűzetek beállítva"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Koppintson a billentyűzetek megtekintéséhez"</string>
</resources>
diff --git a/core/res/res/values-hy/strings.xml b/core/res/res/values-hy/strings.xml
index fdad595c..f1004de1 100644
--- a/core/res/res/values-hy/strings.xml
+++ b/core/res/res/values-hy/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Զանգեր Wi-Fi-ի միջոցով"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Անջատված է"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Զանգ Wi-Fi-ի միջոցով"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Զանգ բջջային ցանցի միջոցով"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Ընտրեք ներածման եղանակը"</string>
<string name="show_ime" msgid="6406112007347443383">"Պահել էկրանին, երբ ֆիզիկական ստեղնաշարն ակտիվ է"</string>
<string name="hardware" msgid="1800597768237606953">"Ցույց տալ վիրտուալ ստեղնաշարը"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Կարգավորեք <xliff:g id="DEVICE_NAME">%s</xliff:g> սարքը"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Կարգավորեք ֆիզիկական ստեղնաշարերը"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Հպեք՝ լեզուն և դասավորությունն ընտրելու համար"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ԱԲԳԴԵԶԷԸԹԺԻԼԽԾԿՀՁՂՃՄՅՆՇՈՉՊՋՌՍՎՏՐՑՈՒՓՔԵւՕՖ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Լսողական սարքեր"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացավ։"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ձայնի կարգավորման կոճակները սեղմվեցին։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունն անջատվեց։"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Բաց թողեք ձայնի ուժգնության կոճակները։ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ծառայությունը միացնելու համար սեղմեք և 3 վայրկյան պահեք ձայնի ուժգնության երկու կոճակը։"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Ընտրեք գործառույթը, որը կգործարկվի «Հատուկ գործառույթներ» կոճակին հպելու դեպքում՝"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Ընտրեք գործառույթը, որը կգործարկվի հատուկ գործառույթների ժեստը (երկու մատը էկրանի ներքևից սահեցրեք վերև) անելու դեպքում՝"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Ընտրեք գործառույթը, որը կգործարկվի հատուկ գործառույթների ժեստը (երեք մատը էկրանի ներքևից սահեցրեք վերև) անելու դեպքում՝"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը երկու էկրաններն էլ օգտագործում է բովանդակություն ցուցադրելու համար"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Սարքը գերտաքացել է"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Կրկնակի էկրանն անհասանելի է, քանի որ ձեր հեռախոսը գերտաքանում է"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Անջատել"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> սարքը կարգավորված է"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Ստեղնաշարի համար կարգավորված է <xliff:g id="LAYOUT_1">%s</xliff:g> դասավորությունը։ Հպեք փոփոխելու համար։"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Ստեղնաշարի համար կարգավորված են <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> դասավորությունները։ Հպեք փոփոխելու համար։"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Ստեղնաշարի համար կարգավորված են <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> դասավորությունները։ Հպեք փոփոխելու համար։"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ստեղնաշարի համար կարգավորված են <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> դասավորությունները։ Հպեք փոխելու համար։"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Ֆիզիկական ստեղնաշարերը կարգավորված են"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Հպեք՝ ստեղնաշարերը դիտելու համար"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 577e9a2..150629f 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Panggilan WiFi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Nonaktif"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Panggilan telepon melalui Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Panggilan telepon melalui jaringan seluler"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Pilih metode masukan"</string>
<string name="show_ime" msgid="6406112007347443383">"Biarkan di layar meski keyboard fisik aktif"</string>
<string name="hardware" msgid="1800597768237606953">"Tampilkan keyboard virtual"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurasi <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurasi keyboard fisik"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Ketuk untuk memilih bahasa dan tata letak"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Alat bantu dengar"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> diaktifkan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tombol volume ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dinonaktifkan."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan tombol volume. Untuk mengaktifkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tekan dan tahan kedua tombol volume lagi selama 3 detik."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pilih fitur yang akan digunakan saat mengetuk tombol aksesibilitas:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pilih fitur yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan dua jari):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pilih fitur yang akan digunakan dengan gestur aksesibilitas (geser ke atas dari bawah layar dengan tiga jari):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> menggunakan kedua layar untuk menampilkan konten"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Suhu perangkat terlalu panas"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Layar ganda tidak tersedia karena suhu ponsel terlalu panas"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Nonaktifkan"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> telah dikonfigurasi"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Tata letak keyboard disetel ke <xliff:g id="LAYOUT_1">%s</xliff:g>. Ketuk untuk mengubah."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Tata letak keyboard disetel ke <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Ketuk untuk mengubah."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Tata letak keyboard di setel ke <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Ketuk untuk mengubah."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tata letak keyboard disetel ke <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Ketuk untuk mengubah."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Keyboard fisik telah dikonfigurasi"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Ketuk untuk melihat keyboard"</string>
</resources>
diff --git a/core/res/res/values-is/strings.xml b/core/res/res/values-is/strings.xml
index bbccc75..10b7549 100644
--- a/core/res/res/values-is/strings.xml
+++ b/core/res/res/values-is/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi símtöl"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Slökkt"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Hringja í gegnum Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Hringja í gegnum farsímakerfi"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Veldu innsláttaraðferð"</string>
<string name="show_ime" msgid="6406112007347443383">"Halda því á skjánum meðan vélbúnaðarlyklaborðið er virkt"</string>
<string name="hardware" msgid="1800597768237606953">"Sýna sýndarlyklaborð"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Stilla <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Stilla vélbúnaðarlyklaborð"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Ýttu til að velja tungumál og útlit"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" AÁBCDÐEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789AÁBCDÐEÉFGHIÍJKLMNOÓPQRSTUÚVWXYÝZÞÆÖ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Heyrnartæki"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Hljóðstyrkstökkum haldið inni. Kveikt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Hljóðstyrkstökkum haldið inni. Slökkt á <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slepptu hljóðstyrkstökkunum. Til að kveikja á <xliff:g id="SERVICE_NAME">%1$s</xliff:g> skaltu halda báðum hljóðstyrkstökkunum aftur inni í 3 sekúndur."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Veldu eiginleika sem á að nota þegar ýtt er á aðgengishnappinn:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Veldu eiginleika sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með tveimur fingrum):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Veldu eiginleika sem á að nota með aðgengisbendingunni (strjúka upp frá neðri hluta skjásins með þremur fingrum):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> er að nota báða skjái til að sýna efni"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Tækið er of heitt"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Tveir skjáir eru ekki í boði vegna þess að síminn er of heitur"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Slökkva"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> er stillt"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Lyklaskipan er stillt á <xliff:g id="LAYOUT_1">%s</xliff:g>. Ýttu til að breyta."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Lyklaskipan er stillt á <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Ýttu til að breyta."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Lyklaskipan er stillt á <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Ýttu til að breyta."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Lyklaskipan er stillt á <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Ýttu til að breyta."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Vélbúnaðarlyklaborð eru stillt"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Ýttu til að sjá lyklaborð"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index d97254d..8cae14d 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -141,6 +141,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Chiamate Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Chiamata WiFi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Chiamata tramite Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Chiamata su rete mobile"</string>
@@ -1394,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Scegli il metodo di immissione"</string>
<string name="show_ime" msgid="6406112007347443383">"Tieni sullo schermo quando è attiva la tastiera fisica"</string>
<string name="hardware" msgid="1800597768237606953">"Mostra tastiera virtuale"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configura <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configura le tastiere fisiche"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tocca per selezionare la lingua e il layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Apparecchi acustici"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> attivato."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tieni premuti i tasti del volume. Servizio <xliff:g id="SERVICE_NAME">%1$s</xliff:g> disattivato."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Rilascia i tasti del volume. Per attivare <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, tieni di nuovo premuti entrambi i tasti del volume per 3 secondi."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Scegli una funzionalità da usare quando tocchi il pulsante Accessibilità:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Scegli una funzionalità da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con due dita):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Scegli una funzionalità da usare con il gesto di accessibilità (scorrimento verso l\'alto dalla parte inferiore dello schermo con tre dita):"</string>
@@ -1996,7 +1994,7 @@
<string name="app_info" msgid="6113278084877079851">"Informazioni app"</string>
<string name="negative_duration" msgid="1938335096972945232">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="demo_starting_message" msgid="6577581216125805905">"Avvio della demo…"</string>
- <string name="demo_restarting_message" msgid="1160053183701746766">"Ripristino del dispositivo…"</string>
+ <string name="demo_restarting_message" msgid="1160053183701746766">"Reset del dispositivo…"</string>
<string name="suspended_widget_accessibility" msgid="6331451091851326101">"Widget <xliff:g id="LABEL">%1$s</xliff:g> disattivato"</string>
<string name="conference_call" msgid="5731633152336490471">"Audioconferenza"</string>
<string name="tooltip_popup_title" msgid="7863719020269945722">"Descrizione comando"</string>
@@ -2327,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> sta usando entrambi i display per mostrare contenuti"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Il dispositivo è troppo caldo"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Il doppio schermo non è disponibile perché il telefono si sta surriscaldando"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Disattiva"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g> configurato"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Layout tastiera impostato su <xliff:g id="LAYOUT_1">%s</xliff:g>. Tocca per cambiare l\'impostazione."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Layout tastiera impostato su <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Tocca per cambiare l\'impostazione."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Layout tastiera impostato su <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Tocca per cambiare l\'impostazione."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Layout tastiera impostato su <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tocca per cambiare l\'impostazione."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Tastiere fisiche configurate"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tocca per visualizzare le tastiere"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index c8ce531..aa81d6a 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -141,6 +141,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"שיחות Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"כבוי"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"שיחה בחיבור Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"שיחה ברשת סלולרית"</string>
@@ -1394,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"בחירה של שיטת הזנה"</string>
<string name="show_ime" msgid="6406112007347443383">"להשאיר במסך בזמן שהמקלדת הפיזית פעילה"</string>
<string name="hardware" msgid="1800597768237606953">"הצגת מקלדת וירטואלית"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"הגדרה של <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"הגדרת מקלדות פיזיות"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"יש להקיש כדי לבחור שפה ופריסה"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"מכשירי שמיעה"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הופעל."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"לחצני עוצמת הקול נלחצו בלחיצה ארוכה. שירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g> הושבת."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"אפשר לשחרר את מקש עוצמת הקול. כדי להפעיל את השירות <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, צריך ללחוץ לחיצה ארוכה על שני המקשים של עוצמת הקול שוב במשך 3 שניות."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"צריך לבחור תכונה שתופעל כשלוחצים על לחצן הנגישות:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"יש לבחור תכונה שתופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שתי אצבעות):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"יש לבחור תכונה שתופעל באמצעות תנועת הנגישות (החלקה למעלה מתחתית המסך בעזרת שלוש אצבעות):"</string>
@@ -2327,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> משתמשת בשני המסכים כדי להציג תוכן"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"המכשיר חם מדי"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"מצב שני מסכים לא זמין כי הטלפון נהיה חם מדי"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"השבתה"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"המקלדת <xliff:g id="DEVICE_NAME">%s</xliff:g> הוגדרה"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%s</xliff:g>. אפשר להקיש כדי לשנות את ההגדרה הזו."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. אפשר להקיש כדי לשנות את ההגדרה הזו."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. אפשר להקיש כדי לשנות את ההגדרה הזו."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"פריסת המקלדת מוגדרת ל<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… אפשר להקיש כדי לשנות את ההגדרה הזו."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"הוגדרו מקלדות פיזיות"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"יש להקיש כדי להציג את המקלדות"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 44ba18e..7d2b2a5 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi 通話"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Wi-Fi 通話"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"OFF"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi 経由で通話"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"モバイル ネットワーク経由で通話"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"入力方法の選択"</string>
<string name="show_ime" msgid="6406112007347443383">"物理キーボードが有効になっていても画面に表示させます"</string>
<string name="hardware" msgid="1800597768237606953">"仮想キーボードの表示"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>の設定"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"物理キーボードの設定"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"タップして言語とレイアウトを選択してください"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"補聴器"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が ON になりました。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"音量ボタンを長押ししました。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> が OFF になりました。"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"音量ボタンを離してください。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> を有効にするには音量大と音量小の両方のボタンを 3 秒ほど長押ししてください。"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ユーザー補助機能ボタンをタップした場合に使用する機能を選択してください。"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ユーザー補助操作(2 本の指で画面の下から上にスワイプ)で使用する機能を選択してください。"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ユーザー補助操作(3 本の指で画面の下から上にスワイプ)で使用する機能を選択してください。"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>は 2 画面でコンテンツを表示しています"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"デバイスが熱くなりすぎています"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"スマートフォンが熱くなりすぎているため、デュアル スクリーンを使用できません"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"オフにする"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g>の設定完了"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%s</xliff:g>に設定されています。タップすると変更できます。"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>に設定されています。タップすると変更できます。"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>に設定されています。タップすると変更できます。"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"キーボードのレイアウトは<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>に設定されています。タップすると変更できます。"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"物理キーボードの設定完了"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"タップするとキーボードを表示できます"</string>
</resources>
diff --git a/core/res/res/values-ka/strings.xml b/core/res/res/values-ka/strings.xml
index e472973..7fdb8d9 100644
--- a/core/res/res/values-ka/strings.xml
+++ b/core/res/res/values-ka/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi დარეკვა"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Wi-Fi-ს გამოყენებით დარეკვა"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"გამორთული"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"დარეკვა Wi-Fi-ის მეშვეობით"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"დარეკვა მობილური ქსელის მეშვეობით"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"აირჩიეთ შეყვანის მეთოდი"</string>
<string name="show_ime" msgid="6406112007347443383">"აქტიური ფიზიკური კლავიატურისას ეკრანზე შენარჩუნება"</string>
<string name="hardware" msgid="1800597768237606953">"ვირტუალური კლავიატურის ჩვენება"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"მოახდინეთ <xliff:g id="DEVICE_NAME">%s</xliff:g>-ის კონფიგურირება"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"მოახდინეთ ფიზიკური კლავიატურების კონფიგურირება"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"შეეხეთ ენისა და განლაგების ასარჩევად"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"სმენის აპარატები"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ჩართულია."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ხანგრძლივად დააჭირეთ ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> გამორთულია."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ხელი აუშვით ხმის ღილაკებს. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-ის ჩასართველად, ხელმეორედ ხანგრძლივად დააჭირეთ ორივე ხმის ღილაკს 3 წამის განმავლობაში."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"აირჩიეთ მარტივი წვდომის ღილაკზე შეხებისას გამოსაყენებელი ფუნქცია:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"აირჩიეთ მარტივი წვდომის ჟესტთან (ორი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი ფუნქცია:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"აირჩიეთ მარტივი წვდომის ჟესტთან (სამი თითით გადაფურცვლა ეკრანის ქვედა კიდიდან ზემოთ) გამოსაყენებელი ფუნქცია:"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> იყენებს ორივე ეკრანს შინაარსის საჩვენებლად"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"მოწყობილობა ძალიან თბილია"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ორმაგი ეკრანი მიუწვდომელია, რადგან თქვენი ტელეფონი ძალიან თბება"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"გამორთვა"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> კონფიგურირებულია"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"დაყენდა კლავიატურის განლაგება: <xliff:g id="LAYOUT_1">%s</xliff:g>. შეეხეთ შესაცვლელად."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"დაყენდა კლავიატურის განლაგება: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. შეეხეთ შესაცვლელად."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"დაყენდა კლავიატურის განლაგება: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. შეეხეთ შესაცვლელად."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"დაყენდა კლავიატურის განლაგება: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… შეეხეთ შესაცვლელად."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ფიზიკური კლავიატურები კონფიგურირებულია"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"შეეხეთ კლავიატურების სანახავად"</string>
</resources>
diff --git a/core/res/res/values-kk/strings.xml b/core/res/res/values-kk/strings.xml
index 2959b25..32e3f59 100644
--- a/core/res/res/values-kk/strings.xml
+++ b/core/res/res/values-kk/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi қоңыраулары"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Өшірулі"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi арқылы қоңырау шалу"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Мобильдік желі арқылы қоңырау шалу"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Енгізу әдісін таңдау"</string>
<string name="show_ime" msgid="6406112007347443383">"Физикалық пернетақта қосулы кезде оны экранға шығару"</string>
<string name="hardware" msgid="1800597768237606953">"Виртуалдық пернетақтаны көрсету"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> конфигурациялау"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Физикалық пернетақталарды конфигурациялау"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Тіл мен пернетақта схемасын таңдау үшін түртіңіз"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Есту аппараттары"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Пайдаланушы дыбыс деңгейі пернелерін басып ұстап тұрды. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қосулы."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дыбыс деңгейі пернелерін басып тұрған соң, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өшірілді."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дыбыс деңгейі пернелерін жіберіңіз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> қызметін қосу үшін дыбыс деңгейі пернесінің екеуін де қайтадан 3 секундқа басып тұрыңыз."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"\"Арнайы мүмкіндіктер\" түймесін түрткенде пайдаланатын функцияны таңдаңыз:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Арнайы мүмкіндіктер қимылымен (екі саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз) пайдаланатын функцияны таңдаңыз:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Арнайы мүмкіндіктер қимылымен (үш саусақпен экранның төменгі жағынан жоғары қарай сырғытыңыз) пайдаланатын функцияны таңдаңыз:"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы контентті көрсету үшін екі дисплейді де пайдаланады."</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Құрылғы қатты қызып кетті."</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Қос экран функциясы істемейді, себебі телефон қатты қызып кетеді."</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Өшіру"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> конфигурацияланды"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Пернетақта форматы <xliff:g id="LAYOUT_1">%s</xliff:g> деп орнатылды. Өзгерту үшін түртіңіз."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Пернетақта форматы <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> деп орнатылды. Өзгерту үшін түртіңіз."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Пернетақта форматы <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> деп орнатылды. Өзгерту үшін түртіңіз."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Пернетақта форматы <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> деп орнатылды… Өзгерту үшін түртіңіз."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физикалық пернетақталар конфигурацияланды"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Пернетақталарды көру үшін түртіңіз."</string>
</resources>
diff --git a/core/res/res/values-km/strings.xml b/core/res/res/values-km/strings.xml
index abe3213..1f72495 100644
--- a/core/res/res/values-km/strings.xml
+++ b/core/res/res/values-km/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"ការហៅតាម Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"បិទ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"ហៅទូរសព្ទតាមរយៈ Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"ហៅទូរសព្ទតាមរយៈបណ្តាញទូរសព្ទចល័ត"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ជ្រើសវិធីសាស្ត្របញ្ចូល"</string>
<string name="show_ime" msgid="6406112007347443383">"ទុកវានៅលើអេក្រង់ខណៈពេលក្តារចុចពិតប្រាកដកំពុងសកម្ម"</string>
<string name="hardware" msgid="1800597768237606953">"បង្ហាញក្ដារចុចនិម្មិត"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"កំណត់រចនាសម្ព័ន្ធ <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"កំណត់រចនាសម្ព័ន្ធក្ដារចុចរូបវន្ត"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ប៉ះដើម្បីជ្រើសភាសា និងប្លង់"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ឧបករណ៍ស្តាប់"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"បានសង្កត់គ្រាប់ចុចកម្រិតសំឡេងជាប់។ បានបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"បានសង្កត់គ្រាប់ចុចកម្រិតសំឡេងជាប់។ បានបិទ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>។"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"លែងគ្រាប់ចុចកម្រិតសំឡេង។ ដើម្បីបើក <xliff:g id="SERVICE_NAME">%1$s</xliff:g> សូមចុចគ្រាប់ចុចកម្រិតសំឡេងទាំងពីរឱ្យជាប់ម្ដងទៀតរយៈពេល 3 វិនាទី។"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ជ្រើសរើសមុខងារដែលត្រូវប្រើ នៅពេលដែលអ្នកចុចប៊ូតុងភាពងាយស្រួល៖"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ជ្រើសរើសមុខងារ ដើម្បីប្រើជាមួយចលនាភាពងាយស្រួល (អូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់ដោយប្រើម្រាមដៃពីរ)៖"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ជ្រើសរើសមុខងារ ដើម្បីប្រើជាមួយចលនាភាពងាយស្រួល (អូសឡើងលើពីផ្នែកខាងក្រោមនៃអេក្រង់ដោយប្រើម្រាមដៃបី)៖"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងប្រើផ្ទាំងអេក្រង់ទាំងពីរដើម្បីបង្ហាញខ្លឹមសារ"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ឧបករណ៍ក្តៅពេក"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"អេក្រង់ពីរមិនអាចប្រើបានទេ ដោយសារទូរសព្ទរបស់អ្នកឡើងក្តៅពេក"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"បិទ"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"បានកំណត់រចនាសម្ព័ន្ធ <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%s</xliff:g>។ សូមចុចដើម្បីប្ដូរ។"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>។ សូមចុចដើម្បីប្ដូរ។"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>។ សូមចុចដើម្បីប្ដូរ។"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"បានកំណត់ប្លង់ក្ដារចុចទៅ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… សូមចុចដើម្បីប្ដូរ។"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"បានកំណត់រចនាសម្ព័ន្ធក្ដារចុចរូបវន្ត"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ចុចដើម្បីមើលក្ដារចុច"</string>
</resources>
diff --git a/core/res/res/values-kn/strings.xml b/core/res/res/values-kn/strings.xml
index 1f24e7d..062cc67 100644
--- a/core/res/res/values-kn/strings.xml
+++ b/core/res/res/values-kn/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"ವೈ-ಫೈ"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"ವೈಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ಆಫ್"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"ವೈ-ಫೈ ಬಳಸಿ ಕರೆ ಮಾಡಿ"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"ಮೊಬೈಲ್ ನೆಟ್ವರ್ಕ್ ಬಳಸಿ ಕರೆ ಮಾಡಿ"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ಇನ್ಪುಟ್ ವಿಧಾನವನ್ನು ಆರಿಸಿ"</string>
<string name="show_ime" msgid="6406112007347443383">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ ಸಕ್ರಿಯವಾಗಿರುವಾಗ ಅದನ್ನು ಪರದೆಯ ಮೇಲಿರಿಸಿ"</string>
<string name="hardware" msgid="1800597768237606953">"ವರ್ಚುವಲ್ ಕೀಬೋರ್ಡ್ ತೋರಿಸಿ"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಿ"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ಭಾಷೆ ಮತ್ತು ವಿನ್ಯಾಸವನ್ನು ಆಯ್ಕೆ ಮಾಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ಶ್ರವಣ ಸಾಧನಗಳು"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದುಕೊಳ್ಳಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲಾಗಿದೆ."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಹಿಡಿದಿಟ್ಟುಕೊಳ್ಳಲಾಗಿದೆ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ಆಫ್ ಮಾಡಲಾಗಿದೆ."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಬಿಡುಗಡೆ ಮಾಡಿ. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ಅನ್ನು ಆನ್ ಮಾಡಲು, ಎರಡೂ ವಾಲ್ಯೂಮ್ ಕೀಗಳನ್ನು ಮತ್ತೊಮ್ಮೆ 3 ಸೆಕೆಂಡ್ಗಳ ಕಾಲ ಒತ್ತಿ ಹಿಡಿದುಕೊಳ್ಳಿ."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ನೀವು ಪ್ರವೇಶಿಸುವಿಕೆ ಬಟನ್ ಟ್ಯಾಪ್ ಮಾಡಿದಾಗ ಬಳಸುವುದಕ್ಕಾಗಿ ವೈಶಿಷ್ಟ್ಯವೊಂದನ್ನು ಆರಿಸಿ:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ಪ್ರವೇಶಿಸುವಿಕೆ ಗೆಸ್ಚರ್ನೊಂದಿಗೆ ಬಳಸಲು ವೈಶಿಷ್ಟ್ಯವೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಎರಡು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ಪ್ರವೇಶಿಸುವಿಕೆ ಗೆಸ್ಚರ್ನೊಂದಿಗೆ ಬಳಸಲು ವೈಶಿಷ್ಟ್ಯವೊಂದನ್ನು ಆಯ್ಕೆಮಾಡಿ (ಮೂರು ಬೆರಳುಗಳನ್ನು ಬಳಸಿ ಪರದೆಯ ಕೆಳಭಾಗದಿಂದ ಮೇಲಕ್ಕೆ ಸ್ವೈಪ್ ಮಾಡಿ):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"ವಿಷಯವನ್ನು ತೋರಿಸಲು <xliff:g id="APP_NAME">%1$s</xliff:g> ಎರಡೂ ಡಿಸ್ಪ್ಲೇಗಳನ್ನು ಬಳಸುತ್ತದೆ"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ಸಾಧನವು ತುಂಬಾ ಬಿಸಿಯಾಗಿದೆ"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ನಿಮ್ಮ ಫೋನ್ ತುಂಬಾ ಬಿಸಿಯಾಗುವುದರಿಂದ ಡ್ಯೂಯಲ್ ಸ್ಕ್ರೀನ್ ಲಭ್ಯವಿಲ್ಲ"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ಆಫ್ ಮಾಡಿ"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿದೆ"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಅನ್ನು <xliff:g id="LAYOUT_1">%s</xliff:g> ಗೆ ಸೆಟ್ ಮಾಡಲಾಗಿದೆ. ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಅನ್ನು <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> ಗೆ ಸೆಟ್ ಮಾಡಲಾಗಿದೆ. ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಅನ್ನು <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ಗೆ ಸೆಟ್ ಮಾಡಲಾಗಿದೆ. ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ಕೀಬೋರ್ಡ್ ಲೇಔಟ್ ಅನ್ನು <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ಗೆ ಸೆಟ್ ಮಾಡಲಾಗಿದೆ… ಬದಲಾಯಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ಭೌತಿಕ ಕೀಬೋರ್ಡ್ಗಳನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಲಾಗಿದೆ"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ಕೀಬೋರ್ಡ್ಗಳನ್ನು ವೀಕ್ಷಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 02b797c..5a982e5 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi 통화"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"꺼짐"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi를 통해 통화"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"모바일 네트워크를 통해 통화"</string>
@@ -1356,7 +1358,7 @@
<string name="no_permissions" msgid="5729199278862516390">"권한 필요 없음"</string>
<string name="perm_costs_money" msgid="749054595022779685">"비용이 부과될 수 있습니다."</string>
<string name="dlg_ok" msgid="5103447663504839312">"확인"</string>
- <string name="usb_charging_notification_title" msgid="1674124518282666955">"이 기기를 USB로 충전 중"</string>
+ <string name="usb_charging_notification_title" msgid="1674124518282666955">"이 기기를 USB로 충전 중."</string>
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"USB를 통해 연결된 기기 충전"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"USB 파일 전송 사용 설정됨"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"USB를 통해 PTP 사용 설정됨"</string>
@@ -1368,7 +1370,7 @@
<string name="usb_power_notification_message" msgid="7284765627437897702">"연결된 기기를 충전합니다. 옵션을 더 보려면 탭하세요."</string>
<string name="usb_unsupported_audio_accessory_title" msgid="2335775548086533065">"아날로그 오디오 액세서리가 감지됨"</string>
<string name="usb_unsupported_audio_accessory_message" msgid="1300168007129796621">"연결된 기기가 이 휴대전화와 호환되지 않습니다. 자세히 알아보려면 탭하세요."</string>
- <string name="adb_active_notification_title" msgid="408390247354560331">"USB 디버깅 연결됨"</string>
+ <string name="adb_active_notification_title" msgid="408390247354560331">"USB 디버깅 연결됨."</string>
<string name="adb_active_notification_message" msgid="5617264033476778211">"USB 디버깅을 사용 중지하려면 탭하세요."</string>
<string name="adb_active_notification_message" product="tv" msgid="6624498401272780855">"USB 디버깅을 사용하지 않으려면 선택합니다."</string>
<string name="adbwifi_active_notification_title" msgid="6147343659168302473">"무선 디버깅 연결됨"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"입력 방법 선택"</string>
<string name="show_ime" msgid="6406112007347443383">"물리적 키보드가 활성 상태인 경우 화면에 켜 둠"</string>
<string name="hardware" msgid="1800597768237606953">"가상 키보드 표시"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> 설정"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"실제 키보드 설정"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"탭하여 언어와 레이아웃을 선택하세요."</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"보청기"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 설정되었습니다."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"볼륨 키를 길게 눌렀습니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>이(가) 사용 중지되었습니다."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"볼륨 키에서 손을 뗍니다. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>을 켜려면 볼륨 키 2개를 3초 동안 길게 누르세요."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"접근성 버튼을 탭할 때 사용할 기능을 선택하세요."</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"접근성 동작(두 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 기능을 선택하세요."</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"접근성 동작(세 손가락을 사용하여 화면 하단에서 위로 스와이프)으로 실행할 기능을 선택하세요."</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 두 화면을 모두 사용하여 콘텐츠를 표시합니다."</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"기기 온도가 너무 높음"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"휴대전화 온도가 너무 높아지고 있으므로 듀얼 스크린을 사용할 수 없습니다."</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"사용 중지"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g>에 설정 완료됨"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%s</xliff:g>(으)로 설정됩니다. 변경하려면 탭하세요."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g> 및 <xliff:g id="LAYOUT_2">%2$s</xliff:g>(으)로 설정됩니다. 변경하려면 탭하세요."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>(으)로 설정됩니다. 변경하려면 탭하세요."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"키보드 레이아웃이 <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>(으)로 설정됩니다. 변경하려면 탭하세요."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"실제 키보드에 구성됨"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"키보드를 보려면 탭하세요."</string>
</resources>
diff --git a/core/res/res/values-ky/strings.xml b/core/res/res/values-ky/strings.xml
index f87be7c..48c2c7b 100644
--- a/core/res/res/values-ky/strings.xml
+++ b/core/res/res/values-ky/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi‑Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi аркылуу чалынууда"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Өчүк"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi аркылуу чалуу"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Мобилдик тармак аркылуу чалуу"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Дайын киргизүү ыкмасын тандаңыз"</string>
<string name="show_ime" msgid="6406112007347443383">"Баскычтоп иштетилгенде экранда көрүнүп турат"</string>
<string name="hardware" msgid="1800597768237606953">"Виртуалдык баскычтоп"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> түзмөгүн конфигурациялоо"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Физикалык баскычтопторду конфигурациялоо"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Тил жана калып тандоо үчүн таптап коюңуз"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Угуу түзмөктөрү"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> күйгүзүлдү."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Үндү катуулатуу/акырындатуу баскычтары басылып, <xliff:g id="SERVICE_NAME">%1$s</xliff:g> өчүрүлдү."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Үн баскычтарын коё бериңиз. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> кызматын күйгүзүү үчүн үн баскычтарын кайра 3 секунд коё бербей басып туруңуз."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Атайын мүмкүнчүлүктөр баскычын таптаганыңызда иштей турган функцияны тандаңыз:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Атайын мүмкүнчүлүктөр жаңсоосу үчүн функцияны тандаңыз (эки манжаңыз менен экранды ылдыйдан өйдө сүрүңүз):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Атайын мүмкүнчүлүктөр жаңсоосу аркылуу иштетиле турган функцияны тандаңыз (үч манжаңыз менен экранды ылдыйдан өйдө сүрүңүз):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> контентти эки түзмөктө тең көрсөтүүдө"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Түзмөк ысып кетти"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Телефонуңуз ысып кеткендиктен, Кош экран функциясы жеткиликсиз"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Өчүрүү"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> конфигурацияланды"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Баскычтоп калыбы төмөнкүгө коюлду: <xliff:g id="LAYOUT_1">%s</xliff:g>. Өзгөртүү үчүн басыңыз."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Баскычтоп калыбы төмөнкүгө коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Өзгөртүү үчүн басыңыз."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Баскычтоп калыбы төмөнкүгө коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Өзгөртүү үчүн басыңыз."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Баскычтоп калыбы төмөнкүгө коюлду: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Өзгөртүү үчүн басыңыз."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физикалык баскычтоптор конфигурацияланды"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Баскычтопторду көрүү үчүн басыңыз"</string>
</resources>
diff --git a/core/res/res/values-lo/strings.xml b/core/res/res/values-lo/strings.xml
index 9366586..5b67814 100644
--- a/core/res/res/values-lo/strings.xml
+++ b/core/res/res/values-lo/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"ການໂທ Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ປິດ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"ໂທຜ່ານ Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"ໂທຜ່ານເຄືອຂ່າຍມືຖື"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ເລືອກຮູບແບບການປ້ອນ"</string>
<string name="show_ime" msgid="6406112007347443383">"ເປີດໃຊ້ໃຫ້ມັນຢູ່ໃນໜ້າຈໍໃນຂະນະທີ່ໃຊ້ແປ້ນພິມພາຍນອກຢູ່"</string>
<string name="hardware" msgid="1800597768237606953">"ສະແດງແປ້ນພິມສະເໝືອນ"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"ຕັ້ງຄ່າ <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ຕັ້ງຄ່າແປ້ນພິມແທ້"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ແຕະເພື່ອເລືອກພາສາ ແລະ ໂຄງແປ້ນພິມ"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ອຸປະກອນຊ່ວຍຟັງ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ເປີດໃຊ້ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ແລ້ວ."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ກົດປຸ່ມລະດັບສຽງຄ້າງໄວ້. ປິດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ໄວ້ແລ້ວ."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ປ່ອຍປຸ່ມລະດັບສຽງ. ເພື່ອເປີດ <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, ໃຫ້ກົດປຸ່ມລະດັບສຽງທັງສອງຄ້າງໄວ້ 3 ວິນາທີ."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ເລືອກຄຸນສົມບັດທີ່ຈະໃຊ້ເມື່ອທ່ານແຕະປຸ່ມການຊ່ວຍເຂົ້າເຖິງ:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ເລືອກຄຸນສົມບັດເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສອງນິ້ວ):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ເລືອກຄຸນສົມບັດເພື່ອໃຊ້ກັບທ່າທາງການຊ່ວຍເຂົ້າເຖິງ (ປັດຂຶ້ນຈາກລຸ່ມສຸດຂອງໜ້າຈໍດ້ວຍສາມນິ້ວ):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງໃຊ້ຈໍສະແດງຜົນທັງສອງເພື່ອສະແດງເນື້ອຫາ"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ອຸປະກອນຮ້ອນເກີນໄປ"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ໜ້າຈໍຄູ່ບໍ່ພ້ອມໃຫ້ນຳໃຊ້ເນື່ອງຈາກໂທລະສັບຂອງທ່ານຮ້ອນເກີນໄປ"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ປິດໄວ້"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"ຕັ້ງຄ່າ <xliff:g id="DEVICE_NAME">%s</xliff:g> ແລ້ວ"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"ຕັ້ງຄ່າໂຄງຮ່າງແປ້ນພິມເປັນ <xliff:g id="LAYOUT_1">%s</xliff:g>. ແຕະເພື່ອປ່ຽນ."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"ຕັ້ງໂຄງຮ່າງແປ້ນພິມເປັນ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. ແຕະເພື່ອປ່ຽນ."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"ຕັ້ງໂຄງຮ່າງແປ້ນພິມເປັນ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. ແຕະເພື່ອປ່ຽນ."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ຕັ້ງໂຄງຮ່າງແປ້ນພິມເປັນ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… ແຕະເພື່ອປ່ຽນແປງ."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ຕັ້ງຄ່າແປ້ນພິມແທ້ແລ້ວ"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ແຕະເພື່ອເບິ່ງແປ້ນພິມ"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 35a2715..6793454 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -142,6 +142,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"„Wi-Fi“ skambinimas"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Išjungta"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Skambinimas naudojant „Wi-Fi“"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Skambinimas naudojant mobiliojo ryšio tinklą"</string>
@@ -1395,10 +1397,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Pasirinkite įvesties metodą"</string>
<string name="show_ime" msgid="6406112007347443383">"Palikti ekrane, kol fizinė klaviatūra aktyvi"</string>
<string name="hardware" msgid="1800597768237606953">"Rodyti virtualiąją klaviatūrą"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"„<xliff:g id="DEVICE_NAME">%s</xliff:g>“ konfigūravimas"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fizinių klaviatūrų konfigūravimas"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Palieskite, kad pasirinktumėte kalbą ir išdėstymą"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789AĄBCČDEĘĖFGHIĮYJKLMNOPRSŠTUŲŪVZŽ"</string>
@@ -1723,8 +1723,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Klausos įrenginiai"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ įjungta."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Laikomi garsumo klavišai. „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“ išjungta."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Atleiskite garsumo klavišus. Kad įjungtumėte „<xliff:g id="SERVICE_NAME">%1$s</xliff:g>“, paspauskite ir 3 sekundes palaikykite garsumo klavišus."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pasirinkite funkciją, kuri bus naudojama, kai paliesite pritaikomumo mygtuką:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pasirinkite funkciją, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn dviem pirštais iš ekrano apačios):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pasirinkite funkciją, kuri bus naudojama su pritaikomumo gestu (perbraukimas aukštyn trimis pirštais iš ekrano apačios):"</string>
@@ -2328,19 +2327,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ naudoja abu ekranus turiniui rodyti"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Įrenginys per daug kaista"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvigubas ekranas nepasiekiamas, nes telefonas per daug kaista"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Išjungti"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Įrenginys „<xliff:g id="DEVICE_NAME">%s</xliff:g>“ sukonfigūruotas"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%s</xliff:g>. Palieskite, kad pakeistumėte."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Palieskite, kad pakeistumėte."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Palieskite, kad pakeistumėte."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klaviatūros išdėstymas nustatytas į <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Palieskite, kad pakeistumėte."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Sukonfigūruotos fizinės klaviatūros"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Palieskite, kad peržiūrėtumėte klaviatūras"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index b27c3d3..56f2241 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -141,6 +141,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi zvani"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Izslēgts"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Zvani Wi-Fi tīklā"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Zvani mobilajā tīklā"</string>
@@ -1394,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Ievades metodes izvēle"</string>
<string name="show_ime" msgid="6406112007347443383">"Paturēt ekrānā, kamēr ir aktīva fiziskā tastatūra"</string>
<string name="hardware" msgid="1800597768237606953">"Virtuālās tastatūras rādīšana"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Jākonfigurē <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurējiet fiziskās tastatūras"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Pieskarieties, lai atlasītu valodu un izkārtojumu"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789AĀBCČDEĒFGĢHIĪJKĶLĻMNŅOPRSŠTUŪVZŽ"</string>
@@ -1722,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Dzirdes aparāti"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika ieslēgts."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Turējāt nospiestas skaļuma pogas. Pakalpojums <xliff:g id="SERVICE_NAME">%1$s</xliff:g> tika izslēgts."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Atlaidiet skaļuma pogas. Lai ieslēgtu pakalpojumu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, vēlreiz nospiediet un trīs sekundes turiet nospiestas abas skaļuma pogas."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izvēlieties funkciju, ko izmantot, kad pieskaraties pieejamības pogai."</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar diviem pirkstiem augšup no ekrāna apakšdaļas)."</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Izvēlieties funkciju, ko izmantot ar pieejamības žestu (vilkšana ar trīs pirkstiem augšup no ekrāna apakšdaļas)."</string>
@@ -2327,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> satura rādīšanai izmanto abus displejus."</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Ierīce ir pārāk sakarsusi"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Divu ekrānu režīms nav pieejams, jo tālrunis sāk pārāk sakarst."</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Izslēgt"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ir konfigurēta"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Ir iestatīts šāds tastatūras izkārtojums: <xliff:g id="LAYOUT_1">%s</xliff:g>. Lai to mainītu, pieskarieties."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Ir iestatīti šādi tastatūras izkārtojumi: <xliff:g id="LAYOUT_1">%1$s</xliff:g> un <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Lai to mainītu, pieskarieties."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Ir iestatīti šādi tastatūras izkārtojumi: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> un <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Lai to mainītu, pieskarieties."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ir iestatīti šādi tastatūras izkārtojumi: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Lai to mainītu, pieskarieties."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fiziskās tastatūras ir konfigurētas"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Lai skatītu tastatūras, pieskarieties"</string>
</resources>
diff --git a/core/res/res/values-mk/strings.xml b/core/res/res/values-mk/strings.xml
index 2179895..1002bdf 100644
--- a/core/res/res/values-mk/strings.xml
+++ b/core/res/res/values-mk/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Повикување преку Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"Глас преку Wi-Fi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Исклучено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Повикувај преку Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Повикувај преку мобилна мрежа"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Одбери метод на внес"</string>
<string name="show_ime" msgid="6406112007347443383">"Прикажувај ја на екранот додека е активна физичката тастатура"</string>
<string name="hardware" msgid="1800597768237606953">"Прикажи виртуелна тастатура"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Конфигурирање на <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Конфигурирање физички тастатури"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Допрете за избирање јазик и распоред"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слушни помагала"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е вклучена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ги задржавте копчињата за јачина на звук. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> е исклучена."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Ослободете ги копчињата за јачина на звукот. Притиснете ги и задржете ги двете копчиња за јачина на звукот во траење од 3 секунди за да вклучите <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изберете функција за користење кога ќе го допрете копчето за пристапност:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со два прста):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Изберете ја функцијата што ќе ја користите со движењето за пристапност (повлекување нагоре од дното на екранот со три прста):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ги користи двата екрани за да прикажува содржини"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Уредот е претопол"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Двојниот екран е недостапен бидејќи вашиот телефон станува претопол"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Исклучи"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> е конфигуриран"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Распоредот на тастатурата е поставен на <xliff:g id="LAYOUT_1">%s</xliff:g>. Допрете за да промените."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Распоредот на тастатурата е поставен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Допрете за да промените."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Распоредот на тастатурата е поставен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Допрете за да промените."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Распоредот на тастатурата е поставен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Допрете за да промените."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физичките тастатури се конфигурирани"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Допрете за да ги видите тастатурите"</string>
</resources>
diff --git a/core/res/res/values-ml/strings.xml b/core/res/res/values-ml/strings.xml
index d568bb8..7e08328 100644
--- a/core/res/res/values-ml/strings.xml
+++ b/core/res/res/values-ml/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"വൈഫൈ"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"വൈഫൈ കോളിംഗ്"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"Voവൈഫൈ"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ഓഫ്"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"വൈഫൈ മുഖേനയുള്ള കോൾ"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"മൊബൈൽ നെറ്റ്വർക്ക് മുഖേനയുള്ള കോൾ"</string>
@@ -1176,7 +1178,7 @@
<string name="not_checked" msgid="7972320087569023342">"പരിശോധിക്കാത്തത്"</string>
<string name="selected" msgid="6614607926197755875">"തിരഞ്ഞെടുത്തു"</string>
<string name="not_selected" msgid="410652016565864475">"തിരഞ്ഞെടുത്തിട്ടില്ല"</string>
- <string name="rating_label" msgid="1837085249662154601">"{rating,plural, =1{{max}-ൽ ഒരു നക്ഷത്ര ചിഹ്നം}other{{max}-ൽ # നക്ഷത്ര ചിഹ്നം}}"</string>
+ <string name="rating_label" msgid="1837085249662154601">"{rating,plural, =1{{max}-ൽ ഒരു സ്റ്റാർ}other{{max}-ൽ # സ്റ്റാർ}}"</string>
<string name="in_progress" msgid="2149208189184319441">"പുരോഗതിയിലാണ്"</string>
<string name="whichApplication" msgid="5432266899591255759">"പൂർണ്ണമായ പ്രവർത്തനം ഉപയോഗിക്കുന്നു"</string>
<string name="whichApplicationNamed" msgid="6969946041713975681">"%1$s ഉപയോഗിച്ച് പ്രവർത്തനം പൂർത്തിയാക്കുക"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ഇൻപുട്ട് രീതി തിരഞ്ഞെടുക്കുക"</string>
<string name="show_ime" msgid="6406112007347443383">"ഫിസിക്കൽ കീബോർഡ് സജീവമായിരിക്കുമ്പോൾ സ്ക്രീനിൽ നിലനിർത്തുക"</string>
<string name="hardware" msgid="1800597768237606953">"വെർച്വൽ കീബോർഡ് കാണിക്കുക"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> കോൺഫിഗർ ചെയ്യുക"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"യഥാർത്ഥ കീബോർഡുകൾ കോൺഫിഗർ ചെയ്യുക"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ഭാഷയും ലേഔട്ടും തിരഞ്ഞെടുക്കുന്നതിന് ടാപ്പ് ചെയ്യുക"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ശ്രവണ ഉപകരണങ്ങൾ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"വോളിയം കീകൾ പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കി."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"വോളിയം കീകൾ അമർത്തിപ്പിടിച്ചു. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓഫാക്കി."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"വോളിയം കീകൾ വിടുക. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ഓണാക്കാൻ, രണ്ട് വോളിയം കീകളും വീണ്ടും മൂന്ന് സെക്കൻഡ് അമർത്തിപ്പിടിക്കുക."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"നിങ്ങൾ ഉപയോഗസഹായി ബട്ടൺ ടാപ്പ് ചെയ്യുമ്പോൾ ഉപയോഗിക്കുന്നതിന് ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക (രണ്ട് വിരലുകളുപയോഗിച്ച് സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ഉപയോഗസഹായി വിരൽചലനത്തോടൊപ്പം ഉപയോഗിക്കാൻ ഒരു ഫീച്ചർ തിരഞ്ഞെടുക്കുക (മൂന്ന് വിരലുകളുപയോഗിച്ച് സ്ക്രീനിന്റെ താഴെ നിന്ന് മുകളിലോട്ട് സ്വൈപ്പ് ചെയ്യുക):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"ഉള്ളടക്കം കാണിക്കാൻ <xliff:g id="APP_NAME">%1$s</xliff:g> രണ്ട് ഡിസ്പ്ലേകളും ഉപയോഗിക്കുന്നു"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ഉപകരണത്തിന് ചൂട് കൂടുതലാണ്"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"നിങ്ങളുടെ ഫോൺ വളരെയധികം ചൂടാകുന്നതിനാൽ ഡ്യുവൽ സ്ക്രീൻ ലഭ്യമല്ല"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ഓഫാക്കുക"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> കോൺഫിഗർ ചെയ്തു"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"കീബോർഡ് ലേഔട്ട് ആയി <xliff:g id="LAYOUT_1">%s</xliff:g> സജ്ജീകരിച്ചു. മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"കീബോർഡ് ലേഔട്ട് ആയി <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> എന്നിവ സജ്ജീകരിച്ചു. മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"കീബോർഡ് ലേഔട്ട് ആയി <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> എന്നിവ സജ്ജീകരിച്ചു. മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"കീബോർഡ് ലേഔട്ട് ആയി ഇനിപ്പറയുന്നവ സജ്ജീകരിച്ചു: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… മാറ്റാൻ ടാപ്പ് ചെയ്യുക."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"യഥാർത്ഥ കീബോർഡുകൾ കോൺഫിഗർ ചെയ്തു"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"കീബോർഡുകൾ കാണാൻ ടാപ്പ് ചെയ്യുക"</string>
</resources>
diff --git a/core/res/res/values-mn/strings.xml b/core/res/res/values-mn/strings.xml
index f924dd7..b83f9fd 100644
--- a/core/res/res/values-mn/strings.xml
+++ b/core/res/res/values-mn/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi дуудлага"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Идэвхгүй"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi-р залгах"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Мобайл сүлжээгээр дуудлага хийх"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Оруулах аргыг сонгоно уу"</string>
<string name="show_ime" msgid="6406112007347443383">"Биет гар идэвхтэй үед үүнийг дэлгэцэд харуулна уу"</string>
<string name="hardware" msgid="1800597768237606953">"Хийсвэр гарыг харуулах"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>-г тохируулна уу"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Биет гарыг тохируулна уу"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Хэл болон бүдүүвчийг сонгохын тулд дарна уу"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Сонсголын төхөөрөмжүүд"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаалаа."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Дууны түвшний түлхүүрийг удаан дарсан. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г унтраалаа."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Дууны түвшний товчнуудыг суллана уу. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>-г асаахын тулд дууны түвшний 2 товчийг зэрэг 3 секундийн турш удаан дарна уу."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Хандалтын товчлуурыг товшихдоо ашиглах онцлогийг сонгоно уу:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Хандалтын зангаагаар ашиглах үйлчилгээг сонгоно уу (хоёр хуруугаараа дэлгэцийн доороос дээш хоёр хуруугаар шударна уу):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Хандалтын зангаагаар ашиглах онцлогийг сонгоно уу (гурван хуруугаар дэлгэцийн доороос дээш шударна уу):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> контент харуулахын тулд хоёр дэлгэцийг хоёуланг нь ашиглаж байна"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Төхөөрөмж хэт халуун байна"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Таны утас хэт халж байгаа тул Хоёр дэлгэц боломжгүй байна"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Унтраах"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g>-г тохируулсан"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Гарын бүдүүвчийг <xliff:g id="LAYOUT_1">%s</xliff:g> болгож тохируулсан. Өөрчлөхийн тулд товшино уу."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Гарын бүдүүвчийг <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> болгож тохируулсан. Өөрчлөхийн тулд товшино уу."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Гарын бүдүүвчийг <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> болгож тохируулсан. Өөрчлөхийн тулд товшино уу."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Гарын бүдүүвчийг <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> болгож тохируулсан… Өөрчлөхийн тулд товшино уу."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Биет гарыг тохируулсан"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Гарыг харахын тулд товшино уу"</string>
</resources>
diff --git a/core/res/res/values-mr/strings.xml b/core/res/res/values-mr/strings.xml
index 48df544..4da7c71 100644
--- a/core/res/res/values-mr/strings.xml
+++ b/core/res/res/values-mr/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"वाय-फाय"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"वायफाय कॉलिंग"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"वायफाय कॉल"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"बंद"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"वाय-फायवरून कॉल करा"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"मोबाइल नेटवर्कवरून कॉल करा"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"इनपुट पद्धत निवडा"</string>
<string name="show_ime" msgid="6406112007347443383">"भौतिक कीबोर्ड सक्रिय असताना त्यास स्क्रीनवर ठेवा"</string>
<string name="hardware" msgid="1800597768237606953">"व्हर्च्युअल कीबोर्ड दर्शवा"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> कॉंफिगर करा"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"वास्तविक कीबोर्ड कॉंफिगर करा"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"भाषा आणि लेआउट निवडण्यासाठी टॅप करा"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"श्रवणयंत्र डिव्हाइस"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू केला आहे."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"धरून ठेवलेल्या व्हॉल्यूम की. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> बंद केले आहे."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"व्हॉल्यूम की रिलीझ करा. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> सुरू करण्यासाठी, दोन्ही व्हॉल्यूम की पुन्हा प्रेस करा आणि तीन सेकंदांसाठी धरून ठेवा."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तुम्ही अॅक्सेसिबिलिटी बटणावर टॅप केल्यास वापरण्यासाठी एक वैशिष्ट्य निवडा:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"अॅक्सेसिबिलिटी जेश्चरसोबत वापराचे असलेले वैशिष्ट्य निवडा (दोन बोटांनी स्क्रीनच्या तळापासून वर स्वाइप करा):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"अॅक्सेसिबिलिटी जेश्चरसोबत वापराचे असलेले वैशिष्ट्य निवडा (तीनन बोटांनी स्क्रीनच्या तळापासून वर स्वाइप करा):"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"आशय दाखवण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> दोन्ही डिस्प्ले वापरत आहे"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"डिव्हाइस खूप गरम आहे"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"तुमचा फोन खूप गरम होत असल्यामुळे ड्युअल स्क्रीन उपलब्ध नाही"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"बंद करा"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> कॉंफिगर केले आहे"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"कीबोर्ड लेआउट <xliff:g id="LAYOUT_1">%s</xliff:g> वर सेट केला. बदलण्यासाठी टॅप करा."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"कीबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> वर सेट केला. बदलण्यासाठी टॅप करा."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"कीबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> वर सेट केला. बदलण्यासाठी टॅप करा."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"कीबोर्ड लेआउट <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> वर सेट करा… बदलण्यासाठी टॅप करा."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"वास्तविक कीबोर्ड कॉंफिगर केला"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"कीबोर्ड पाहण्यासाठी टॅप करा"</string>
</resources>
diff --git a/core/res/res/values-ms/strings.xml b/core/res/res/values-ms/strings.xml
index cc41127f..d780cba 100644
--- a/core/res/res/values-ms/strings.xml
+++ b/core/res/res/values-ms/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Panggilan Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Mati"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Panggil melalui Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Panggil melalui rangkaian mudah alih"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Pilih kaedah input"</string>
<string name="show_ime" msgid="6406112007347443383">"Pastikannya pada skrin, semasa papan kekunci fizikal aktif"</string>
<string name="hardware" msgid="1800597768237606953">"Tunjukkan papan kekunci maya"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurasikan <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurasikan papan kekunci fizikal"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Ketik untuk memilih bahasa dan susun atur"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Peranti pendengaran"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dihidupkan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Kekunci kelantangan ditahan. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> dimatikan."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lepaskan kekunci kelantangan. Untuk menghidupkan <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, sila tekan dan tahan kedua-dua kekunci kelantangan sekali lagi selama 3 saat."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pilih ciri yang hendak digunakan apabila anda mengetik butang kebolehaksesan:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pilih ciri untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan dua jari):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pilih ciri untuk digunakan dengan gerak isyarat kebolehaksesan (leret ke atas dari bahagian bawah skrin menggunakan tiga jari):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> menggunakan kedua-dua paparan untuk menunjukkan kandungan"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Peranti terlalu panas"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dwiskrin tidak tersedia kerana telefon anda terlalu panas"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Matikan"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> dikonfigurasikan"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Reka letak papan kekunci ditetapkan kepada <xliff:g id="LAYOUT_1">%s</xliff:g>. Ketik untuk menukar reka letak."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Reka letak papan kekunci ditetapkan kepada <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Ketik untuk menukar reka letak."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Reka letak papan kekunci ditetapkan kepada <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Ketik untuk menukar reka letak."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Reka letak papan kekunci ditetapkan kepada <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Ketik untuk menukar reka letak."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Papan kekunci fizikal dikonfigurasikan"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Ketik untuk melihat papan kekunci"</string>
</resources>
diff --git a/core/res/res/values-my/strings.xml b/core/res/res/values-my/strings.xml
index 9a37e10..9a72679 100644
--- a/core/res/res/values-my/strings.xml
+++ b/core/res/res/values-my/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi ခေါ်ဆိုမှု"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ပိတ်"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi သုံး၍ ခေါ်ဆိုသည်"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"မိုဘိုင်းကွန်ရက်သုံး၍ ခေါ်ဆိုသည်"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ထည့်သွင်းရေး နည်းကို ရွေးရန်"</string>
<string name="show_ime" msgid="6406112007347443383">"စက်၏ကီးဘုတ် ဖွင့်ထားစဉ်တွင် ၎င်းကို ဖန်သားပြင်ပေါ်တွင် ဆက်ထားပါ"</string>
<string name="hardware" msgid="1800597768237606953">"ပကတိအသွင်ကီးဘုတ်ပြရန်"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ကို စီစဉ်သတ်မှတ်ရန်"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ပကတိကီးဘုတ်များကို စီစဉ်သတ်မှတ်ရန်"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ဘာသာစကားနှင့် အသွင်အပြင်ရွေးချယ်ရန် တို့ပါ"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"နားကြားကိရိယာ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်လိုက်သည်။"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"အသံခလုတ်များကို ဖိထားသည်။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ပိတ်လိုက်သည်။"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"အသံထိန်းခလုတ်များကို လွှတ်လိုက်ပါ။ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ဖွင့်ရန် အသံထိန်းခလုတ်နှစ်ခုစလုံးကို ၃ စက္ကန့်ကြာအောင် ထပ်နှိပ်ပါ။"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"သုံးနိုင်မှုခလုတ်ကို တို့ပြီးလျှင် ဝန်ဆောင်မှုတစ်ခု ရွေးပါ−"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"သုံးနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (ဖန်သားပြင်အောက်ခြေမှနေ၍ လက်နှစ်ချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"သုံးနိုင်မှုလက်ဟန်ဖြင့် အသုံးပြုရန် ဝန်ဆောင်မှုတစ်ခုကို ရွေးပါ (ဖန်သားပြင်အောက်ခြေမှနေ၍ လက်သုံးချောင်းဖြင့် အပေါ်သို့ ပွတ်ဆွဲပါ)-"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အကြောင်းအရာကို ဖန်သားပြင်နှစ်ခုစလုံးတွင် ပြနေသည်"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"စက်ပစ္စည်း အလွန်ပူနေသည်"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"သင့်ဖုန်း အလွန်ပူနေသဖြင့် ‘စခရင်နှစ်ခု’ သုံး၍မရပါ"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ပိတ်ရန်"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> စီစဉ်သတ်မှတ်ထားသည်"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"ကီးဘုတ်အပြင်အဆင်ကို <xliff:g id="LAYOUT_1">%s</xliff:g> ဟု သတ်မှတ်ထားသည်။ ပြောင်းရန်တို့ပါ။"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"ကီးဘုတ်အပြင်အဆင်ကို <xliff:g id="LAYOUT_1">%1$s</xliff:g>၊ <xliff:g id="LAYOUT_2">%2$s</xliff:g> ဟု သတ်မှတ်ထားသည်။ ပြောင်းရန်တို့ပါ။"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"ကီးဘုတ်အပြင်အဆင်ကို <xliff:g id="LAYOUT_1">%1$s</xliff:g>၊ <xliff:g id="LAYOUT_2">%2$s</xliff:g>၊ <xliff:g id="LAYOUT_3">%3$s</xliff:g> ဟု သတ်မှတ်ထားသည်။ ပြောင်းရန်တို့ပါ။"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ကီးဘုတ်အပြင်အဆင်ကို <xliff:g id="LAYOUT_1">%1$s</xliff:g>၊ <xliff:g id="LAYOUT_2">%2$s</xliff:g>၊ <xliff:g id="LAYOUT_3">%3$s</xliff:g> သို့ သတ်မှတ်လိုက်သည်… ပြောင်းရန် တို့ပါ။"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ပကတိကီးဘုတ်များကို စီစဉ်သတ်မှတ်ထားသည်"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ကီးဘုတ်များကြည့်ရန် တို့ပါ"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index 826ff49..979d464 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wifi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wifi-anrop"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Av"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Ring via Wifi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Ring over mobilnettverk"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Velg inndatametode"</string>
<string name="show_ime" msgid="6406112007347443383">"Ha den på skjermen mens det fysiske tastaturet er aktivt"</string>
<string name="hardware" msgid="1800597768237606953">"Vis det virtuelle tastaturet"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurer <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurer de fysiske tastaturene"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Trykk for å velge språk og layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZÆØÅ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Høreapparater"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått på."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumtastene holdes inne. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> er slått av."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Slipp opp volumtastene. For å slå på <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, trykk og hold på begge volumtastene igjen i 3 sekunder."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Velg en funksjon du vil bruke når du trykker på Tilgjengelighet-knappen:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Velg en funksjon du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med to fingre):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Velg en funksjon du vil bruke med tilgjengelighetsbevegelsen (sveip opp fra bunnen av skjermen med tre fingre):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> bruker begge skjermene til å vise innhold"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Enheten er for varm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dobbel skjerm er ikke tilgjengelig fordi telefonen begynner å bli for varm"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Slå av"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> er konfigurert"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Tastaturoppsettet er satt til <xliff:g id="LAYOUT_1">%s</xliff:g>. Trykk for å endre det."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Tastaturoppsettet er satt til <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Trykk for å endre det."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Tastaturoppsettet er satt til <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Trykk for å endre det."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tastaturoppsettet er satt til <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> … Trykk for å endre det."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"De fysiske tastaturene er konfigurert"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Trykk for å se tastaturene"</string>
</resources>
diff --git a/core/res/res/values-ne/strings.xml b/core/res/res/values-ne/strings.xml
index 2624a39..886b27c 100644
--- a/core/res/res/values-ne/strings.xml
+++ b/core/res/res/values-ne/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WiFi कलिङ"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"अफ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi मार्फत कल गर्नुहोस्"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"मोबाइल नेटवर्कमार्फत कल गर्नुहोस्"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"निवेश विधि छान्नुहोस्"</string>
<string name="show_ime" msgid="6406112007347443383">"फिजिकल किबोर्ड सक्रिय हुँदा यसलाई स्क्रिनमा राखियोस्"</string>
<string name="hardware" msgid="1800597768237606953">"भर्चुअल किबोर्ड देखाउनुहोस्"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> कन्फिगर गर्नुहोस्"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"भौतिक किबोर्डहरू कन्फिगर गर्नुहोस्"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"भाषा र लेआउट चयन गर्न ट्याप गर्नुहोस्"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"हियरिङ डिभाइसहरू"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन भयो।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"तपाईंले भोल्युम बटनहरू थिचिराख्नुभयो। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अफ भयो।"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"भोल्युम बटनहरू थिच्न छाड्नुहोस्। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> अन गर्न दुवै भोल्युम बटन फेरि ३ सेकेन्डसम्म थिचिराख्नुहोस्।"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"तपाईंले एक्सेसिबिलिटी बटन ट्याप गर्दा प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस्:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (दुईवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"तपाईंले पहुँचको इसारामार्फत प्रयोग गर्न चाहनुभएको सुविधा छनौट गर्नुहोस् (तीनवटा औँलाले स्क्रिनको फेदबाट माथितिर स्वाइप गर्नुहोस्):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ले सामग्री देखाउन दुई वटै डिस्प्ले प्रयोग गरिरहेको छ"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"डिभाइस ज्यादै तातेको छ"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"तपाईंको फोन ज्यादै तातिरहेको हुनाले डुअल स्क्रिन उपलब्ध छैन"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"अफ गर्नुहोस्"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> कन्फिगर गरिएको छ"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"किबोर्ड लेआउट सेट गरी <xliff:g id="LAYOUT_1">%s</xliff:g> बनाइएको छ। परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"किबोर्ड लेआउट सेट गरी <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> बनाइएको छ। परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"किबोर्ड लेआउट सेट गरी <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> बनाइएको छ। परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"किबोर्ड लेआउट सेट गरी <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> बनाइएको छ… परिवर्तन गर्न ट्याप गर्नुहोस्।"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"भौतिक किबोर्डहरू कन्फिगर गरिएका छन्"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"किबोर्डहरू हेर्न ट्याप गर्नुहोस्"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index b56efb5..97d277d 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wifi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Bellen via wifi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Uit"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Bellen via wifi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Bellen via mobiel netwerk"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Invoermethode selecteren"</string>
<string name="show_ime" msgid="6406112007347443383">"Toon op het scherm terwijl het fysieke toetsenbord actief is"</string>
<string name="hardware" msgid="1800597768237606953">"Virtueel toetsenbord tonen"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> instellen"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fysieke toetsenborden instellen"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tik om een taal en indeling te selecteren"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hoortoestellen"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat aan."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volumetoetsen ingedrukt gehouden. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> staat uit."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Laat de volumeknoppen los. Als je <xliff:g id="SERVICE_NAME">%1$s</xliff:g> wilt aanzetten, houd je beide volumeknoppen weer 3 seconden ingedrukt."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Kies een functie om te gebruiken als je op de knop Toegankelijkheid tikt:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Kies een functie om te gebruiken met het toegankelijkheidsgebaar (met twee vingers omhoog swipen vanaf de onderkant van het scherm):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Kies een functie om te gebruiken met het toegankelijkheidsgebaar (met drie vingers omhoog swipen vanaf de onderkant van het scherm):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> gebruikt beide schermen om content te tonen"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Het apparaat is te warm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dubbel scherm is niet beschikbaar, omdat je telefoon te warm wordt"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Uitzetten"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> is ingesteld"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Toetsenbordindeling ingesteld op <xliff:g id="LAYOUT_1">%s</xliff:g>. Tik om te wijzigen."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Toetsenbordindeling is ingesteld op <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Tik om te wijzigen."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Toetsenbordindeling is ingesteld op <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Tik om te wijzigen."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Toetsenbordindeling ingesteld op <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Tik om te wijzigen."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fysieke toetsenborden zijn ingesteld"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tik om toetsenborden te bekijken"</string>
</resources>
diff --git a/core/res/res/values-or/strings.xml b/core/res/res/values-or/strings.xml
index 15fb22a..bc28604 100644
--- a/core/res/res/values-or/strings.xml
+++ b/core/res/res/values-or/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"ୱାଇ-ଫାଇ"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"ୱାଇଫାଇ କଲିଂ"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ବନ୍ଦ ଅଛି"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"ୱାଇ-ଫାଇ ମାଧ୍ୟମରେ କଲ୍ କରନ୍ତୁ"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"ମୋବାଇଲ ନେଟ୍ୱର୍କ ମାଧ୍ୟମରେ କଲ୍ କରନ୍ତୁ"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ଇନପୁଟ୍ ପଦ୍ଧତି ବାଛନ୍ତୁ"</string>
<string name="show_ime" msgid="6406112007347443383">"ଫିଜିକାଲ୍ କୀବୋର୍ଡ ସକ୍ରିୟ ଥିବାବେଳେ ଏହାକୁ ସ୍କ୍ରିନ୍ ଉପରେ ରଖନ୍ତୁ"</string>
<string name="hardware" msgid="1800597768237606953">"ଭର୍ଚୁଆଲ୍ କୀ’ବୋର୍ଡ ଦେଖାନ୍ତୁ"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>କୁ କନଫିଗର କରନ୍ତୁ"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ଫିଜିକାଲ କୀବୋର୍ଡଗୁଡ଼ିକୁ କନଫିଗର କରନ୍ତୁ"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ଭାଷା ଓ ଲେଆଉଟ୍ ଚୟନ କରିବା ପାଇଁ ଟାପ୍ କରନ୍ତୁ"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ହିଅରିଂ ଡିଭାଇସଗୁଡ଼ିକ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ଚାଲୁ ହୋଇଛି।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ଭଲ୍ୟୁମ୍ କୀ\'ଗୁଡ଼ିକୁ ଧରି ରଖାଯାଇଛି। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ବନ୍ଦ ହୋଇଛି।"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ଭଲ୍ୟୁମ କୀ\'ଗୁଡ଼ିକୁ ରିଲିଜ କରନ୍ତୁ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g>କୁ ଚାଲୁ କରିବା ପାଇଁ ଉଭୟ ଭଲ୍ୟୁମ କୀ\'କୁ ପୁଣି 3 ସେକେଣ୍ଡ ପାଇଁ ଦବାଇ ଧରି ରଖନ୍ତୁ।"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ଆପଣ ଆକ୍ସେସିବିଲିଟୀ ବଟନ୍ ଟାପ୍ କରିବା ବେଳେ ଏକ ଫିଚର୍ ବ୍ୟବହାର କରିବାକୁ ବାଛନ୍ତୁ:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଏକ ଫିଚର୍ ବାଛନ୍ତୁ (ଦୁଇଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ଆକ୍ସେସିବିଲିଟୀ ଜେଶ୍ଚର୍ ସହିତ ବ୍ୟବହାର କରିବାକୁ ଏକ ଫିଚର୍ ବାଛନ୍ତୁ (ତିନୋଟି ଆଙ୍ଗୁଠିରେ ସ୍କ୍ରିନର ତଳୁ ଉପରକୁ ସ୍ୱାଇପ୍ କରନ୍ତୁ):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"ବିଷୟବସ୍ତୁ ଦେଖାଇବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଉଭୟ ଡିସପ୍ଲେକୁ ବ୍ୟବହାର କରୁଛି"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ଡିଭାଇସ ବହୁତ ଗରମ ଅଛି"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ଆପଣଙ୍କ ଫୋନ ବହୁତ ଗରମ ହେଉଥିବା ଯୋଗୁଁ ଡୁଆଲ ସ୍କ୍ରିନ ଉପଲବ୍ଧ ନାହିଁ"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ବନ୍ଦ କରନ୍ତୁ"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g>କୁ କନଫିଗର କରାଯାଇଛି"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"କୀବୋର୍ଡ ଲେଆଉଟକୁ <xliff:g id="LAYOUT_1">%s</xliff:g>ରେ ସେଟ କରାଯାଇଛି। ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"କୀବୋର୍ଡ ଲେଆଉଟକୁ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>ରେ ସେଟ କରାଯାଇଛି। ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"କୀବୋର୍ଡ ଲେଆଉଟକୁ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>ରେ ସେଟ କରାଯାଇଛି। ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"କୀବୋର୍ଡ ଲେଆଉଟକୁ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>ରେ ସେଟ କରାଯାଇଛି… ପରିବର୍ତ୍ତନ କରିବାକୁ ଟାପ କରନ୍ତୁ।"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ଫିଜିକାଲ କୀବୋର୍ଡଗୁଡ଼ିକୁ କନଫିଗର କରାଯାଇଛି"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"କୀବୋର୍ଡଗୁଡ଼ିକୁ ଦେଖିବା ପାଇଁ ଟାପ କରନ୍ତୁ"</string>
</resources>
diff --git a/core/res/res/values-pa/strings.xml b/core/res/res/values-pa/strings.xml
index f0c0521..e188a0d 100644
--- a/core/res/res/values-pa/strings.xml
+++ b/core/res/res/values-pa/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"ਵਾਈ-ਫਾਈ"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"ਵਾਈ-ਫਾਈ ਕਾਲਿੰਗ"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ਬੰਦ"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"ਵਾਈ-ਫਾਈ \'ਤੇ ਕਾਲ ਕਰੋ"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"ਮੋਬਾਈਲ ਨੈੱਟਵਰਕ ਤੋਂ ਕਾਲ ਕਰੋ"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ਇਨਪੁਟ ਵਿਧੀ ਚੁਣੋ"</string>
<string name="show_ime" msgid="6406112007347443383">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡ ਸਰਗਰਮ ਹੋਣ ਦੌਰਾਨ ਇਸ ਨੂੰ ਸਕ੍ਰੀਨ \'ਤੇ ਬਣਾਈ ਰੱਖੋ"</string>
<string name="hardware" msgid="1800597768237606953">"ਆਭਾਸੀ ਕੀ-ਬੋਰਡ ਦਿਖਾਓ"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ਦਾ ਸੰਰੂਪਣ ਕਰੋ"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡਾਂ ਦਾ ਸੰਰੂਪਣ ਕਰੋ"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"ਭਾਸ਼ਾ ਅਤੇ ਖਾਕਾ ਚੁਣਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ਸੁਣਨ ਵਾਲੇ ਡੀਵਾਈਸ"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ।"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ਅਵਾਜ਼ੀ ਕੁੰਜੀਆਂ ਦਬਾ ਕੇ ਰੱਖੀਆਂ ਗਈਆਂ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਬੰਦ ਕੀਤਾ ਗਿਆ।"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ ਛੱਡੋ। <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ਨੂੰ ਚਾਲੂ ਕਰਨ ਲਈ, ਦੋਵੇਂ ਅਵਾਜ਼ ਕੁੰਜੀਆਂ ਨੂੰ 3 ਸਕਿੰਟਾਂ ਲਈ ਦੁਬਾਰਾ ਦਬਾਈ ਰੱਖੋ।"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ਤੁਹਾਡੇ ਵੱਲੋਂ ਪਹੁੰਚਯੋਗਤਾ ਬਟਨ ਨੂੰ ਟੈਪ ਕੀਤੇ ਜਾਣ \'ਤੇ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ (ਦੋ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ਪਹੁੰਚਯੋਗਤਾ ਸੰਕੇਤ ਨਾਲ ਵਰਤਣ ਲਈ ਕੋਈ ਵਿਸ਼ੇਸ਼ਤਾ ਚੁਣੋ (ਤਿੰਨ ਉਂਗਲਾਂ ਨਾਲ ਸਕ੍ਰੀਨ ਦੇ ਹੇਠਾਂ ਤੋਂ ਉੱਪਰ ਵੱਲ ਸਵਾਈਪ ਕਰੋ):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਸਮੱਗਰੀ ਨੂੰ ਦਿਖਾਉਣ ਲਈ ਦੋਵੇਂ ਡਿਸਪਲੇਆਂ ਦੀ ਵਰਤੋਂ ਕਰ ਰਹੀ ਹੈ"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"ਡੀਵਾਈਸ ਬਹੁਤ ਗਰਮ ਹੈ"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ਦੋਹਰੀ ਸਕ੍ਰੀਨ ਵਿਸ਼ੇਸ਼ਤਾ ਉਪਲਬਧ ਨਹੀਂ ਹੈ ਕਿਉਂਕਿ ਤੁਹਾਡਾ ਫ਼ੋਨ ਬਹੁਤ ਗਰਮ ਹੋ ਰਿਹਾ ਹੈ"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ਬੰਦ ਕਰੋ"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ਦਾ ਸੰਰੂਪਣ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%s</xliff:g> \'ਤੇ ਸੈੱਟ ਹੈ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> \'ਤੇ ਸੈੱਟ ਹੈ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>\'ਤੇ ਸੈੱਟ ਹੈ। ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ਕੀ-ਬੋਰਡ ਦਾ ਖਾਕਾ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> \'ਤੇ ਸੈੱਟ ਹੈ… ਬਦਲਣ ਲਈ ਟੈਪ ਕਰੋ।"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ਭੌਤਿਕ ਕੀ-ਬੋਰਡਾਂ ਦਾ ਸੰਰੂਪਣ ਕੀਤਾ ਗਿਆ"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"ਕੀ-ਬੋਰਡਾਂ ਨੂੰ ਦੇਖਣ ਲਈ ਟੈਪ ਕਰੋ"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 2f5aa5a..031d576 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -142,6 +142,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Połączenia przez Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Połączenie przez Wi-Fi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Wył."</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Rozmowa przez Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Połączenia przez sieć komórkową"</string>
@@ -1395,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Wybierz metodę wprowadzania"</string>
<string name="show_ime" msgid="6406112007347443383">"Pozostaw na ekranie, gdy aktywna jest klawiatura fizyczna"</string>
<string name="hardware" msgid="1800597768237606953">"Pokaż klawiaturę wirtualną"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Skonfiguruj urządzenie <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Skonfiguruj klawiatury fizyczne"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Kliknij, by wybrać język i układ"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" AĄBCĆDEĘFGHIJKLŁMNŃOÓPQRSŚTUVWXYZŹŻ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1723,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Urządzenia słuchowe"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została włączona."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Przytrzymano klawisze głośności. Usługa <xliff:g id="SERVICE_NAME">%1$s</xliff:g> została wyłączona."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Zwolnij przyciski głośności. Aby włączyć usługę <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, naciśnij i przytrzymaj oba przyciski głośności przez 3 sekundy."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Wybierz funkcję używaną po kliknięciu przycisku ułatwień dostępu:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Wybierz funkcję, której chcesz używać w przypadku gestu ułatwień dostępu (przesunięcie dwoma palcami w górę od dołu ekranu):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Wybierz funkcję, której chcesz używać w przypadku gestu ułatwień dostępu (przesunięcie trzema palcami w górę od dołu ekranu):"</string>
@@ -2328,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> korzysta z obu wyświetlaczy, aby pokazać treści"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Urządzenie jest za ciepłe"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Podwójny ekran jest niedostępny, ponieważ telefon za bardzo się nagrzewa"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Wyłącz"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Skonfigurowano urządzenie <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Ustawiono układ klawiatury <xliff:g id="LAYOUT_1">%s</xliff:g>. Kliknij, aby to zmienić."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Ustawiono układ klawiatury <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Kliknij, aby to zmienić."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Ustawiono układ klawiatury <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Kliknij, aby to zmienić."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Ustawiono układ klawiatury <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Kliknij, aby to zmienić."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Skonfigurowano klawiatury fizyczne"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Kliknij, aby wyświetlić klawiatury"</string>
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index 5eb7a46..a315bb1 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -141,6 +141,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Chamada no Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Ligação pelo Wi-Fi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desativado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Chamar via Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Chamar via rede móvel"</string>
@@ -1394,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Selecione o método de entrada"</string>
<string name="show_ime" msgid="6406112007347443383">"Mantém o teclado virtual na tela enquanto o teclado físico está ativo"</string>
<string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure o dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure teclados físicos"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toque para selecionar o idioma e o layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha um recurso a ser usado quando você toca no botão de acessibilidade:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
@@ -2327,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está usando as duas telas para mostrar conteúdo"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"O dispositivo está muito quente"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A tela dupla está indisponível porque o smartphone está ficando muito quente"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desativar"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g> configurado"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%s</xliff:g>. Toque para mudar."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g> e <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Toque para mudar."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> e <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Toque para mudar."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toque para mudar."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toque para conferir os teclados"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 18df66e..5a68166 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -141,6 +141,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Chamadas Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Chamada Wi-Fi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desativado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Chamada por Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Chamada por rede móvel"</string>
@@ -1394,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Escolher o método de entrada"</string>
<string name="show_ime" msgid="6406112007347443383">"Manter no ecrã enquanto o teclado físico estiver ativo"</string>
<string name="hardware" msgid="1800597768237606953">"Mostrar o teclado virtual"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure o dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure teclados físicos"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toque para selecionar o idioma e o esquema"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"A app <xliff:g id="APP_NAME">%1$s</xliff:g> está a usar ambos os ecrãs para mostrar conteúdo"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"O dispositivo está a ficar demasiado quente"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A funcionalidade Dois ecrãs está indisponível porque o seu telemóvel está a ficar demasiado quente"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desativar"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g> configurado"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Esquema do teclado definido como <xliff:g id="LAYOUT_1">%s</xliff:g>. Toque para o alterar."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Esquema do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g> e <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Toque para o alterar."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Esquema do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> e <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Toque para o alterar."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Esquema do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toque para o alterar."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toque para ver os teclados"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index 5eb7a46..a315bb1 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -141,6 +141,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Chamada no Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Ligação pelo Wi-Fi"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Desativado"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Chamar via Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Chamar via rede móvel"</string>
@@ -1394,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Selecione o método de entrada"</string>
<string name="show_ime" msgid="6406112007347443383">"Mantém o teclado virtual na tela enquanto o teclado físico está ativo"</string>
<string name="hardware" msgid="1800597768237606953">"Mostrar teclado virtual"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configure o dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configure teclados físicos"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Toque para selecionar o idioma e o layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparelhos auditivos"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Teclas de volume pressionadas. Serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ativado."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Teclas de volume pressionadas. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> desativado."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Solte as teclas de volume. Para ativar o serviço <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, toque e pressione as duas teclas de volume por três segundos."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Escolha um recurso a ser usado quando você toca no botão de acessibilidade:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com dois dedos):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Escolha um recurso para usar com o gesto de acessibilidade (deslizar de baixo para cima na tela com três dedos):"</string>
@@ -2327,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está usando as duas telas para mostrar conteúdo"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"O dispositivo está muito quente"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"A tela dupla está indisponível porque o smartphone está ficando muito quente"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Desativar"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Dispositivo <xliff:g id="DEVICE_NAME">%s</xliff:g> configurado"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%s</xliff:g>. Toque para mudar."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g> e <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Toque para mudar."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> e <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Toque para mudar."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Layout do teclado definido como <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Toque para mudar."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Teclados físicos configurados"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Toque para conferir os teclados"</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index f477049..14570f7 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -141,6 +141,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Apelare prin Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Dezactivată"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Apelează prin Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Sună prin rețeaua mobilă"</string>
@@ -1394,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Alege metoda de introducere de text"</string>
<string name="show_ime" msgid="6406112007347443383">"Se păstrează pe ecran cât timp este activată tastatura fizică"</string>
<string name="hardware" msgid="1800597768237606953">"Afișează tastatura virtuală"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Configurează <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Configurează tastaturi fizice"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Atinge pentru a selecta limba și aspectul"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Aparate auditive"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"S-au apăsat lung tastele de volum. S-a activat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"S-au apăsat lung tastele de volum. S-a dezactivat <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Eliberează butoanele de volum. Pentru a activa <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, apasă lung pe ambele butoane de volum timp de trei secunde încă o dată."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Alege o funcție pe care să o folosești când atingi butonul de accesibilitate:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Alege o funcție pe care să o folosești cu gestul de accesibilitate (glisează în sus cu două degete din partea de jos a ecranului):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Alege o funcție pe care să o folosești cu gestul de accesibilitate (glisează în sus cu trei degete din partea de jos a ecranului):"</string>
@@ -2327,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> folosește ambele ecrane pentru a afișa conținut"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Dispozitivul este prea cald"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Funcția Dual Screen este indisponibilă, deoarece telefonul s-a încălzit prea tare"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Dezactivează"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"S-a configurat <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Aspectul tastaturii este setat la <xliff:g id="LAYOUT_1">%s</xliff:g>. Atinge pentru a-l schimba."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Aspectul tastaturii este setat la <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Atinge pentru a-l schimba."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Aspectul tastaturii este setat la <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Atinge pentru a-l schimba."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Aspectul tastaturii este setat la <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Atinge pentru a-l schimba."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Tastaturile fizice au fost configurate"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Atinge pentru a vedea tastaturile"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 70cc882..3dffa92 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -142,6 +142,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Звонки по Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Отключено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Звонить по Wi‑Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Звонить по мобильной сети"</string>
@@ -1358,7 +1360,7 @@
<string name="no_permissions" msgid="5729199278862516390">"Не требуется разрешений"</string>
<string name="perm_costs_money" msgid="749054595022779685">"это может стоить вам денег!"</string>
<string name="dlg_ok" msgid="5103447663504839312">"ОК"</string>
- <string name="usb_charging_notification_title" msgid="1674124518282666955">"Зарядка устройства через USB…"</string>
+ <string name="usb_charging_notification_title" msgid="1674124518282666955">"Зарядка устройства через USB"</string>
<string name="usb_supplying_notification_title" msgid="5378546632408101811">"Зарядка устройства через USB…"</string>
<string name="usb_mtp_notification_title" msgid="1065989144124499810">"Передача файлов через USB включена"</string>
<string name="usb_ptp_notification_title" msgid="5043437571863443281">"Режим PTP включен"</string>
@@ -1395,10 +1397,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Выберите способ ввода"</string>
<string name="show_ime" msgid="6406112007347443383">"Не скрывать экранную клавиатуру, когда включена физическая"</string>
<string name="hardware" msgid="1800597768237606953">"Виртуальная клавиатура"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Настройте устройство \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\""</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Настройте физические клавиатуры"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Нажмите, чтобы выбрать язык и раскладку"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1723,8 +1723,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слуховые аппараты"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" включена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Использован жест с кнопками регулировки громкости. Функция \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\" отключена."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Отпустите кнопки громкости. Чтобы включить <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, нажмите и удерживайте обе кнопки регулировки громкости в течение трех секунд."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Выберите функцию, которая будет запускаться при нажатии кнопки специальных возможностей:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Выберите функцию, которая будет запускаться с помощью жеста (провести по экрану снизу вверх двумя пальцами):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Выберите функцию, которая будет запускаться с помощью жеста (провести по экрану снизу вверх тремя пальцами):"</string>
@@ -2328,19 +2327,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> показывает контент на обоих экранах."</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Устройство перегрелось"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Двойной экран недоступен из-за перегрева телефона."</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Отключить"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Устройство \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\" настроено"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Для клавиатуры настроена раскладка <xliff:g id="LAYOUT_1">%s</xliff:g>. Нажмите, чтобы изменить."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Для клавиатуры настроены раскладки <xliff:g id="LAYOUT_1">%1$s</xliff:g> и <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Нажмите, чтобы изменить."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Для клавиатуры настроены раскладки <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> и <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Нажмите, чтобы изменить."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Для клавиатуры настроено несколько раскладок: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> и другие. Нажмите, чтобы изменить."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физические клавиатуры настроены"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Нажмите, чтобы посмотреть подключенные клавиатуры."</string>
</resources>
diff --git a/core/res/res/values-si/strings.xml b/core/res/res/values-si/strings.xml
index 7f9a6cb..93302ff 100644
--- a/core/res/res/values-si/strings.xml
+++ b/core/res/res/values-si/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi ඇමතීම"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ක්රියාවිරහිතයි"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi ඔස්සේ ඇමතුම"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"ජංගම ජාලය ඔස්සේ ඇමතුම"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ආදාන ක්රමයක් තෝරන්න"</string>
<string name="show_ime" msgid="6406112007347443383">"භෞතික යතුරු පුවරුව සක්රිය අතරතුර එය තිරය මත තබා ගන්න"</string>
<string name="hardware" msgid="1800597768237606953">"අතථ්ය යතුරු පුවරුව පෙන්වන්න"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> වින්යාස කරන්න"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"භෞතික යතුරුපුවරුව වින්යාස කරන්න"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"භාෂාව හා පිරිසැලසුම තේරීමට තට්ටු කරන්න"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"ශ්රවණ උපාංග"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්රියාත්මකයි."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"හඬ පරිමා යතුරු අල්ලා ගන්න <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ක්රියාවිරහිතයි."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"හඬ පරිමා යතුරු මුදා හරින්න. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> සක්රීය කිරීමට, හඬ පරිමා යතුරු දෙකම නැවත තත්පර 3ක් ඔබා අල්ලා සිටින්න."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ඔබ ප්රවේශ්යතා බොත්තම තට්ටු කරන විට භාවිත කිරීමට විශේෂාංගයක් තෝරා ගන්න:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ප්රවේශ්යතා ඉංගිතය සමඟ භාවිතයට විශේෂාංගයක් තෝරා ගන්න (ඇඟිලි දෙකකින් තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ප්රවේශ්යතා ඉංගිතය සමඟ භාවිතයට විශේෂාංගයක් තෝරා ගන්න (ඇඟිලි තුනකින් තිරයේ පහළ සිට ඉහළට ස්වයිප් කරන්න):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"අන්තර්ගතය පෙන්වීමට <xliff:g id="APP_NAME">%1$s</xliff:g> සංදර්ශන දෙකම භාවිත කරයි"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"උපාංගය ඉතා උණුසුම් වේ"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"ඔබේ දුරකථනය ඉතා උණුසුම් නිසා ද්විත්ව තිරය ලබා ගත නොහැක"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"අක්රිය කරන්න"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> වින්යාස කෙරිණි"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"යතුරු පුවරු පිරිසැලසුම <xliff:g id="LAYOUT_1">%s</xliff:g> ලෙස සැකසිණි. වෙනස් කිරීමට තට්ටු කරන්න."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"යතුරු පුවරු පිරිසැලසුම <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> ලෙස සැකසිණි. වෙනස් කිරීමට තට්ටු කරන්න."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"යතුරු පුවරුව <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ලෙස සැකසිණි. වෙනස් කිරීමට තට්ටු කරන්න."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"යතුරු පුවරුව <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ලෙස සකසා ඇත… වෙනස් කිරීමට තට්ටු කරන්න."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"භෞතික යතුරු පුවරුව වින්යාස කෙරිණි"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"යතුරු පුවරු බැලීමට තට්ටු කරන්න"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index 9c481a9..3ab9547 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -142,6 +142,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Volanie cez Wi‑Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Vypnuté"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Volanie cez Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Volanie cez mobilnú sieť"</string>
@@ -1395,10 +1397,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Zvoliť metódu vstupu"</string>
<string name="show_ime" msgid="6406112007347443383">"Ponechať na obrazovke, keď je aktívna fyzická klávesnica"</string>
<string name="hardware" msgid="1800597768237606953">"Zobraziť virtuálnu klávesnicu"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Nakonfigurujte <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Nakonfigurujte fyzické klávesnice"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Klepnutím vyberte jazyk a rozloženie"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" AÁÄBCČDĎDZDŽEÉFGHCHIÍJKLĽMNŇOÓÔPRŔSŠTŤUÚVWXYÝZŽ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1723,8 +1723,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Načúvacie zariadenia"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je zapnutá."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pridržali ste tlačidlá hlasitosti. Služba <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vypnutá."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Uvoľnite tlačidlá hlasitosti. Ak chcete zapnúť službu <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pridržte tri sekundy obe tlačidlá hlasitosti."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Klepnutím na tlačidlo dostupnosti vyberte požadovanú funkciu:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Vyberte funkciu, ktorú chcete používať s daným gestom dostupnosti (potiahnutím dvoma prstami z dolnej časti obrazovky nahor):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Vyberte funkciu aktivovanú daným gestom dostupnosti (potiahnutím troma prstami z dolnej časti obrazovky nahor):"</string>
@@ -2328,19 +2327,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> zobrazuje obsah na oboch obrazovkách"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Zariadenie je príliš horúce"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvojitá obrazovka nie je k dispozícii, pretože telefón sa prehrieva"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Vypnúť"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Klávesnica <xliff:g id="DEVICE_NAME">%s</xliff:g> je nakonfigurovaná"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Rozloženie klávesnice je nastavené na jazyk <xliff:g id="LAYOUT_1">%s</xliff:g>. Môžete to zmeniť klepnutím."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Rozloženie klávesnice je nastavené na jazyky <xliff:g id="LAYOUT_1">%1$s</xliff:g> a <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Môžete to zmeniť klepnutím."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Rozloženie klávesnice je nastavené na jazyky <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> a <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Môžete to zmeniť klepnutím."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Rozloženie klávesnice je nastavené na jazyky <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> a <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Môžete to zmeniť klepnutím."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fyzické klávesnice sú nakonfigurované"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klávesnice si zobrazíte klepnutím"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 39a722d..cdac333 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -142,6 +142,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Klicanje prek Wi-Fi-ja"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"Govor prek Wi-Fi-ja"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Izklopljeno"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Klic prek omrežja Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Klic prek mobilnega omrežja"</string>
@@ -1395,10 +1397,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Izberite način vnosa"</string>
<string name="show_ime" msgid="6406112007347443383">"Ohrani na zaslonu, dokler je aktivna fizična tipkovnica"</string>
<string name="hardware" msgid="1800597768237606953">"Pokaži navidezno tipkovnico"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfiguriranje naprave <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfiguriranje fizičnih tipkovnic"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dotaknite se, če želite izbrati jezik in postavitev."</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1723,8 +1723,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Slušni aparati"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je vklopljena."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tipki za glasnost sta pridržani. Storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g> je izklopljena."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Spustite gumba za glasnost. Če želite vklopiti storitev <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, znova pritisnite in 3 sekunde pridržite oba gumba za glasnost."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Izberite funkcijo, ki jo želite uporabljati, ko se dotaknete gumba za funkcije za ljudi s posebnimi potrebami:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Izberite funkcijo, ki jo želite zagnati s potezo za ljudi s posebnimi potrebami (vlečenje z dvema prstoma z dna zaslona navzgor):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Izberite funkcijo, ki jo želite zagnati s potezo za ljudi s posebnimi potrebami (vlečenje s tremi prsti z dna zaslona navzgor):"</string>
@@ -2328,19 +2327,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> uporablja oba zaslona za prikaz vsebine."</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Naprava se pregreva"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dvojni zaslon ni na voljo, ker se telefon pregreva."</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Izklopi"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Naprava <xliff:g id="DEVICE_NAME">%s</xliff:g> je konfigurirana"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Razporeditev tipkovnice je nastavljena na »<xliff:g id="LAYOUT_1">%s</xliff:g>«. Za spremembo se dotaknite."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Razporeditev tipkovnice je nastavljena na »<xliff:g id="LAYOUT_1">%1$s</xliff:g>«, »<xliff:g id="LAYOUT_2">%2$s</xliff:g>«. Za spremembo se dotaknite."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Razporeditev tipkovnice je nastavljena na »<xliff:g id="LAYOUT_1">%1$s</xliff:g>«, »<xliff:g id="LAYOUT_2">%2$s</xliff:g>«, »<xliff:g id="LAYOUT_3">%3$s</xliff:g>«. Za spremembo se dotaknite."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Razporeditev tipkovnice je nastavljena na »<xliff:g id="LAYOUT_1">%1$s</xliff:g>«, »<xliff:g id="LAYOUT_2">%2$s</xliff:g>«, »<xliff:g id="LAYOUT_3">%3$s</xliff:g>« … Za spremembo se dotaknite."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fizične tipkovnice so konfigurirane"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Dotaknite se za ogled tipkovnic"</string>
</resources>
diff --git a/core/res/res/values-sq/strings.xml b/core/res/res/values-sq/strings.xml
index d8494b4..436a00d 100644
--- a/core/res/res/values-sq/strings.xml
+++ b/core/res/res/values-sq/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Telefonatë me WiFi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Çaktivizuar"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Telefono nëpërmjet Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Telefono nëpërmjet rrjetit celular"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Zgjidh metodën e hyrjes"</string>
<string name="show_ime" msgid="6406112007347443383">"Mbaje në ekran ndërsa tastiera fizike është aktive"</string>
<string name="hardware" msgid="1800597768237606953">"Shfaq tastierën virtuale"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfiguro <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfiguro tastierat fizike"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Trokit për të zgjedhur gjuhën dhe strukturën"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Pajisjet e dëgjimit"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tastet e volumit të mbajtura shtypur. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> i aktivizuar."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tastet e volumit të mbajtura shtypur. U çaktivizua \"<xliff:g id="SERVICE_NAME">%1$s</xliff:g>\"."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Lësho tastet e volumit. Për të aktivizuar <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, shtyp dhe mbaj shtypur të dy tastet e volumit sërish për 3 sekonda."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Zgjidh një funksion për ta përdorur kur troket butonin e qasshmërisë:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Zgjidh një veçori për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me dy gishta):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Zgjidh një veçori për ta përdorur me gjestin e qasshmërisë (rrëshqit shpejt lart nga fundi i ekranit me tre gishta):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> po i përdor të dyja ekranet për të shfaqur përmbajtje"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Pajisja është shumë e nxehtë"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"\"Ekrani i dyfishtë\" nuk ofrohet sepse telefoni yt po nxehet shumë"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Çaktivizoje"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> u konfigurua"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Struktura e tastierës u caktua në: <xliff:g id="LAYOUT_1">%s</xliff:g>. Trokit për ta ndryshuar."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Struktura e tastierës u caktua në: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Trokit për ta ndryshuar."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Struktura e tastierës u caktua në: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Trokit për ta ndryshuar."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Struktura e tastierës u caktua në: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Trokit për ta ndryshuar."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Tastierat fizike u konfiguruan"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Trokit për të parë tastierat"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 2e4c4ea..6187a69 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -141,6 +141,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WiFi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Позивање преко WiFi-а"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Искључено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Позивање преко WiFi-а"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Позив преко мобилне мреже"</string>
@@ -1394,10 +1396,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Избор метода уноса"</string>
<string name="show_ime" msgid="6406112007347443383">"Задржава се на екрану док је физичка тастатура активна"</string>
<string name="hardware" msgid="1800597768237606953">"Прикажи виртуелну тастатуру"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Конфигуришите уређај <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Конфигуришите физичке тастатуре"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Додирните да бисте изабрали језик и распоред"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1722,8 +1722,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слушни апарати"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је укључена."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Држали сте тастере за јачину звука. Услуга <xliff:g id="SERVICE_NAME">%1$s</xliff:g> је искључена."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Пустите тастере за јачину звука. Да бисте укључили <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, поново притисните и задржите оба тастера за јачину звука 3 секунде."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Изаберите функцију која ће се користити када додирнете дугме Приступачност:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу два прста превуците нагоре од дна екрана):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Одаберите функцију која ће се користити помоћу покрета за приступачност (помоћу три прста превуците нагоре од дна екрана):"</string>
@@ -2327,19 +2326,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> користи оба екрана за приказивање садржаја"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Уређај је превише загрејан"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Двојни екран је недоступан јер је телефон превише загрејан"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Искључи"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Уређај <xliff:g id="DEVICE_NAME">%s</xliff:g> је конфигурисан"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Распоред тастатуре је подешен на <xliff:g id="LAYOUT_1">%s</xliff:g>. Додирните да бисте то променили."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Распоред тастатуре је подешен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Додирните да бисте то променили."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Распоред тастатуре је подешен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Додирните да бисте то променили."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Распоред тастатуре је подешен на <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Додирните да бисте променили."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Физичке тастатуре су конфигурисане"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Додирните да бисте видели тастатуре"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index 098b32f..5278939 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wifi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"wifi-samtal"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Av"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Ring via wifi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Ring via mobilnätverk"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Välj inmatningsmetod"</string>
<string name="show_ime" msgid="6406112007347443383">"Ha kvar det på skärmen när det fysiska tangentbordet används"</string>
<string name="hardware" msgid="1800597768237606953">"Visa virtuellt tangentbord"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Konfigurera <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Konfigurera fysiska tangentbord"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Tryck om du vill välja språk och layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Hörapparater"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har aktiverats."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Volymknapparna har tryckts ned. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> har inaktiverats."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Släpp volymknapparna. Du kan aktivera <xliff:g id="SERVICE_NAME">%1$s</xliff:g> genom att hålla båda volymknapparna nedtryckta i tre sekunder igen."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Välj en funktion som ska användas när du trycker på tillgänglighetsknappen:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Välj en funktion som ska användas med tillgänglighetsrörelsen (svepa uppåt med två fingrar från skärmens nederkant):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Välj en funktion som ska användas med tillgänglighetsrörelsen (svepa uppåt med tre fingrar från skärmens nederkant):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> använder båda skärmarna för att visa innehåll"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Enheten är för varm"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Dubbel skärm kan inte användas eftersom telefonen börjar bli för varm"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Stäng av"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> har konfigurerats"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Tangentbordslayouten har ställts in på <xliff:g id="LAYOUT_1">%s</xliff:g>. Tryck om du vill ändra."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Tangentbordslayouten har ställts in på <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Tryck om du vill ändra."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Tangentbordslayouten har ställts in på <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Tryck om du vill ändra."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Tangentbordslayouten är inställd på <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> … Tryck om du vill ändra."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fysiska tangentbord har konfigurerats"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Tryck för att visa tangentbord"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index 0d7b9da..1398271 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Kupiga simu kupitia WiFi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Imezimwa"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Piga simu ukitumia WI-FI"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Piga ukitumia mtandao wa simu"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Chagua njia ya ingizo"</string>
<string name="show_ime" msgid="6406112007347443383">"Ionyeshe kwenye skrini wakati kibodi halisi inatumika"</string>
<string name="hardware" msgid="1800597768237606953">"Onyesha kibodi pepe"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Wekea mipangilio <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Wekea kibodi halisi mipangilio"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Gusa ili uchague lugha na muundo"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Vifaa vya kusaidia kusikia"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Vitufe vya sauti vilivyoshikiliwa. Umewasha <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Vitufe vya sauti vimeshikiliwa. Umezima <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Achilia vitufe vya sauti. Ili uwashe <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, bonyeza na ushikilie tena vitufe vyote vya sauti kwa sekunde 3."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Chagua kipengele utakachotumia ukigusa kitufe cha ufikivu:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Chagua kipengele cha kutumia pamoja na ishara ya ufikivu (telezesha vidole viwili kutoka chini kwenda juu kwenye skrini):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Chagua kipengele cha kutumia pamoja na ishara ya ufikivu (telezesha vidole vitatu kutoka chini kwenda juu kwenye skrini):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> inatumia skrini zote kuonyesha maudhui"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Kifaa kina joto sana"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Kipengele cha Hali ya Skrini Mbili hakipatikani kwa sababu simu yako inapata joto sana"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Zima"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> imewekewa mipangilio"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Muundo wa kibodi umewekwa kuwa <xliff:g id="LAYOUT_1">%s</xliff:g>. Gusa ili ubadilishe."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Muundo wa kibodi umewekwa kuwa <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Gusa ili ubadilishe."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Muundo wa kibodi umewekwa kuwa <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Gusa ili ubadilishe."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Muundo wa kibodi umewekwa kuwa <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Gusa ili ubadilishe."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Mipangilio ya kibodi halisi imewekwa"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Gusa ili uangalie kibodi"</string>
</resources>
diff --git a/core/res/res/values-ta/strings.xml b/core/res/res/values-ta/strings.xml
index e1f709e6..a7eb123 100644
--- a/core/res/res/values-ta/strings.xml
+++ b/core/res/res/values-ta/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"வைஃபை"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"வைஃபை அழைப்பு"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ஆஃப்"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"வைஃபை மூலம் அழை"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"மொபைல் நெட்வொர்க் மூலமாக அழை"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"உள்ளீட்டு முறையைத் தேர்வுசெய்க"</string>
<string name="show_ime" msgid="6406112007347443383">"கைமுறை கீபோர்டு இயக்கத்தில் இருக்கும் போது IMEஐ திரையில் வைத்திரு"</string>
<string name="hardware" msgid="1800597768237606953">"விர்ச்சுவல் கீபோர்டை காட்டு"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> சாதனத்தை உள்ளமைத்தல்"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"கீபோர்டுகளை உள்ளமைத்தல்"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"மொழியையும் தளவமைப்பையும் தேர்ந்தெடுக்க, தட்டவும்"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"செவித்துணைக் கருவிகள்"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆன் செய்யப்பட்டது."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"ஒலியளவுக்கான விசைகளைப் பிடித்திருந்தீர்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ஆஃப் செய்யப்பட்டது."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ஒலியளவு பட்டன்களை அழுத்துவதை நிறுத்துங்கள். <xliff:g id="SERVICE_NAME">%1$s</xliff:g> சேவையை இயக்க, ஒலியளவு பட்டன்கள் இரண்டையும் 3 வினாடிகளுக்கு மீண்டும் அழுத்திப் பிடிக்கவும்."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"அணுகல்தன்மை பட்டனைத் தட்டுவதன் மூலம் பயன்படுத்த விரும்பும் அம்சத்தைத் தேர்ந்தெடுக்கவும்:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"அணுகல்தன்மை சைகைக்கான அம்சத்தைத் தேர்வுசெய்யவும் (இரண்டு விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"அணுகல்தன்மை சைகைக்கான அம்சத்தைத் தேர்வுசெய்யவும் (மூன்று விரல்களால் திரையின் கீழிருந்து மேல் நோக்கி ஸ்வைப் செய்யவும்):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"உள்ளடக்கத்தைக் காட்டுவதற்கு இரண்டு டிஸ்ப்ளேக்களையும் <xliff:g id="APP_NAME">%1$s</xliff:g> பயன்படுத்துகிறது"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"சாதனம் மிகவும் சூடாக உள்ளது"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"உங்கள் மொபைல் மிகவும் சூடாக இருப்பதால் இரட்டைத் திரை அம்சத்தைப் பயன்படுத்த முடியாது"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"முடக்கு"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> சாதனம் உள்ளமைக்கப்பட்டது"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"கீபோர்டு தளவமைப்பு <xliff:g id="LAYOUT_1">%s</xliff:g> மொழியில் அமைக்கப்பட்டது. மாற்ற தட்டவும்."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> ஆகிய மொழிகளில் கீபோர்டு தளவமைப்பு அமைக்கப்பட்டது. மாற்ற தட்டவும்."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> ஆகிய மொழிகளில் கீபோர்டு தளவமைப்பு அமைக்கப்பட்டது. மாற்ற தட்டவும்."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"கீபோர்டு தளவமைப்பு <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… ஆகிய மொழிகளில் அமைக்கப்பட்டது, மாற்ற தட்டவும்."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"கீபோர்டுகள் உள்ளமைக்கப்பட்டன"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"கீபோர்டுகளைப் பார்க்க தட்டவும்"</string>
</resources>
diff --git a/core/res/res/values-te/strings.xml b/core/res/res/values-te/strings.xml
index 4d66751..530c2e6 100644
--- a/core/res/res/values-te/strings.xml
+++ b/core/res/res/values-te/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi కాలింగ్"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ఆఫ్లో ఉంది"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi ద్వారా కాల్"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"మొబైల్ నెట్వర్క్ ద్వారా కాల్"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ఇన్పుట్ పద్ధతిని ఎంచుకోండి"</string>
<string name="show_ime" msgid="6406112007347443383">"దీన్ని భౌతిక కీబోర్డ్ యాక్టివ్గా ఉన్నప్పుడు స్క్రీన్పై ఉంచుతుంది"</string>
<string name="hardware" msgid="1800597768237606953">"వర్చువల్ కీబోర్డ్ను చూపు"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g>ను కాన్ఫిగర్ చేయండి"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"ఫిజికల్ కీబోర్డ్లను కాన్ఫిగర్ చేయండి"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"భాష మరియు లేఅవుట్ను ఎంచుకోవడానికి నొక్కండి"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"వినికిడి పరికరం"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆన్ చేయబడింది"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"వాల్యూమ్ కీలు నొక్కి ఉంచబడ్డాయి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ఆఫ్ చేయబడింది"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"వాల్యూమ్ కీలను రిలీజ్ చేయండి. <xliff:g id="SERVICE_NAME">%1$s</xliff:g>ను ఆన్ చేయడానికి, రెండు వాల్యూమ్ కీలను మళ్లీ 3 సెకన్ల పాటు నొక్కి పట్టుకోండి."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"యాక్సెస్ సామర్థ్య బటన్ను మీరు నొక్కినప్పుడు ఉపయోగించాల్సిన ఒక ఫీచర్ను ఎంచుకోండి:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక ఫీచర్ని ఎంచుకోండి (రెండు వేళ్లతో స్క్రీన్ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"యాక్సెసిబిలిటీ సంజ్ఞతో ఉపయోగించడానికి ఒక ఫీచర్ను ఎంచుకోండి (మూడు చేతి వేళ్లతో స్క్రీన్ను కింద నుండి పైకి స్వైప్ చేయండి):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"కంటెంట్ను చూపడం కోసం <xliff:g id="APP_NAME">%1$s</xliff:g> రెండు డిస్ప్లేలనూ ఉపయోగిస్తుంది"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"పరికరం చాలా వేడిగా ఉంది"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"మీ ఫోన్ చాలా వేడిగా అవుతున్నందున, డ్యూయల్ స్క్రీన్ అందుబాటులో లేదు"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ఆఫ్ చేయండి"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> కాన్ఫిగర్ చేయబడింది"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"కీబోర్డ్ లేఅవుట్ <xliff:g id="LAYOUT_1">%s</xliff:g>కు సెట్ చేయబడింది. మార్చడానికి ట్యాప్ చేయండి."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"కీబోర్డ్ లేఅవుట్ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>కు సెట్ చేయబడింది. మార్చడానికి ట్యాప్ చేయండి."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"కీబోర్డ్ లేఅవుట్ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>కు సెట్ చేయబడింది. మార్చడానికి ట్యాప్ చేయండి."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"కీబోర్డ్ లేఅవుట్ <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>కు సెట్ చేయబడింది… మార్చడానికి ట్యాప్ చేయండి."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"ఫిజికల్ కీబోర్డ్లు కాన్ఫిగర్ చేయబడ్డాయి"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"కీబోర్డ్లను చూడటానికి ట్యాప్ చేయండి"</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 2d00d89f..0b481f3 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"การโทรผ่าน Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"ปิด"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"โทรผ่าน Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"โทรผ่านเครือข่ายมือถือ"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"เลือกวิธีการป้อนข้อมูล"</string>
<string name="show_ime" msgid="6406112007347443383">"เปิดทิ้งไว้บนหน้าจอในระหว่างใช้งานแป้นพิมพ์จริง"</string>
<string name="hardware" msgid="1800597768237606953">"แสดงแป้นพิมพ์เสมือน"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"กำหนดค่า <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"กำหนดค่าแป้นพิมพ์จริง"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"แตะเพื่อเลือกภาษาและรูปแบบ"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" กขฃคฅฆงจฉชซฌญฎฏฐฑฒณดตถทธนบปผฝพฟภมยรลวศษสหฬอฮ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"เครื่องช่วยฟัง"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว เปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"กดปุ่มปรับระดับเสียงค้างไว้แล้ว ปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> แล้ว"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"ปล่อยปุ่มปรับระดับเสียง หากต้องการเปิด <xliff:g id="SERVICE_NAME">%1$s</xliff:g> ให้กดปุ่มปรับระดับเสียงทั้ง 2 ปุ่มค้างไว้อีกครั้งเป็นเวลา 3 วินาที"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"เลือกฟีเจอร์ที่จะใช้เมื่อคุณแตะปุ่มการช่วยเหลือพิเศษดังต่อไปนี้"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"เลือกฟีเจอร์ที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 2 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ) ดังต่อไปนี้"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"เลือกฟีเจอร์ที่จะใช้กับท่าทางสัมผัสการช่วยเหลือพิเศษ (ใช้ 3 นิ้วเลื่อนขึ้นจากด้านล่างของหน้าจอ) ดังต่อไปนี้"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังใช้จอแสดงผลทั้งสองจอเพื่อแสดงเนื้อหา"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"อุปกรณ์ร้อนเกินไป"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"หน้าจอคู่ไม่พร้อมให้ใช้งานเนื่องจากโทรศัพท์ของคุณร้อนเกินไป"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"ปิด"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"กำหนดค่า <xliff:g id="DEVICE_NAME">%s</xliff:g> แล้ว"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"ตั้งค่ารูปแบบแป้นพิมพ์เป็นภาษา<xliff:g id="LAYOUT_1">%s</xliff:g> แตะเพื่อเปลี่ยน"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"ตั้งค่ารูปแบบแป้นพิมพ์เป็นภาษา<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> แตะเพื่อเปลี่ยน"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"ตั้งค่ารูปแบบแป้นพิมพ์เป็นภาษา<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> แตะเพื่อเปลี่ยน"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"ตั้งค่ารูปแบบแป้นพิมพ์เป็นภาษา<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… แตะเพื่อเปลี่ยน"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"กำหนดค่าแป้นพิมพ์จริงแล้ว"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"แตะเพื่อดูแป้นพิมพ์"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 238cbfb..e7005db 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Pagtawag Gamit ang WiFi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Naka-off"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Tumawag gamit ang Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Tumawag gamit ang mobile network"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Pumili ng pamamaraan ng pag-input"</string>
<string name="show_ime" msgid="6406112007347443383">"Panatilihin ito sa screen habang aktibo ang pisikal na keyboard"</string>
<string name="hardware" msgid="1800597768237606953">"Ipakita ang virtual keyboard"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"I-configure ang <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"I-configure ang mga pisikal na keyboard"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"I-tap upang pumili ng wika at layout"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Mga hearing device"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Pinindot nang matagal ang volume keys. Na-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Pinindot nang matagal ang volume keys. Na-off ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Bitawan ang mga volume key. Para i-on ang <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, muling pindutin nang matagal ang dalawang volume key sa loob ng 3 segundo."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Pumili ng feature na gagana sa pamamagitan ng pag-tap mo sa button ng accessibility:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Pumili ng feature na gagana sa pamamagitan ng galaw ng accessibility (pag-swipe pataas mula sa ibaba ng screen gamit ang dalawang daliri):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Pumili ng feature na gagana sa pamamagitan ng galaw ng accessibility (pag-swipe pataas mula sa ibaba ng screen gamit ang tatlong daliri):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Ginagamit ng <xliff:g id="APP_NAME">%1$s</xliff:g> ang parehong display para magpakita ng content"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Masyadong mainit ang device"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Hindi available ang Dual Screen dahil masyado nang umiinit ang telepono mo"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"I-off"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Na-configure ang <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Naitakda ang layout ng keyboard sa <xliff:g id="LAYOUT_1">%s</xliff:g>. I-tap para baguhin."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Naitakda ang layout ng keyboard sa <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. I-tap para baguhin."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Naitakda ang layout ng keyboard sa <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. I-tap para baguhin."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Naitakda ang layout ng keyboard sa <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… I-tap para baguhin."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Na-configure ang mga pisikal na keyboard"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"I-tap para tingnan ang mga keyboard"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 834bd47..998b2fa 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Kablosuz"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Kablosuz Çağrı"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Kapalı"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Kablosuz ağ üzerinden arama"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Mobil ağ üzerinden arama"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Giriş yöntemini seçin"</string>
<string name="show_ime" msgid="6406112007347443383">"Fiziksel klavye etkin durumdayken ekranda tut"</string>
<string name="hardware" msgid="1800597768237606953">"Sanal klavyeyi göster"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> ayarlarını yapılandır"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Fiziksel klavyeleri yapılandırın"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Dili ve düzeni seçmek için dokunun"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"İşitme cihazları"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> açıldı."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ses tuşlarını basılı tuttunuz. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> kapatıldı."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Ses seviyesi tuşlarını bırakın. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> hizmetini etkinleştirmek için her iki ses seviyesi tuşuna yeniden basıp 3 saniye boyunca basılı tutun."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Erişilebilirlik düğmesine dokunduğunuzda kullanmak için bir özellik seçin:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Erişilebilirlik hareketiyle (iki parmakla ekranın altından yukarı kaydırma) kullanılacak bir özellik seçin:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Erişilebilirlik hareketiyle (üç parmakla ekranın altından yukarı kaydırma) kullanılacak bir özellik seçin:"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>, içeriği göstermek için her iki ekranı da kullanıyor"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Cihaz çok ısındı"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Telefonunuz çok ısındığı için Çift Ekran kullanılamıyor"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Kapat"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> yapılandırıldı"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Klavye düzeni <xliff:g id="LAYOUT_1">%s</xliff:g> olarak ayarlandı. Değiştirmek için dokunun."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Klavye düzeni <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g> olarak ayarlandı. Değiştirmek için dokunun."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Klavye düzeni <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> olarak ayarlandı. Değiştirmek için dokunun."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klavye düzeni <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g> olarak ayarlandı… Değiştirmek için dokunun."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Fiziksel klavyeler yapılandırıldı"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klavyeleri görüntülemek için dokunun"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index d9eef0d..be4b2a2e 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -142,6 +142,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Дзвінки через Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"Передавання голосу через Wi-Fi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Вимкнено"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Телефонувати через Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Телефонувати через мобільну мережу"</string>
@@ -227,9 +229,9 @@
<string name="reboot_to_update_title" msgid="2125818841916373708">"Оновлення системи Android"</string>
<string name="reboot_to_update_prepare" msgid="6978842143587422365">"Підготовка до оновлення…"</string>
<string name="reboot_to_update_package" msgid="4644104795527534811">"Обробка пакета оновлення…"</string>
- <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Перезавантаження…"</string>
+ <string name="reboot_to_update_reboot" msgid="4474726009984452312">"Перезапуск…"</string>
<string name="reboot_to_reset_title" msgid="2226229680017882787">"Скидання налаштувань"</string>
- <string name="reboot_to_reset_message" msgid="3347690497972074356">"Перезавантаження…"</string>
+ <string name="reboot_to_reset_message" msgid="3347690497972074356">"Перезапуск…"</string>
<string name="shutdown_progress" msgid="5017145516412657345">"Вимкнення..."</string>
<string name="shutdown_confirm" product="tablet" msgid="2872769463279602432">"Ваш пристрій буде вимкнено."</string>
<string name="shutdown_confirm" product="tv" msgid="7975942887313518330">"Пристрій Android TV буде вимкнено."</string>
@@ -1395,10 +1397,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Вибрати метод введення"</string>
<string name="show_ime" msgid="6406112007347443383">"Утримуйте на екрані, коли активна фізична клавіатура"</string>
<string name="hardware" msgid="1800597768237606953">"Показати віртуальну клавіатуру"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Налаштуйте клавіатуру \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\""</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Налаштуйте фізичні клавіатури"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Торкніться, щоб вибрати мову та розкладку"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789АБВГҐДЕЄЖЗИІЇЙКЛМНОПРСТУФХЦЧШЩЬЮЯ"</string>
@@ -1723,8 +1723,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Слухові апарати"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> увімкнено."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Утримано клавіші гучності. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> вимкнено."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Відпустіть клавіші гучності. Щоб увімкнути сервіс <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, натисніть і втримуйте обидві клавіші гучності протягом 3 секунд."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Виберіть функцію для кнопки спеціальних можливостей:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Виберіть функцію для жесту спеціальних можливостей (проведення двома пальцями знизу вгору):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Виберіть функцію для жесту спеціальних можливостей (проведення трьома пальцями знизу вгору):"</string>
@@ -2328,19 +2327,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> використовує обидва екрани для показу контенту"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Пристрій сильно нагрівається"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Подвійний екран недоступний, оскільки телефон сильно нагрівається"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Вимкнути"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Клавіатуру \"<xliff:g id="DEVICE_NAME">%s</xliff:g>\" налаштовано"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Вибрано розкладку клавіатури \"<xliff:g id="LAYOUT_1">%s</xliff:g>\". Натисніть, щоб змінити."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Вибрано такі розкладки клавіатури: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Натисніть, щоб змінити."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Вибрано такі розкладки клавіатури: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Натисніть, щоб змінити."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Вибрано такі розкладки клавіатури: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Натисніть, щоб змінити."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Фізичні клавіатури налаштовано"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Натисніть, щоб переглянути клавіатури"</string>
</resources>
diff --git a/core/res/res/values-ur/strings.xml b/core/res/res/values-ur/strings.xml
index ac30a26..977374e 100644
--- a/core/res/res/values-ur/strings.xml
+++ b/core/res/res/values-ur/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi کالنگ"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Wi-Fi کال"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"آف"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi پر کال کریں"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"موبائل نیٹ ورک پر کال کریں"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"ان پٹ کا طریقہ منتخب کریں"</string>
<string name="show_ime" msgid="6406112007347443383">"جب فزیکل کی بورڈ فعال ہو تو IME کو اسکرین پر رکھیں"</string>
<string name="hardware" msgid="1800597768237606953">"ورچوئل کی بورڈ دکھائیں"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"<xliff:g id="DEVICE_NAME">%s</xliff:g> کنفیگر کریں"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"فزیکل کی بورڈز کنفیگر کریں"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"زبان اور لے آؤٹ منتخب کرنے کیلئے تھپتھپائیں"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"سماعتی آلات"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آن ہے۔"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"والیوم کی کلیدوں کو دبائے رکھا گیا۔ <xliff:g id="SERVICE_NAME">%1$s</xliff:g> آف ہے۔"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"والیوم کی کلیدوں کو ریلیز کریں <xliff:g id="SERVICE_NAME">%1$s</xliff:g> کو آن کرنے کے لیے، والیوم کی دونوں کلیدوں کو دوبارہ 3 سیکنڈ تک چھوئیں اور دبائے رکھیں۔"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"ایکسیسبیلٹی بٹن پر تھپتھپانے وقت استعمال کرنے کیلئے ایک خصوصیت منتخب کریں:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک خصوصیت چنیں (دو انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"ایکسیسبیلٹی اشارہ کے ساتھ استعمال کرنے کے لیے ایک خصوصیت چنیں (تین انگلیوں سے اسکرین کے نیچے سے اوپر کی طرف سوائپ کریں):"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> مواد دکھانے کیلئے دونوں ڈسپلیز استعمال کر رہی ہے"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"آلہ بہت زیادہ گرم ہے"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"دوہری اسکرین دستیاب نہیں ہے کیونکہ آپ کا فون بہت زیادہ گرم ہو رہا ہے"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"آف کریں"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> میں کنفیگر کیا گیا"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%s</xliff:g> پر سیٹ ہے۔ تبدیل کرنے کیلئے تھپتھپائیں۔"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g> پر سیٹ ہے۔ تبدیل کرنے کیلئے تھپتھپائیں۔"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> پر سیٹ ہے۔ تبدیل کرنے کیلئے تھپتھپائیں۔"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"کی بورڈ لے آؤٹ <xliff:g id="LAYOUT_1">%1$s</xliff:g>، <xliff:g id="LAYOUT_2">%2$s</xliff:g>، <xliff:g id="LAYOUT_3">%3$s</xliff:g> پر سیٹ ہے… تبدیل کرنے کے لیے تھپتھپائیں۔"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"فزیکل کی بورڈز کنفیگر کئے گئے"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"کی بورڈز دیکھنے کے لیے تھپتھپائیں"</string>
</resources>
diff --git a/core/res/res/values-uz/strings.xml b/core/res/res/values-uz/strings.xml
index 0f7a9ef..08b4471 100644
--- a/core/res/res/values-uz/strings.xml
+++ b/core/res/res/values-uz/strings.xml
@@ -140,6 +140,7 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi chaqiruv"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWi-Fi"</string>
+ <string name="wfcSpnFormat_wifi_call" msgid="434016592539090004">"Wi-Fi chaqiruv"</string>
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Yoqilmagan"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Wi-Fi orqali chaqiruv"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Mobil tarmoq orqali chaqiruv"</string>
@@ -1393,10 +1394,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Matn kiritish usulini tanlang"</string>
<string name="show_ime" msgid="6406112007347443383">"Tashqi klaviatura ulanganida ekranda chiqib turadi"</string>
<string name="hardware" msgid="1800597768237606953">"Virtual klaviatura"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Sozlang: <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Tashqi klaviaturalarni sozlang"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Til va sxemani belgilash uchun bosing"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1720,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Eshitish qurilmalari"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> yoqildi."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Tovush tugmalari bosib turildi. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> faolsizlantirildi."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Tovush tugmalarini qoʻyib yuboring. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> xizmatini yoqish uchun ikkala tovush tugmasini 3 soniya bosib turing."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Maxsus imkoniyatlar tugmasi bosilganda ishga tushadigan funksiyani tanlang:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Maxsus imkoniyatlar ishorasi bilan ishga tushadigan funksiyani tanlang (ikkita barmoq bilan ekranning pastidan tepaga surib tortilganda):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Maxsus imkoniyatlar ishorasi bilan ishga tushadigan funksiyani tanlang (uchta barmoq bilan ekranning pastidan tepaga surib tortilganda):"</string>
@@ -2326,19 +2324,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> kontentni ikkala ekranda chiqarmoqda"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Qurilma qizib ketdi"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Telefon qizib ketgani uchun hozir ikki ekranli rejim ishlamaydi"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Faolsizlantirish"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"<xliff:g id="DEVICE_NAME">%s</xliff:g> sozlandi"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Klaviatura terilmasi bunga sozlandi: <xliff:g id="LAYOUT_1">%s</xliff:g>. Oʻzgartirish uchun ustiga bosing."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Klaviatura terilmasi bunga sozlandi: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Oʻzgartirish uchun ustiga bosing."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Klaviatura terilmasi bunga sozlandi: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Oʻzgartirish uchun ustiga bosing."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Klaviatura terilmasi bunga sozlandi: <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Oʻzgartirish uchun ustiga bosing."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Tashqi klaviaturalar sozlandi"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Klaviaturalarni ochish uchun ustiga bosing"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index 2bcadcc..29acdc0 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Gọi qua Wi-Fi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Tắt"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Gọi qua Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Gọi qua mạng di động"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Chọn phương thức nhập"</string>
<string name="show_ime" msgid="6406112007347443383">"Hiện bàn phím ảo trên màn hình trong khi bàn phím vật lý đang hoạt động"</string>
<string name="hardware" msgid="1800597768237606953">"Hiện bàn phím ảo"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Định cấu hình <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Định cấu hình bàn phím vật lý"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Nhấn để chọn ngôn ngữ và bố cục"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Thiết bị trợ thính"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã bật."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Bạn đã giữ các phím âm lượng. <xliff:g id="SERVICE_NAME">%1$s</xliff:g> đã tắt."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Thả phím âm lượng. Để bật <xliff:g id="SERVICE_NAME">%1$s</xliff:g>, hãy nhấn và giữ cả 2 phím âm lượng trong 3 giây một lần nữa."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Chọn một tính năng để dùng khi bạn nhấn nút hỗ trợ tiếp cận:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Chọn một tính năng để dùng với cử chỉ hỗ trợ tiếp cận (dùng 2 ngón tay vuốt lên từ cuối màn hình):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Chọn một tính năng để dùng với cử chỉ hỗ trợ tiếp cận (dùng 3 ngón tay vuốt lên từ cuối màn hình):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang dùng cả hai màn hình để thể hiện nội dung"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Thiết bị quá nóng"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"Không bật được chế độ Màn hình đôi vì điện thoại của bạn quá nóng"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Tắt"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"Đã định cấu hình <xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Đã thiết lập bố cục bàn phím thành <xliff:g id="LAYOUT_1">%s</xliff:g>. Hãy nhấn để thay đổi."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Đã thiết lập bố cục bàn phím thành <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Hãy nhấn để thay đổi."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Đã thiết lập bố cục bàn phím thành <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Hãy nhấn để thay đổi."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Đã thiết lập bố cục bàn phím thành <xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Hãy nhấn để thay đổi."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Đã định cấu hình bàn phím vật lý"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Nhấn để xem bàn phím"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 2ca846e..428531e 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"WLAN"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"WLAN 通话"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"已关闭"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"通过 WLAN 进行通话"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"通过移动网络进行通话"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"选择输入法"</string>
<string name="show_ime" msgid="6406112007347443383">"开启后,连接到实体键盘时,它会一直显示在屏幕上"</string>
<string name="hardware" msgid="1800597768237606953">"显示虚拟键盘"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"配置“<xliff:g id="DEVICE_NAME">%s</xliff:g>”"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"配置物理键盘"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"点按即可选择语言和布局"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"助听设备"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已开启。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量键。<xliff:g id="SERVICE_NAME">%1$s</xliff:g>已关闭。"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"松开音量键。如要启用 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,请再次同时按住两个音量键 3 秒。"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"选择点按“无障碍”按钮后要使用的功能:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"选择要搭配无障碍手势(用两根手指从屏幕底部向上滑动)使用的功能:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"选择要搭配无障碍手势(用三根手指从屏幕底部向上滑动)使用的功能:"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"<xliff:g id="APP_NAME">%1$s</xliff:g>正在使用双屏幕显示内容"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"设备过热"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"手机过热,因此无法使用双屏幕功能"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"关闭"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"已配置“<xliff:g id="DEVICE_NAME">%s</xliff:g>”"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"键盘布局已设为<xliff:g id="LAYOUT_1">%s</xliff:g>。点按即可更改。"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"键盘布局已设为<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>。点按即可更改。"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"键盘布局已设为<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>。点按即可更改。"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"键盘布局已设为<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>…点按即可更改。"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"已配置物理键盘"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"点按即可查看键盘"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 080165c..0caf957 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi 通話"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"關閉"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"使用 Wi-Fi 通話"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"使用流動網絡通話"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"選擇輸入法"</string>
<string name="show_ime" msgid="6406112007347443383">"在實體鍵盤處於連接狀態時保持顯示"</string>
<string name="hardware" msgid="1800597768237606953">"顯示虛擬鍵盤"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"設定「<xliff:g id="DEVICE_NAME">%s</xliff:g>」"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"設定實體鍵盤"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"輕按即可選取語言和鍵盤配置"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"助聽器"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已開啟。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。<xliff:g id="SERVICE_NAME">%1$s</xliff:g> 已關閉。"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"鬆開音量鍵。如果要開 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時㩒住兩個音量鍵 3 秒。"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"請選擇輕按「無障礙功能」按鈕時使用的功能:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"請選擇要配搭無障礙手勢 (使用兩隻手指從螢幕底部向上滑動) 使用的功能:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"請選擇要配搭無障礙手勢 (使用三隻手指從螢幕底部向上滑動) 使用的功能:"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在使用雙螢幕顯示內容"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"裝置過熱"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"由於手機過熱,雙螢幕功能無法使用"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"關閉"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"已設定「<xliff:g id="DEVICE_NAME">%s</xliff:g>」"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"鍵盤版面配置已設定為<xliff:g id="LAYOUT_1">%s</xliff:g>。輕按即可變更。"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"鍵盤版面配置已設定為<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>。輕按即可變更。"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"鍵盤版面配置已設定為<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>。輕按即可變更。"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"鍵盤版面配置已設定為<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>…輕按即可變更。"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"已設定實體鍵盤"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"輕按即可查看鍵盤"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index 460bc73..90d7e21 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Wi-Fi 通話"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"關閉"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"透過 Wi-Fi 進行通話"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"透過行動網路進行通話"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"選擇輸入法"</string>
<string name="show_ime" msgid="6406112007347443383">"使用實體鍵盤時仍繼續顯示虛擬鍵盤"</string>
<string name="hardware" msgid="1800597768237606953">"顯示虛擬鍵盤"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"設定「<xliff:g id="DEVICE_NAME">%s</xliff:g>」"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"設定實體鍵盤"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"輕觸即可選取語言和版面配置"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"助聽器"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已開啟。"</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"已按住音量鍵。「<xliff:g id="SERVICE_NAME">%1$s</xliff:g>」已關閉。"</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"放開音量鍵。如要開啟 <xliff:g id="SERVICE_NAME">%1$s</xliff:g>,請同時按住音量調高鍵和調低鍵 3 秒。"</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"輕觸無障礙工具按鈕後,選擇你想使用的功能:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"選擇要搭配無障礙手勢 (用兩指從螢幕底部向上滑動) 使用的功能:"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"選擇要搭配無障礙手勢 (用三指從螢幕底部向上滑動) 使用的功能:"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在使用雙螢幕顯示內容"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"裝置過熱"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"手機過熱,因此無法使用雙螢幕功能"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"停用"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"已設定「<xliff:g id="DEVICE_NAME">%s</xliff:g>」"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"鍵盤配置已設為<xliff:g id="LAYOUT_1">%s</xliff:g>。輕觸即可變更。"</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"鍵盤配置已設為<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>。輕觸即可變更。"</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"鍵盤配置已設為<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>。輕觸即可變更。"</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"鍵盤配置已設為<xliff:g id="LAYOUT_1">%1$s</xliff:g>、<xliff:g id="LAYOUT_2">%2$s</xliff:g>、<xliff:g id="LAYOUT_3">%3$s</xliff:g>…輕觸即可變更。"</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"已設定實體鍵盤"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"輕觸即可查看鍵盤"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index 363660d..967d9ea 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -140,6 +140,8 @@
<string name="wfcSpnFormat_wifi" msgid="1376356951297043426">"I-Wi-Fi"</string>
<string name="wfcSpnFormat_wifi_calling_wo_hyphen" msgid="7178561009225028264">"Ukushaya kwe-WiFi"</string>
<string name="wfcSpnFormat_vowifi" msgid="8371335230890725606">"VoWifi"</string>
+ <!-- no translation found for wfcSpnFormat_wifi_call (434016592539090004) -->
+ <skip />
<string name="wifi_calling_off_summary" msgid="5626710010766902560">"Valiwe"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1035175836270943089">"Ikholi esebenza nge-Wi-Fi"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="4958965609212575619">"Shaya ngenethiwekhi yeselula"</string>
@@ -1393,10 +1395,8 @@
<string name="select_input_method" msgid="3971267998568587025">"Khetha indlela yokufaka"</string>
<string name="show_ime" msgid="6406112007347443383">"Yigcine kusikrini ngenkathi kusebenza ikhibhodi ephathekayo"</string>
<string name="hardware" msgid="1800597768237606953">"Bonisa ikhibhodi ebonakalayo"</string>
- <!-- no translation found for select_keyboard_layout_notification_title (5823199895322205589) -->
- <skip />
- <!-- no translation found for select_multiple_keyboards_layout_notification_title (6999491025126641938) -->
- <skip />
+ <string name="select_keyboard_layout_notification_title" msgid="5823199895322205589">"Lungisa i-<xliff:g id="DEVICE_NAME">%s</xliff:g>"</string>
+ <string name="select_multiple_keyboards_layout_notification_title" msgid="6999491025126641938">"Lungiselela amakhibhodi aphathekayo"</string>
<string name="select_keyboard_layout_notification_message" msgid="8835158247369158154">"Thepha ukuze ukhethe ulimi nesakhiwo"</string>
<string name="fast_scroll_alphabet" msgid="8854435958703888376">" ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
<string name="fast_scroll_numeric_alphabet" msgid="2529539945421557329">" 0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"</string>
@@ -1721,8 +1721,7 @@
<string name="hearing_aids_feature_name" msgid="1125892105105852542">"Amadivayizi okuzwa"</string>
<string name="accessibility_shortcut_enabling_service" msgid="5473495203759847687">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivuliwe."</string>
<string name="accessibility_shortcut_disabling_service" msgid="8675244165062700619">"Ubambe okhiye bevolumu. I-<xliff:g id="SERVICE_NAME">%1$s</xliff:g> ivaliwe."</string>
- <!-- no translation found for accessibility_shortcut_spoken_feedback (3760999147597564314) -->
- <skip />
+ <string name="accessibility_shortcut_spoken_feedback" msgid="3760999147597564314">"Khipha okhiye bevolumu. Ukuze uvule i-<xliff:g id="SERVICE_NAME">%1$s</xliff:g>, cindezela bese ubamba bobabili okhiye bevolumu futhi imizuzwana emi-3."</string>
<string name="accessibility_button_prompt_text" msgid="8343213623338605305">"Khetha isici ozosisebenzisa uma uthepha inkinobho yokufinyelela:"</string>
<string name="accessibility_gesture_prompt_text" msgid="8742535972130563952">"Khetha isici ozosisebenzisa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela ngaphansi kwesikrini ngeminwe emibili):"</string>
<string name="accessibility_gesture_3finger_prompt_text" msgid="5211827854510660203">"Khetha isici ozosisebenzisa ngokuthinta kokufinyeleleka (swayiphela phezulu kusukela phansi esikrinini ngeminwe emithathu):"</string>
@@ -2326,19 +2325,18 @@
<string name="concurrent_display_notification_active_content" msgid="5889355473710601270">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> isebenzisa zombili izibonisi ukukhombisa okuqukethwe"</string>
<string name="concurrent_display_notification_thermal_title" msgid="5921609404644739229">"Idivayisi ifudumele kakhulu"</string>
<string name="concurrent_display_notification_thermal_content" msgid="2075484836527609319">"I-Dual Screen ayitholakali ngoba ifoni yakho iqala ukufudumala kakhulu"</string>
+ <!-- no translation found for concurrent_display_notification_power_save_title (1794569070730736281) -->
+ <skip />
+ <!-- no translation found for concurrent_display_notification_power_save_content (2198116070583851493) -->
+ <skip />
+ <!-- no translation found for device_state_notification_settings_button (691937505741872749) -->
+ <skip />
<string name="device_state_notification_turn_off_button" msgid="6327161707661689232">"Vala"</string>
- <!-- no translation found for keyboard_layout_notification_selected_title (1202560174252421219) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_one_selected_message (4314216053129257197) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_two_selected_message (1876349944065922950) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_three_selected_message (280734264593115419) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_more_than_three_selected_message (1581834181578206937) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_title (5242444914367024499) -->
- <skip />
- <!-- no translation found for keyboard_layout_notification_multiple_selected_message (6576533454124419202) -->
- <skip />
+ <string name="keyboard_layout_notification_selected_title" msgid="1202560174252421219">"I-<xliff:g id="DEVICE_NAME">%s</xliff:g> ilungiselelwe"</string>
+ <string name="keyboard_layout_notification_one_selected_message" msgid="4314216053129257197">"Isakhiwo sekhibhodi sisethelwe ku-<xliff:g id="LAYOUT_1">%s</xliff:g>. Thepha ukushintsha."</string>
+ <string name="keyboard_layout_notification_two_selected_message" msgid="1876349944065922950">"Uhlaka lwekhibhodi lusethelwe ku-<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>. Thepha ukushintsha."</string>
+ <string name="keyboard_layout_notification_three_selected_message" msgid="280734264593115419">"Uhlaka lwekhibhodi lusethelwe ku-<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>. Thepha ukushintsha."</string>
+ <string name="keyboard_layout_notification_more_than_three_selected_message" msgid="1581834181578206937">"Uhlaka lwekhibhodi lusethelwe ku-<xliff:g id="LAYOUT_1">%1$s</xliff:g>, <xliff:g id="LAYOUT_2">%2$s</xliff:g>, <xliff:g id="LAYOUT_3">%3$s</xliff:g>… Thepha ukuze ushintshe."</string>
+ <string name="keyboard_layout_notification_multiple_selected_title" msgid="5242444914367024499">"Amakhibhodi aphathekayo amisiwe"</string>
+ <string name="keyboard_layout_notification_multiple_selected_message" msgid="6576533454124419202">"Thepha ukuze ubuke amakhibhodi"</string>
</resources>
diff --git a/core/res/res/values/arrays.xml b/core/res/res/values/arrays.xml
index b35481d..97e753e 100644
--- a/core/res/res/values/arrays.xml
+++ b/core/res/res/values/arrays.xml
@@ -227,6 +227,12 @@
<string-array name="device_state_notification_thermal_contents">
<item>@string/concurrent_display_notification_thermal_content</item>
</string-array>
+ <string-array name="device_state_notification_power_save_titles">
+ <item>@string/concurrent_display_notification_power_save_title</item>
+ </string-array>
+ <string-array name="device_state_notification_power_save_contents">
+ <item>@string/concurrent_display_notification_power_save_content</item>
+ </string-array>
<!-- Certificate digests for trusted apps that will be allowed to obtain the knownSigner of the
demo device provisioning permissions. -->
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 000e5b2..c34f670 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -1312,15 +1312,21 @@
<!-- The container color of surface the most elevated, which replaces the previous surface
variant. @hide -->
<attr name="materialColorSurfaceContainerHighest" format="color"/>
- <!-- undefined @hide -->
+ <!-- A tonal variation of the on surface color that passes accessibility guidelines for
+ text/iconography when drawn on top of surface variant. @hide -->
<attr name="materialColorOnSurfaceVariant" format="color"/>
- <!-- undefined @hide -->
+ <!-- A color meant to be used in element outlines. @hide -->
<attr name="materialColorOutline" format="color"/>
- <!-- undefined @hide -->
+ <!-- A color meant to be used in element outlines on the surface-variant color. @hide -->
+ <attr name="materialColorOutlineVariant" format="color"/>
+ <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of
+ primary. @hide -->
<attr name="materialColorOnPrimary" format="color"/>
- <!-- undefined @hide -->
+ <!-- A color that passes accessibility guidelines for text/iconography when drawn on top of
+ surface. @hide -->
<attr name="materialColorOnSurface" format="color"/>
- <!-- undefined @hide -->
+ <!-- The container color of surface, which replaces the previous surface at elevation level
+ 2. @hide -->
<attr name="materialColorSurfaceContainer" format="color"/>
<!-- The container color of surface, which replaces the previous surface at elevation level
2. @hide -->
diff --git a/core/res/res/values/colors.xml b/core/res/res/values/colors.xml
index 692011b..42ccfbe 100644
--- a/core/res/res/values/colors.xml
+++ b/core/res/res/values/colors.xml
@@ -465,6 +465,7 @@
<color name="system_surface_variant_light">#E1E2EC</color>
<color name="system_on_surface_variant_light">#44474F</color>
<color name="system_outline_light">#72747D</color>
+ <color name="system_outline_variant_light">#C4C7C5</color>
<color name="system_error_light">#C00003</color>
<color name="system_on_error_light">#FFFFFF</color>
<color name="system_error_container_light">#FFDAD5</color>
@@ -520,6 +521,7 @@
<color name="system_surface_variant_dark">#44474F</color>
<color name="system_on_surface_variant_dark">#C4C6D0</color>
<color name="system_outline_dark">#72747D</color>
+ <color name="system_outline_variant_dark">#444746</color>
<color name="system_error_dark">#FFB4A8</color>
<color name="system_on_error_dark">#690001</color>
<color name="system_error_container_dark">#930001</color>
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 135e5d2..a16d6d5 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -720,14 +720,13 @@
display is powered on at the same time. -->
<bool name="config_supportsConcurrentInternalDisplays">true</bool>
- <!-- Map of DeviceState to rotation lock setting. Each entry must be in the format
- "key:value", for example: "0:1".
- The keys are device states, and the values are one of
- Settings.Secure.DeviceStateRotationLockSetting.
- Any device state that doesn't have a default set here will be treated as
- DEVICE_STATE_ROTATION_LOCK_IGNORED meaning it will not have its own rotation lock setting.
- If this map is missing, the feature is disabled and only one global rotation lock setting
- will apply, regardless of device state. -->
+ <!-- Map of device posture to rotation lock setting. Each entry must be in the format
+ "key:value", or "key:value:fallback_key" for example: "0:1" or "2:0:1". The keys are one of
+ Settings.Secure.DeviceStateRotationLockKey, and the values are one of
+ Settings.Secure.DeviceStateRotationLockSetting.
+ The fallback is a key to a device posture that can be specified when the value is
+ Settings.Secure.DEVICE_STATE_ROTATION_LOCK_IGNORED.
+ -->
<string-array name="config_perDeviceStateRotationLockDefaults" />
<!-- Dock behavior -->
@@ -2079,7 +2078,7 @@
<integer name="config_audio_ring_vol_default">5</integer>
<!-- Enable sound dose computation and warnings -->
- <bool name="config_audio_csd_enabled_default">false</bool>
+ <bool name="config_audio_csd_enabled_default">true</bool>
<!-- The default value for whether head tracking for
spatial audio is enabled for a newly connected audio device -->
@@ -3254,6 +3253,9 @@
<!-- Feature flag to store TaskSnapshot in 16 bit pixel format to save memory. -->
<bool name="config_use16BitTaskSnapshotPixelFormat">false</bool>
+ <!-- The amount to scale fullscreen activity snapshot for predict-back animation. -->
+ <item name="config_resActivitySnapshotScale" format="float" type="dimen">0.6</item>
+
<!-- Determines whether recent tasks are provided to the user. Default device has recents
property. If this is false, then the following recents config flags are ignored. -->
<bool name="config_hasRecents">true</bool>
@@ -6095,7 +6097,7 @@
<bool name="config_settingsHelpLinksEnabled">false</bool>
<!-- Whether or not to enable the lock screen entry point for the QR code scanner. -->
- <bool name="config_enableQrCodeScannerOnLockScreen">false</bool>
+ <bool name="config_enableQrCodeScannerOnLockScreen">true</bool>
<!-- Default component for QR code scanner -->
<string name="config_defaultQrCodeComponent"></string>
diff --git a/core/res/res/values/dimens.xml b/core/res/res/values/dimens.xml
index 5bb86dc..80bf795 100644
--- a/core/res/res/values/dimens.xml
+++ b/core/res/res/values/dimens.xml
@@ -356,7 +356,7 @@
<dimen name="notification_headerless_margin_twoline">20dp</dimen>
<!-- The height of each of the 1 or 2 lines in the headerless notification template -->
- <dimen name="notification_headerless_line_height">24dp</dimen>
+ <dimen name="notification_headerless_line_height">24sp</dimen>
<!-- vertical margin for the headerless notification content -->
<dimen name="notification_headerless_min_height">56dp</dimen>
diff --git a/core/res/res/values/public-staging.xml b/core/res/res/values/public-staging.xml
index 9d5a2bc..9cbf3b6 100644
--- a/core/res/res/values/public-staging.xml
+++ b/core/res/res/values/public-staging.xml
@@ -283,6 +283,8 @@
<public name="system_tertiary_fixed_dim" />
<public name="system_on_tertiary_fixed" />
<public name="system_on_tertiary_fixed_variant" />
+ <public name="system_outline_variant_light" />
+ <public name="system_outline_variant_dark" />
</staging-public-group>
<staging-public-group type="array" first-id="0x01c80000">
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index d8e69d7..6afdae5 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -6267,6 +6267,12 @@
<string name="concurrent_display_notification_thermal_title">Device is too warm</string>
<!-- Content of concurrent display thermal notification. [CHAR LIMIT=NONE] -->
<string name="concurrent_display_notification_thermal_content">Dual Screen is unavailable because your phone is getting too warm</string>
+ <!-- Title of concurrent display power saver notification. [CHAR LIMIT=NONE] -->
+ <string name="concurrent_display_notification_power_save_title">Dual Screen is unavailable</string>
+ <!-- Content of concurrent display power saver notification. [CHAR LIMIT=NONE] -->
+ <string name="concurrent_display_notification_power_save_content">Dual Screen is unavailable because Battery Saver is on. You can turn this off in Settings.</string>
+ <!-- Text of power saver notification settings button. [CHAR LIMIT=NONE] -->
+ <string name="device_state_notification_settings_button">Go to Settings</string>
<!-- Text of device state notification turn off button. [CHAR LIMIT=NONE] -->
<string name="device_state_notification_turn_off_button">Turn off</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index a001a71..b6b2ce2 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -362,6 +362,7 @@
<java-symbol type="bool" name="config_disableUsbPermissionDialogs"/>
<java-symbol type="dimen" name="config_highResTaskSnapshotScale" />
<java-symbol type="dimen" name="config_lowResTaskSnapshotScale" />
+ <java-symbol type="dimen" name="config_resActivitySnapshotScale" />
<java-symbol type="dimen" name="config_qsTileStrokeWidthInactive" />
<java-symbol type="dimen" name="config_qsTileStrokeWidthActive" />
<java-symbol type="bool" name="config_use16BitTaskSnapshotPixelFormat" />
@@ -4931,12 +4932,17 @@
<java-symbol type="array" name="device_state_notification_active_contents"/>
<java-symbol type="array" name="device_state_notification_thermal_titles"/>
<java-symbol type="array" name="device_state_notification_thermal_contents"/>
+ <java-symbol type="array" name="device_state_notification_power_save_titles"/>
+ <java-symbol type="array" name="device_state_notification_power_save_contents"/>
<java-symbol type="string" name="concurrent_display_notification_name"/>
<java-symbol type="string" name="concurrent_display_notification_active_title"/>
<java-symbol type="string" name="concurrent_display_notification_active_content"/>
<java-symbol type="string" name="concurrent_display_notification_thermal_title"/>
<java-symbol type="string" name="concurrent_display_notification_thermal_content"/>
+ <java-symbol type="string" name="concurrent_display_notification_power_save_title"/>
+ <java-symbol type="string" name="concurrent_display_notification_power_save_content"/>
<java-symbol type="string" name="device_state_notification_turn_off_button"/>
+ <java-symbol type="string" name="device_state_notification_settings_button"/>
<java-symbol type="bool" name="config_independentLockscreenLiveWallpaper"/>
<java-symbol type="integer" name="config_deviceStateConcurrentRearDisplay" />
<java-symbol type="string" name="config_rearDisplayPhysicalAddress" />
@@ -5020,6 +5026,7 @@
<java-symbol name="materialColorSurfaceContainerHighest" type="attr"/>
<java-symbol name="materialColorOnSurfaceVariant" type="attr"/>
<java-symbol name="materialColorOutline" type="attr"/>
+ <java-symbol name="materialColorOutlineVariant" type="attr"/>
<java-symbol name="materialColorOnPrimary" type="attr"/>
<java-symbol name="materialColorOnSurface" type="attr"/>
<java-symbol name="materialColorSurfaceContainer" type="attr"/>
diff --git a/core/res/res/values/themes_device_defaults.xml b/core/res/res/values/themes_device_defaults.xml
index 80df1f4..2e3d145 100644
--- a/core/res/res/values/themes_device_defaults.xml
+++ b/core/res/res/values/themes_device_defaults.xml
@@ -278,6 +278,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -372,6 +373,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -465,6 +467,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -560,6 +563,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -654,6 +658,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -756,6 +761,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -849,6 +855,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -941,6 +948,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1034,6 +1042,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1143,6 +1152,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1237,6 +1247,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1329,6 +1340,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1423,6 +1435,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1516,6 +1529,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1609,6 +1623,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1702,6 +1717,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1795,6 +1811,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1888,6 +1905,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -1986,6 +2004,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -2077,6 +2096,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -2306,6 +2326,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -2400,6 +2421,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -2493,6 +2515,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -2587,6 +2610,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -2683,6 +2707,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -2778,6 +2803,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -2879,6 +2905,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -2976,6 +3003,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3072,6 +3100,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3169,6 +3198,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3247,6 +3277,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3325,6 +3356,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3422,6 +3454,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3520,6 +3553,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3616,6 +3650,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3711,6 +3746,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3805,6 +3841,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3899,6 +3936,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -3991,6 +4029,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -4090,6 +4129,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -4169,6 +4209,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -4240,6 +4281,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -4333,6 +4375,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -4410,6 +4453,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -4527,6 +4571,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -4622,6 +4667,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -4743,6 +4789,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -4794,6 +4841,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -4850,6 +4898,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
@@ -4901,6 +4950,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_light</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_light</item>
<item name="materialColorOutline">@color/system_outline_light</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_light</item>
<item name="materialColorOnPrimary">@color/system_on_primary_light</item>
<item name="materialColorOnSurface">@color/system_on_surface_light</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_light</item>
@@ -4964,6 +5014,7 @@
<item name="materialColorSurfaceContainerHighest">@color/system_surface_container_highest_dark</item>
<item name="materialColorOnSurfaceVariant">@color/system_on_surface_variant_dark</item>
<item name="materialColorOutline">@color/system_outline_dark</item>
+ <item name="materialColorOutlineVariant">@color/system_outline_variant_dark</item>
<item name="materialColorOnPrimary">@color/system_on_primary_dark</item>
<item name="materialColorOnSurface">@color/system_on_surface_dark</item>
<item name="materialColorSurfaceContainer">@color/system_surface_container_dark</item>
diff --git a/core/tests/BroadcastRadioTests/AndroidManifest.xml b/core/tests/BroadcastRadioTests/AndroidManifest.xml
index 8f655ef..fef3d16 100644
--- a/core/tests/BroadcastRadioTests/AndroidManifest.xml
+++ b/core/tests/BroadcastRadioTests/AndroidManifest.xml
@@ -18,6 +18,8 @@
package="com.android.frameworks.broadcastradiotests">
<uses-permission android:name="android.permission.ACCESS_BROADCAST_RADIO" />
+ <uses-permission android:name="android.permission.LOG_COMPAT_CHANGE" />
+ <uses-permission android:name="android.permission.READ_COMPAT_CHANGE_CONFIG" />
<application android:debuggable="true">
<uses-library android:name="android.test.runner" />
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/ProgramListTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/ProgramListTest.java
index 75f8c95..7c3d2f2 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/ProgramListTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/ProgramListTest.java
@@ -580,7 +580,7 @@
doAnswer(invocation -> {
mTunerCallback = (ITunerCallback) invocation.getArguments()[3];
return mTunerMock;
- }).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any(), anyInt());
+ }).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any());
mRadioTuner = radioManager.openTuner(/* moduleId= */ 0, band,
/* withAudio= */ true, mTunerCallbackMock, /* handler= */ null);
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioManagerTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioManagerTest.java
index ce3e019..b9f4c3f 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioManagerTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/RadioManagerTest.java
@@ -30,7 +30,6 @@
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
-import android.os.Build;
import android.os.Parcel;
import android.os.RemoteException;
import android.util.ArrayMap;
@@ -50,8 +49,6 @@
@RunWith(MockitoJUnitRunner.class)
public final class RadioManagerTest {
- private static final int TEST_TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
-
private static final int REGION = RadioManager.REGION_ITU_2;
private static final int FM_LOWER_LIMIT = 87500;
private static final int FM_UPPER_LIMIT = 108000;
@@ -1043,14 +1040,13 @@
mRadioManager.openTuner(moduleId, FM_BAND_CONFIG, withAudio, mCallbackMock,
/* handler= */ null);
- verify(mRadioServiceMock).openTuner(eq(moduleId), eq(FM_BAND_CONFIG), eq(withAudio), any(),
- anyInt());
+ verify(mRadioServiceMock).openTuner(eq(moduleId), eq(FM_BAND_CONFIG), eq(withAudio), any());
}
@Test
public void openTuner_whenServiceDied_returnsNull() throws Exception {
createRadioManager();
- when(mRadioServiceMock.openTuner(anyInt(), any(), anyBoolean(), any(), anyInt()))
+ when(mRadioServiceMock.openTuner(anyInt(), any(), anyBoolean(), any()))
.thenThrow(new RemoteException());
RadioTuner nullTuner = mRadioManager.openTuner(/* moduleId= */ 0, FM_BAND_CONFIG,
@@ -1166,7 +1162,6 @@
}
private void createRadioManager() throws RemoteException {
- mApplicationInfo.targetSdkVersion = TEST_TARGET_SDK_VERSION;
when(mContextMock.getApplicationInfo()).thenReturn(mApplicationInfo);
when(mRadioServiceMock.listModules()).thenReturn(Arrays.asList(AMFM_PROPERTIES));
when(mRadioServiceMock.addAnnouncementListener(any(), any())).thenReturn(mCloseHandleMock);
diff --git a/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java b/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java
index 8b257e8..c7b82b1 100644
--- a/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java
+++ b/core/tests/BroadcastRadioTests/src/android/hardware/radio/TunerAdapterTest.java
@@ -86,7 +86,7 @@
doAnswer(invocation -> {
mTunerCallback = (ITunerCallback) invocation.getArguments()[3];
return mTunerMock;
- }).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any(), anyInt());
+ }).when(mRadioServiceMock).openTuner(anyInt(), any(), anyBoolean(), any());
doAnswer(invocation -> {
ProgramSelector program = (ProgramSelector) invocation.getArguments()[0];
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/IRadioServiceAidlImplTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/IRadioServiceAidlImplTest.java
index 16c1499..da51ba4 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/IRadioServiceAidlImplTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/IRadioServiceAidlImplTest.java
@@ -24,7 +24,6 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
-import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doNothing;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -35,7 +34,6 @@
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
-import android.os.Build;
import android.os.IBinder;
import android.os.ServiceManager;
@@ -58,7 +56,6 @@
"android.hardware.broadcastradio.IBroadcastRadio/amfm";
private static final String DAB_SERVICE_NAME =
"android.hardware.broadcastradio.IBroadcastRadio/dab";
- private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
private IRadioServiceAidlImpl mAidlImpl;
@@ -86,7 +83,7 @@
doNothing().when(mServiceMock).enforcePolicyAccess();
when(mHalMock.listModules()).thenReturn(List.of(mModuleMock));
- when(mHalMock.openSession(anyInt(), any(), anyBoolean(), any(), eq(TARGET_SDK_VERSION)))
+ when(mHalMock.openSession(anyInt(), any(), anyBoolean(), any()))
.thenReturn(mTunerMock);
when(mHalMock.addAnnouncementListener(any(), any())).thenReturn(mICloseHandle);
@@ -118,7 +115,7 @@
@Test
public void openTuner_forAidlImpl() throws Exception {
ITuner tuner = mAidlImpl.openTuner(/* moduleId= */ 0, mBandConfigMock,
- /* withAudio= */ true, mTunerCallbackMock, TARGET_SDK_VERSION);
+ /* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Tuner opened in AIDL HAL")
.that(tuner).isEqualTo(mTunerMock);
@@ -128,7 +125,7 @@
public void openTuner_withNullCallbackForAidlImpl_fails() throws Exception {
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
() -> mAidlImpl.openTuner(/* moduleId= */ 0, mBandConfigMock,
- /* withAudio= */ true, /* callback= */ null, TARGET_SDK_VERSION));
+ /* withAudio= */ true, /* callback= */ null));
assertWithMessage("Exception for opening tuner with null callback")
.that(thrown).hasMessageThat().contains("Callback must not be null");
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/IRadioServiceHidlImplTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/IRadioServiceHidlImplTest.java
index 164c9af..20bc8d4 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/IRadioServiceHidlImplTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/IRadioServiceHidlImplTest.java
@@ -33,7 +33,6 @@
import android.hardware.radio.ITuner;
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
-import android.os.Build;
import org.junit.Before;
import org.junit.Test;
@@ -51,7 +50,6 @@
private static final int HAL1_MODULE_ID = 0;
private static final int[] ENABLE_TYPES = new int[]{Announcement.TYPE_TRAFFIC};
- private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
private IRadioServiceHidlImpl mHidlImpl;
@@ -106,7 +104,7 @@
@Test
public void openTuner_withHal1ModuleId_forHidlImpl() throws Exception {
ITuner tuner = mHidlImpl.openTuner(HAL1_MODULE_ID, mBandConfigMock,
- /* withAudio= */ true, mTunerCallbackMock, TARGET_SDK_VERSION);
+ /* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Tuner opened in HAL 1")
.that(tuner).isEqualTo(mHal1TunerMock);
@@ -115,7 +113,7 @@
@Test
public void openTuner_withHal2ModuleId_forHidlImpl() throws Exception {
ITuner tuner = mHidlImpl.openTuner(HAL1_MODULE_ID + 1, mBandConfigMock,
- /* withAudio= */ true, mTunerCallbackMock, TARGET_SDK_VERSION);
+ /* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Tuner opened in HAL 2")
.that(tuner).isEqualTo(mHal2TunerMock);
@@ -125,7 +123,7 @@
public void openTuner_withNullCallbackForHidlImpl_fails() throws Exception {
NullPointerException thrown = assertThrows(NullPointerException.class,
() -> mHidlImpl.openTuner(/* moduleId= */ 0, mBandConfigMock,
- /* withAudio= */ true, /* callback= */ null, TARGET_SDK_VERSION));
+ /* withAudio= */ true, /* callback= */ null));
assertWithMessage("Exception for opening tuner with null callback")
.that(thrown).hasMessageThat().contains("Callback must not be null");
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java
index 161ac2d..3e9e992 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/RadioServiceUserControllerTest.java
@@ -24,6 +24,7 @@
import static org.mockito.Mockito.when;
import android.app.ActivityManager;
+import android.app.compat.CompatChanges;
import android.os.Binder;
import android.os.UserHandle;
@@ -46,8 +47,8 @@
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
- builder.spyStatic(ActivityManager.class)
- .spyStatic(Binder.class);
+ builder.spyStatic(ActivityManager.class).spyStatic(Binder.class)
+ .spyStatic(CompatChanges.class);
}
@Before
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java
index 98103f6..22f3bd4 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImplTest.java
@@ -36,7 +36,6 @@
import android.hardware.radio.ITunerCallback;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
-import android.os.Build;
import android.os.IBinder;
import android.os.IServiceCallback;
import android.os.RemoteException;
@@ -55,8 +54,6 @@
public final class BroadcastRadioServiceImplTest extends ExtendedRadioMockitoTestCase {
- private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
-
private static final int FM_RADIO_MODULE_ID = 0;
private static final int DAB_RADIO_MODULE_ID = 1;
private static final ArrayList<String> SERVICE_LIST =
@@ -140,8 +137,7 @@
createBroadcastRadioService();
ITuner session = mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID,
- /* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock,
- TARGET_SDK_VERSION);
+ /* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Session opened in FM radio module")
.that(session).isEqualTo(mFmTunerSessionMock);
@@ -152,8 +148,7 @@
createBroadcastRadioService();
ITuner session = mBroadcastRadioService.openSession(DAB_RADIO_MODULE_ID + 1,
- /* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock,
- TARGET_SDK_VERSION);
+ /* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock);
assertWithMessage("Session opened with id not found").that(session).isNull();
}
@@ -165,8 +160,7 @@
IllegalStateException thrown = assertThrows(IllegalStateException.class,
() -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID,
- /* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock,
- TARGET_SDK_VERSION));
+ /* legacyConfig= */ null, /* withAudio= */ true, mTunerCallbackMock));
assertWithMessage("Exception for opening session by non-current user")
.that(thrown).hasMessageThat().contains("Cannot open session for non-current user");
@@ -178,8 +172,7 @@
IllegalArgumentException thrown = assertThrows(IllegalArgumentException.class,
() -> mBroadcastRadioService.openSession(FM_RADIO_MODULE_ID,
- /* legacyConfig= */ null, /* withAudio= */ false, mTunerCallbackMock,
- TARGET_SDK_VERSION));
+ /* legacyConfig= */ null, /* withAudio= */ false, mTunerCallbackMock));
assertWithMessage("Exception for opening session without audio")
.that(thrown).hasMessageThat().contains("not supported");
@@ -247,7 +240,6 @@
return null;
}).when(mFmBinderMock).linkToDeath(any(), anyInt());
- when(mFmRadioModuleMock.openSession(eq(mTunerCallbackMock), eq(TARGET_SDK_VERSION)))
- .thenReturn(mFmTunerSessionMock);
+ when(mFmRadioModuleMock.openSession(mTunerCallbackMock)).thenReturn(mFmTunerSessionMock);
}
}
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
index 5d0e076..ba05791 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/ConversionUtilsTest.java
@@ -16,6 +16,9 @@
package com.android.server.broadcastradio.aidl;
+import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
+
+import android.app.compat.CompatChanges;
import android.hardware.broadcastradio.AmFmBandRange;
import android.hardware.broadcastradio.AmFmRegionConfig;
import android.hardware.broadcastradio.DabTableEntry;
@@ -29,17 +32,23 @@
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
-import android.os.Build;
+
+import com.android.dx.mockito.inline.extended.StaticMockitoSessionBuilder;
+import com.android.server.broadcastradio.ExtendedRadioMockitoTestCase;
import com.google.common.truth.Expect;
+import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
import java.util.Map;
import java.util.Set;
-public final class ConversionUtilsTest {
+public final class ConversionUtilsTest extends ExtendedRadioMockitoTestCase {
+
+ private static final int U_APP_UID = 1001;
+ private static final int T_APP_UID = 1002;
private static final int FM_LOWER_LIMIT = 87_500;
private static final int FM_UPPER_LIMIT = 108_000;
@@ -118,16 +127,29 @@
@Rule
public final Expect expect = Expect.create();
+ @Override
+ protected void initializeSession(StaticMockitoSessionBuilder builder) {
+ builder.spyStatic(CompatChanges.class);
+ }
+
+ @Before
+ public void setUp() {
+ doReturn(true).when(() -> CompatChanges.isChangeEnabled(
+ ConversionUtils.RADIO_U_VERSION_REQUIRED, U_APP_UID));
+ doReturn(false).when(() -> CompatChanges.isChangeEnabled(
+ ConversionUtils.RADIO_U_VERSION_REQUIRED, T_APP_UID));
+ }
+
@Test
public void isAtLeastU_withTSdkVersion_returnsFalse() {
expect.withMessage("Target SDK version of T")
- .that(ConversionUtils.isAtLeastU(Build.VERSION_CODES.TIRAMISU)).isFalse();
+ .that(ConversionUtils.isAtLeastU(T_APP_UID)).isFalse();
}
@Test
public void isAtLeastU_withCurrentSdkVersion_returnsTrue() {
expect.withMessage("Target SDK version of U")
- .that(ConversionUtils.isAtLeastU(Build.VERSION_CODES.CUR_DEVELOPMENT)).isTrue();
+ .that(ConversionUtils.isAtLeastU(U_APP_UID)).isTrue();
}
@Test
@@ -372,14 +394,14 @@
public void programSelectorMeetsSdkVersionRequirement_withLowerVersionId_returnsFalse() {
expect.withMessage("Selector %s without required SDK version", TEST_DAB_SELECTOR)
.that(ConversionUtils.programSelectorMeetsSdkVersionRequirement(TEST_DAB_SELECTOR,
- Build.VERSION_CODES.TIRAMISU)).isFalse();
+ T_APP_UID)).isFalse();
}
@Test
public void programSelectorMeetsSdkVersionRequirement_withRequiredVersionId_returnsTrue() {
expect.withMessage("Selector %s with required SDK version", TEST_FM_SELECTOR)
.that(ConversionUtils.programSelectorMeetsSdkVersionRequirement(TEST_FM_SELECTOR,
- Build.VERSION_CODES.TIRAMISU)).isTrue();
+ T_APP_UID)).isTrue();
}
@Test
@@ -389,7 +411,7 @@
expect.withMessage("Program info %s without required SDK version", dabProgramInfo)
.that(ConversionUtils.programInfoMeetsSdkVersionRequirement(dabProgramInfo,
- Build.VERSION_CODES.TIRAMISU)).isFalse();
+ T_APP_UID)).isFalse();
}
@Test
@@ -399,7 +421,7 @@
expect.withMessage("Program info %s with required SDK version", fmProgramInfo)
.that(ConversionUtils.programInfoMeetsSdkVersionRequirement(fmProgramInfo,
- Build.VERSION_CODES.TIRAMISU)).isTrue();
+ T_APP_UID)).isTrue();
}
@Test
@@ -413,7 +435,7 @@
Set.of(TEST_DAB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID));
ProgramList.Chunk convertedChunk = ConversionUtils.convertChunkToTargetSdkVersion(chunk,
- Build.VERSION_CODES.TIRAMISU);
+ T_APP_UID);
expect.withMessage(
"Purged state of the converted program list chunk with lower SDK version")
@@ -441,7 +463,7 @@
Set.of(TEST_DAB_SID_EXT_ID, TEST_DAB_ENSEMBLE_ID, TEST_VENDOR_ID));
ProgramList.Chunk convertedChunk = ConversionUtils.convertChunkToTargetSdkVersion(chunk,
- Build.VERSION_CODES.CUR_DEVELOPMENT);
+ U_APP_UID);
expect.withMessage("Converted program list chunk with required SDK version")
.that(convertedChunk).isEqualTo(chunk);
diff --git a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
index 464ecb2..78b5a4a 100644
--- a/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
+++ b/core/tests/BroadcastRadioTests/src/com/android/server/broadcastradio/aidl/TunerSessionTest.java
@@ -33,6 +33,7 @@
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.compat.CompatChanges;
import android.graphics.Bitmap;
import android.hardware.broadcastradio.IBroadcastRadio;
import android.hardware.broadcastradio.ITunerCallback;
@@ -46,7 +47,6 @@
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
import android.hardware.radio.RadioTuner;
-import android.os.Build;
import android.os.ParcelableException;
import android.os.RemoteException;
import android.os.ServiceSpecificException;
@@ -73,7 +73,6 @@
*/
public final class TunerSessionTest extends ExtendedRadioMockitoTestCase {
- private static final int TARGET_SDK_VERSION = Build.VERSION_CODES.CUR_DEVELOPMENT;
private static final VerificationWithTimeout CALLBACK_TIMEOUT =
timeout(/* millis= */ 200);
private static final int SIGNAL_QUALITY = 90;
@@ -125,11 +124,13 @@
@Override
protected void initializeSession(StaticMockitoSessionBuilder builder) {
- builder.spyStatic(RadioServiceUserController.class);
+ builder.spyStatic(RadioServiceUserController.class).spyStatic(CompatChanges.class);
}
@Before
public void setup() throws Exception {
+ doReturn(true).when(() -> CompatChanges.isChangeEnabled(
+ eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt()));
doReturn(true).when(() -> RadioServiceUserController.isCurrentOrSystemUser());
mRadioModule = new RadioModule(mBroadcastRadioMock,
@@ -341,7 +342,9 @@
@Test
public void tune_withLowerSdkVersion() throws Exception {
- openAidlClients(/* numClients= */ 1, Build.VERSION_CODES.TIRAMISU);
+ doReturn(false).when(() -> CompatChanges.isChangeEnabled(
+ eq(ConversionUtils.RADIO_U_VERSION_REQUIRED), anyInt()));
+ openAidlClients(/* numClients= */ 1);
ProgramSelector initialSel = AidlTestUtils.makeFmSelector(AM_FM_FREQUENCY_LIST[1]);
RadioManager.ProgramInfo tuneInfo =
AidlTestUtils.makeProgramInfo(initialSel, SIGNAL_QUALITY);
@@ -1175,17 +1178,13 @@
.onParametersUpdated(parametersExpected);
}
}
- private void openAidlClients(int numClients) throws Exception {
- openAidlClients(numClients, TARGET_SDK_VERSION);
- }
- private void openAidlClients(int numClients, int targetSdkVersion) throws Exception {
+ private void openAidlClients(int numClients) throws Exception {
mAidlTunerCallbackMocks = new android.hardware.radio.ITunerCallback[numClients];
mTunerSessions = new TunerSession[numClients];
for (int index = 0; index < numClients; index++) {
mAidlTunerCallbackMocks[index] = mock(android.hardware.radio.ITunerCallback.class);
- mTunerSessions[index] = mRadioModule.openSession(mAidlTunerCallbackMocks[index],
- targetSdkVersion);
+ mTunerSessions[index] = mRadioModule.openSession(mAidlTunerCallbackMocks[index]);
}
}
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index e811bb6..3ea1592 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -20,6 +20,7 @@
"BinderProxyCountingTestService/src/**/*.java",
"BinderDeathRecipientHelperApp/src/**/*.java",
"aidl/**/I*.aidl",
+ ":FrameworksCoreTestDoubles-sources",
],
aidl: {
diff --git a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
index 7a1de0c..a753870 100644
--- a/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
+++ b/core/tests/coretests/src/android/animation/AnimatorSetActivityTest.java
@@ -435,9 +435,11 @@
mActivityRule.runOnUiThread(s::start);
while (!listener.endIsCalled) {
- boolean passedStartDelay = a1.isStarted() || a2.isStarted() || a3.isStarted() ||
- a4.isStarted() || a5.isStarted();
- assertEquals(passedStartDelay, s.isRunning());
+ mActivityRule.runOnUiThread(() -> {
+ boolean passedStartDelay = a1.isStarted() || a2.isStarted() || a3.isStarted()
+ || a4.isStarted() || a5.isStarted();
+ assertEquals(passedStartDelay, s.isRunning());
+ });
Thread.sleep(50);
}
assertFalse(s.isRunning());
diff --git a/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java b/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java
index 22da0aa..43266a5 100644
--- a/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java
+++ b/core/tests/coretests/src/android/animation/AnimatorSetCallsTest.java
@@ -17,6 +17,7 @@
package android.animation;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
import android.util.PollingCheck;
import android.view.View;
@@ -31,6 +32,8 @@
import org.junit.Test;
import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
@MediumTest
public class AnimatorSetCallsTest {
@@ -40,6 +43,7 @@
private AnimatorSetActivity mActivity;
private AnimatorSet mSet1;
+ private AnimatorSet mSet2;
private ObjectAnimator mAnimator;
private CountListener mListener1;
private CountListener mListener2;
@@ -56,10 +60,10 @@
mSet1.addListener(mListener1);
mSet1.addPauseListener(mListener1);
- AnimatorSet set2 = new AnimatorSet();
+ mSet2 = new AnimatorSet();
mListener2 = new CountListener();
- set2.addListener(mListener2);
- set2.addPauseListener(mListener2);
+ mSet2.addListener(mListener2);
+ mSet2.addPauseListener(mListener2);
mAnimator = ObjectAnimator.ofFloat(square, "translationX", 0f, 100f);
mListener3 = new CountListener();
@@ -67,8 +71,8 @@
mAnimator.addPauseListener(mListener3);
mAnimator.setDuration(1);
- set2.play(mAnimator);
- mSet1.play(set2);
+ mSet2.play(mAnimator);
+ mSet1.play(mSet2);
});
}
@@ -175,6 +179,7 @@
assertEquals(1, updateValues.size());
assertEquals(0f, updateValues.get(0), 0f);
}
+
@Test
public void updateOnlyWhileRunning() {
ArrayList<Float> updateValues = new ArrayList<>();
@@ -207,6 +212,226 @@
}
}
+ @Test
+ public void pauseResumeSeekingAnimators() {
+ ValueAnimator animator2 = ValueAnimator.ofFloat(0f, 1f);
+ mSet2.play(animator2).after(mAnimator);
+ mSet2.setStartDelay(100);
+ mSet1.setStartDelay(100);
+ mAnimator.setDuration(100);
+
+ mActivity.runOnUiThread(() -> {
+ mSet1.setCurrentPlayTime(0);
+ mSet1.pause();
+
+ // only startForward and pause should have been called once
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 0
+ );
+ mListener2.assertValues(
+ 0, 0, 0, 0, 0, 0, 0, 0
+ );
+ mListener3.assertValues(
+ 0, 0, 0, 0, 0, 0, 0, 0
+ );
+
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 1
+ );
+ mListener2.assertValues(
+ 0, 0, 0, 0, 0, 0, 0, 0
+ );
+ mListener3.assertValues(
+ 0, 0, 0, 0, 0, 0, 0, 0
+ );
+
+ mSet1.setCurrentPlayTime(200);
+
+ // resume and endForward should have been called once
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 1
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 0, 0
+ );
+ mListener3.assertValues(
+ 1, 0, 0, 0, 0, 0, 0, 0
+ );
+
+ mSet1.pause();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 2, 1
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 0
+ );
+ mListener3.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 0
+ );
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 2, 2
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 1
+ );
+ mListener3.assertValues(
+ 1, 0, 0, 0, 0, 0, 1, 1
+ );
+
+ // now go to animator2
+ mSet1.setCurrentPlayTime(400);
+ mSet1.pause();
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 3, 3
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 2, 2
+ );
+ mListener3.assertValues(
+ 1, 0, 1, 0, 0, 0, 1, 1
+ );
+
+ // now go back to mAnimator
+ mSet1.setCurrentPlayTime(250);
+ mSet1.pause();
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 4, 4
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 0, 0, 0, 3, 3
+ );
+ mListener3.assertValues(
+ 1, 1, 1, 0, 0, 0, 2, 2
+ );
+
+ // now go back to before mSet2 was being run
+ mSet1.setCurrentPlayTime(1);
+ mSet1.pause();
+ mSet1.resume();
+ mListener1.assertValues(
+ 1, 0, 0, 0, 0, 0, 5, 5
+ );
+ mListener2.assertValues(
+ 1, 0, 0, 1, 0, 0, 3, 3
+ );
+ mListener3.assertValues(
+ 1, 1, 1, 1, 0, 0, 2, 2
+ );
+ });
+ }
+
+ @Test
+ public void endInCancel() throws Throwable {
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationCancel(Animator animation) {
+ mSet1.end();
+ }
+ };
+ mSet1.addListener(listener);
+ mActivity.runOnUiThread(() -> {
+ mSet1.start();
+ mSet1.cancel();
+ // Should go to the end value
+ View square = mActivity.findViewById(R.id.square1);
+ assertEquals(100f, square.getTranslationX(), 0.001f);
+ });
+ }
+
+ @Test
+ public void reentrantStart() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(3);
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation, boolean isReverse) {
+ mSet1.start();
+ latch.countDown();
+ }
+ };
+ mSet1.addListener(listener);
+ mSet2.addListener(listener);
+ mAnimator.addListener(listener);
+ mActivity.runOnUiThread(() -> mSet1.start());
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread hasn't been destroyed by a stack overflow...
+ mActivity.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantEnd() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(3);
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationEnd(Animator animation, boolean isReverse) {
+ mSet1.end();
+ latch.countDown();
+ }
+ };
+ mSet1.addListener(listener);
+ mSet2.addListener(listener);
+ mAnimator.addListener(listener);
+ mActivity.runOnUiThread(() -> {
+ mSet1.start();
+ mSet1.end();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread hasn't been destroyed by a stack overflow...
+ mActivity.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantPause() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(3);
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationPause(Animator animation) {
+ mSet1.pause();
+ latch.countDown();
+ }
+ };
+ mSet1.addPauseListener(listener);
+ mSet2.addPauseListener(listener);
+ mAnimator.addPauseListener(listener);
+ mActivity.runOnUiThread(() -> {
+ mSet1.start();
+ mSet1.pause();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread hasn't been destroyed by a stack overflow...
+ mActivity.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantResume() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(3);
+ AnimatorListenerAdapter listener = new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationResume(Animator animation) {
+ mSet1.resume();
+ latch.countDown();
+ }
+ };
+ mSet1.addPauseListener(listener);
+ mSet2.addPauseListener(listener);
+ mAnimator.addPauseListener(listener);
+ mActivity.runOnUiThread(() -> {
+ mSet1.start();
+ mSet1.pause();
+ mSet1.resume();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread hasn't been destroyed by a stack overflow...
+ mActivity.runOnUiThread(() -> {});
+ }
+
private void waitForOnUiThread(PollingCheck.PollingCheckCondition condition) {
final boolean[] value = new boolean[1];
PollingCheck.waitFor(() -> {
@@ -238,16 +463,16 @@
int pause,
int resume
) {
- assertEquals(0, startNoParam);
- assertEquals(0, endNoParam);
- assertEquals(startForward, this.startForward);
- assertEquals(startReverse, this.startReverse);
- assertEquals(endForward, this.endForward);
- assertEquals(endReverse, this.endReverse);
- assertEquals(cancel, this.cancel);
- assertEquals(repeat, this.repeat);
- assertEquals(pause, this.pause);
- assertEquals(resume, this.resume);
+ assertEquals("onAnimationStart() without direction", 0, startNoParam);
+ assertEquals("onAnimationEnd() without direction", 0, endNoParam);
+ assertEquals("onAnimationStart(forward)", startForward, this.startForward);
+ assertEquals("onAnimationStart(reverse)", startReverse, this.startReverse);
+ assertEquals("onAnimationEnd(forward)", endForward, this.endForward);
+ assertEquals("onAnimationEnd(reverse)", endReverse, this.endReverse);
+ assertEquals("onAnimationCancel()", cancel, this.cancel);
+ assertEquals("onAnimationRepeat()", repeat, this.repeat);
+ assertEquals("onAnimationPause()", pause, this.pause);
+ assertEquals("onAnimationResume()", resume, this.resume);
}
@Override
diff --git a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
index dee0a3e..a53d57f 100644
--- a/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
+++ b/core/tests/coretests/src/android/animation/ValueAnimatorTests.java
@@ -40,6 +40,8 @@
import org.junit.runner.RunWith;
import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
@RunWith(AndroidJUnit4.class)
@MediumTest
@@ -1067,6 +1069,64 @@
});
}
+ @Test
+ public void reentrantStart() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(1);
+ a1.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation, boolean isReverse) {
+ a1.start();
+ latch.countDown();
+ }
+ });
+ mActivityRule.runOnUiThread(() -> a1.start());
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread isn't blocked by an infinite loop:
+ mActivityRule.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantPause() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(1);
+ a1.addPauseListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationPause(Animator animation) {
+ a1.pause();
+ latch.countDown();
+ }
+ });
+ mActivityRule.runOnUiThread(() -> {
+ a1.start();
+ a1.pause();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread isn't blocked by an infinite loop:
+ mActivityRule.runOnUiThread(() -> {});
+ }
+
+ @Test
+ public void reentrantResume() throws Throwable {
+ CountDownLatch latch = new CountDownLatch(1);
+ a1.addPauseListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationResume(Animator animation) {
+ a1.resume();
+ latch.countDown();
+ }
+ });
+ mActivityRule.runOnUiThread(() -> {
+ a1.start();
+ a1.pause();
+ a1.resume();
+ });
+ assertTrue(latch.await(1, TimeUnit.SECONDS));
+
+ // Make sure that the UI thread isn't blocked by an infinite loop:
+ mActivityRule.runOnUiThread(() -> {});
+ }
+
class MyUpdateListener implements ValueAnimator.AnimatorUpdateListener {
boolean wasRunning = false;
long firstRunningFrameTime = -1;
diff --git a/core/tests/coretests/src/android/app/NotificationTest.java b/core/tests/coretests/src/android/app/NotificationTest.java
index 34d669b..6debbfe 100644
--- a/core/tests/coretests/src/android/app/NotificationTest.java
+++ b/core/tests/coretests/src/android/app/NotificationTest.java
@@ -63,7 +63,6 @@
import static org.mockito.Mockito.when;
import android.annotation.Nullable;
-import android.app.Notification.CallStyle;
import android.content.Context;
import android.content.Intent;
import android.content.LocusId;
@@ -1039,6 +1038,69 @@
}
@Test
+ public void areIconsDifferent_sameSmallIcon_false() {
+ Notification n1 = new Notification.Builder(mContext, "test").setSmallIcon(1).build();
+ Notification n2 = new Notification.Builder(mContext, "test").setSmallIcon(1).build();
+
+ assertThat(Notification.areIconsDifferent(n1, n2)).isFalse();
+ }
+
+ @Test
+ public void areIconsDifferent_differentSmallIcon_true() {
+ Notification n1 = new Notification.Builder(mContext, "test").setSmallIcon(1).build();
+ Notification n2 = new Notification.Builder(mContext, "test").setSmallIcon(2).build();
+
+ assertThat(Notification.areIconsDifferent(n1, n2)).isTrue();
+ }
+
+ @Test
+ public void areIconsDifferent_sameLargeIcon_false() {
+ Icon icon1 = Icon.createWithContentUri("uri");
+ Icon icon2 = Icon.createWithContentUri("uri");
+ Notification n1 = new Notification.Builder(mContext, "test")
+ .setSmallIcon(1).setLargeIcon(icon1).build();
+ Notification n2 = new Notification.Builder(mContext, "test")
+ .setSmallIcon(1).setLargeIcon(icon2).build();
+
+ // Note that this will almost certainly not happen for Icons created from Bitmaps, since
+ // their serialization/deserialization of Bitmaps (app -> system_process) results in a
+ // different getGenerationId() value. :(
+ assertThat(Notification.areIconsDifferent(n1, n2)).isFalse();
+ }
+
+ @Test
+ public void areIconsDifferent_differentLargeIcon_true() {
+ Icon icon1 = Icon.createWithContentUri("uri1");
+ Icon icon2 = Icon.createWithContentUri("uri2");
+ Notification n1 = new Notification.Builder(mContext, "test")
+ .setSmallIcon(1).setLargeIcon(icon1).build();
+ Notification n2 = new Notification.Builder(mContext, "test")
+ .setSmallIcon(2).setLargeIcon(icon2).build();
+
+ assertThat(Notification.areIconsDifferent(n1, n2)).isTrue();
+ }
+
+ @Test
+ public void areIconsDifferent_addedLargeIcon_true() {
+ Icon icon = Icon.createWithContentUri("uri");
+ Notification n1 = new Notification.Builder(mContext, "test").setSmallIcon(1).build();
+ Notification n2 = new Notification.Builder(mContext, "test")
+ .setSmallIcon(2).setLargeIcon(icon).build();
+
+ assertThat(Notification.areIconsDifferent(n1, n2)).isTrue();
+ }
+
+ @Test
+ public void areIconsDifferent_removedLargeIcon_true() {
+ Icon icon = Icon.createWithContentUri("uri");
+ Notification n1 = new Notification.Builder(mContext, "test")
+ .setSmallIcon(1).setLargeIcon(icon).build();
+ Notification n2 = new Notification.Builder(mContext, "test").setSmallIcon(2).build();
+
+ assertThat(Notification.areIconsDifferent(n1, n2)).isTrue();
+ }
+
+ @Test
public void testStyleChangeVisiblyDifferent_noStyles() {
Notification.Builder n1 = new Notification.Builder(mContext, "test");
Notification.Builder n2 = new Notification.Builder(mContext, "test");
diff --git a/core/tests/coretests/src/android/hardware/display/VirtualDisplayConfigTest.java b/core/tests/coretests/src/android/hardware/display/VirtualDisplayConfigTest.java
new file mode 100644
index 0000000..4e59064
--- /dev/null
+++ b/core/tests/coretests/src/android/hardware/display/VirtualDisplayConfigTest.java
@@ -0,0 +1,118 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.hardware.display;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.graphics.SurfaceTexture;
+import android.os.Binder;
+import android.os.IBinder;
+import android.os.Parcel;
+import android.util.DisplayMetrics;
+import android.view.ContentRecordingSession;
+import android.view.Surface;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.Set;
+
+/**
+ * Tests for non-public APIs in {@link VirtualDisplayConfig}.
+ * See also related CTS tests.
+ *
+ * Run with:
+ * atest FrameworksCoreTests:VirtualDisplayConfigTest
+ */
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class VirtualDisplayConfigTest {
+
+ private static final String NAME = "VirtualDisplayConfigTest";
+ private static final int WIDTH = 720;
+ private static final int HEIGHT = 480;
+ private static final int DENSITY = DisplayMetrics.DENSITY_MEDIUM;
+ private static final float REQUESTED_REFRESH_RATE = 30.0f;
+ private static final int FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC
+ | DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE;
+
+ // Values for hidden APIs.
+ private static final int DISPLAY_ID_TO_MIRROR = 10;
+ private static final IBinder WINDOW_TOKEN = new Binder("DisplayContentWindowToken");
+ private static final ContentRecordingSession CONTENT_RECORDING_SESSION =
+ ContentRecordingSession.createTaskSession(WINDOW_TOKEN);
+
+ private final Surface mSurface = new Surface(new SurfaceTexture(/*texName=*/1));
+
+ @Test
+ public void testParcelAndUnparcel_matches() {
+ final VirtualDisplayConfig originalConfig = buildGenericVirtualDisplay(NAME);
+
+ validateConstantFields(originalConfig);
+ assertThat(originalConfig.getName()).isEqualTo(NAME);
+
+
+ final Parcel parcel = Parcel.obtain();
+ originalConfig.writeToParcel(parcel, /* flags= */ 0);
+ parcel.setDataPosition(0);
+ final VirtualDisplayConfig recreatedConfig =
+ VirtualDisplayConfig.CREATOR.createFromParcel(parcel);
+
+ validateConstantFields(recreatedConfig);
+ assertThat(recreatedConfig.getName()).isEqualTo(NAME);
+ }
+
+ @Test
+ public void testEquals_matches() {
+ assertThat(buildGenericVirtualDisplay(NAME)).isEqualTo(buildGenericVirtualDisplay(NAME));
+ }
+
+ @Test
+ public void testEquals_different() {
+ assertThat(buildGenericVirtualDisplay(NAME + "2")).isNotEqualTo(
+ buildGenericVirtualDisplay(NAME));
+ }
+
+ private VirtualDisplayConfig buildGenericVirtualDisplay(String name) {
+ return new VirtualDisplayConfig.Builder(name, WIDTH, HEIGHT, DENSITY)
+ .setFlags(FLAGS)
+ .setSurface(mSurface)
+ .setDisplayCategories(Set.of("C1", "C2"))
+ .addDisplayCategory("C3")
+ .setRequestedRefreshRate(REQUESTED_REFRESH_RATE)
+ .setDisplayIdToMirror(DISPLAY_ID_TO_MIRROR)
+ .setWindowManagerMirroringEnabled(true)
+ .setContentRecordingSession(CONTENT_RECORDING_SESSION)
+ .build();
+ }
+
+ private void validateConstantFields(VirtualDisplayConfig config) {
+ assertThat(config.getWidth()).isEqualTo(WIDTH);
+ assertThat(config.getHeight()).isEqualTo(HEIGHT);
+ assertThat(config.getDensityDpi()).isEqualTo(DENSITY);
+ assertThat(config.getFlags()).isEqualTo(FLAGS);
+ assertThat(config.getSurface()).isNotNull();
+ assertThat(config.getDisplayCategories()).containsExactly("C1", "C2", "C3");
+ assertThat(config.getRequestedRefreshRate()).isEqualTo(REQUESTED_REFRESH_RATE);
+ assertThat(config.getDisplayIdToMirror()).isEqualTo(DISPLAY_ID_TO_MIRROR);
+ assertThat(config.isWindowManagerMirroringEnabled()).isTrue();
+ assertThat(config.getContentRecordingSession()).isEqualTo(CONTENT_RECORDING_SESSION);
+ }
+}
diff --git a/core/tests/coretests/src/android/hardware/face/FaceManagerTest.java b/core/tests/coretests/src/android/hardware/face/FaceManagerTest.java
index 9b1f0cd..9a202ae 100644
--- a/core/tests/coretests/src/android/hardware/face/FaceManagerTest.java
+++ b/core/tests/coretests/src/android/hardware/face/FaceManagerTest.java
@@ -112,7 +112,7 @@
mCaptor.getValue().onAllAuthenticatorsRegistered(mProps);
List<FaceSensorPropertiesInternal> actual = mFaceManager.getSensorPropertiesInternal();
- assertThat(actual).isEqualTo(mProps);
+ assertThat(actual).containsExactlyElementsIn(mProps);
verify(mService, never()).getSensorPropertiesInternal(any());
}
diff --git a/core/tests/coretests/src/android/hardware/fingerprint/FingerprintManagerTest.java b/core/tests/coretests/src/android/hardware/fingerprint/FingerprintManagerTest.java
index f31903a..5058065 100644
--- a/core/tests/coretests/src/android/hardware/fingerprint/FingerprintManagerTest.java
+++ b/core/tests/coretests/src/android/hardware/fingerprint/FingerprintManagerTest.java
@@ -113,7 +113,7 @@
List<FingerprintSensorPropertiesInternal> actual =
mFingerprintManager.getSensorPropertiesInternal();
- assertThat(actual).isEqualTo(mProps);
+ assertThat(actual).containsExactlyElementsIn(mProps);
verify(mService, never()).getSensorPropertiesInternal(any());
}
diff --git a/core/tests/coretests/src/android/provider/DeviceConfigTest.java b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
index aa1853f..1ea20f1 100644
--- a/core/tests/coretests/src/android/provider/DeviceConfigTest.java
+++ b/core/tests/coretests/src/android/provider/DeviceConfigTest.java
@@ -803,51 +803,51 @@
try {
// Ensure the device starts in a known state.
- DeviceConfig.setSyncDisabledMode(Settings.Config.SYNC_DISABLED_MODE_NONE);
+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_NONE);
// Assert starting state.
assertThat(DeviceConfig.getSyncDisabledMode())
- .isEqualTo(Settings.Config.SYNC_DISABLED_MODE_NONE);
+ .isEqualTo(DeviceConfig.SYNC_DISABLED_MODE_NONE);
assertThat(DeviceConfig.setProperties(properties1)).isTrue();
assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
.isEqualTo(VALUE);
// Test disabled (persistent). Persistence is not actually tested, that would require
// a host test.
- DeviceConfig.setSyncDisabledMode(Settings.Config.SYNC_DISABLED_MODE_PERSISTENT);
+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_PERSISTENT);
assertThat(DeviceConfig.getSyncDisabledMode())
- .isEqualTo(Settings.Config.SYNC_DISABLED_MODE_PERSISTENT);
+ .isEqualTo(DeviceConfig.SYNC_DISABLED_MODE_PERSISTENT);
assertThat(DeviceConfig.setProperties(properties2)).isFalse();
assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
.isEqualTo(VALUE);
// Return to not disabled.
- DeviceConfig.setSyncDisabledMode(Settings.Config.SYNC_DISABLED_MODE_NONE);
+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_NONE);
assertThat(DeviceConfig.getSyncDisabledMode())
- .isEqualTo(Settings.Config.SYNC_DISABLED_MODE_NONE);
+ .isEqualTo(DeviceConfig.SYNC_DISABLED_MODE_NONE);
assertThat(DeviceConfig.setProperties(properties2)).isTrue();
assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
.isEqualTo(VALUE2);
// Test disabled (persistent). Absence of persistence is not actually tested, that would
// require a host test.
- DeviceConfig.setSyncDisabledMode(Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT);
+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_UNTIL_REBOOT);
assertThat(DeviceConfig.getSyncDisabledMode())
- .isEqualTo(Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT);
+ .isEqualTo(DeviceConfig.SYNC_DISABLED_MODE_UNTIL_REBOOT);
assertThat(DeviceConfig.setProperties(properties1)).isFalse();
assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
.isEqualTo(VALUE2);
// Return to not disabled.
- DeviceConfig.setSyncDisabledMode(Settings.Config.SYNC_DISABLED_MODE_NONE);
+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_NONE);
assertThat(DeviceConfig.getSyncDisabledMode())
- .isEqualTo(Settings.Config.SYNC_DISABLED_MODE_NONE);
+ .isEqualTo(DeviceConfig.SYNC_DISABLED_MODE_NONE);
assertThat(DeviceConfig.setProperties(properties1)).isTrue();
assertThat(DeviceConfig.getProperties(NAMESPACE, KEY).getString(KEY, DEFAULT_VALUE))
.isEqualTo(VALUE);
} finally {
// Try to return to the default sync disabled state in case of failure.
- DeviceConfig.setSyncDisabledMode(Settings.Config.SYNC_DISABLED_MODE_NONE);
+ DeviceConfig.setSyncDisabledMode(DeviceConfig.SYNC_DISABLED_MODE_NONE);
// NAMESPACE will be cleared by cleanUp()
}
diff --git a/core/tests/coretests/src/android/view/inputmethod/DeleteRangeGestureTest.java b/core/tests/coretests/src/android/view/inputmethod/DeleteRangeGestureTest.java
new file mode 100644
index 0000000..d7b911d
--- /dev/null
+++ b/core/tests/coretests/src/android/view/inputmethod/DeleteRangeGestureTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.graphics.RectF;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.ApiTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@ApiTest(apis = {"android.view.inputmethod.DeleteRangeGesture.Builder#setGranularity",
+ "android.view.inputmethod.DeleteRangeGesture.Builder#setDeletionStartArea",
+ "android.view.inputmethod.DeleteRangeGesture.Builder#setDeletionEndArea",
+ "android.view.inputmethod.DeleteRangeGesture.Builder#setFallbackText",
+ "android.view.inputmethod.DeleteRangeGesture.Builder#build"})
+public class DeleteRangeGestureTest {
+ private static final RectF DELETION_START_RECTANGLE = new RectF(1, 2, 3, 4);
+ private static final RectF DELETION_END_RECTANGLE = new RectF(0, 2, 3, 4);
+ private static final String FALLBACK_TEXT = "fallback_test";
+
+ @Test
+ public void testBuilder() {
+ DeleteRangeGesture.Builder builder = new DeleteRangeGesture.Builder();
+ DeleteRangeGesture gesture = builder.setGranularity(HandwritingGesture.GRANULARITY_WORD)
+ .setDeletionStartArea(DELETION_START_RECTANGLE)
+ .setDeletionEndArea(DELETION_END_RECTANGLE)
+ .setFallbackText(FALLBACK_TEXT).build();
+ assertNotNull(gesture);
+ assertEquals(HandwritingGesture.GRANULARITY_WORD, gesture.getGranularity());
+ assertEquals(DELETION_START_RECTANGLE, gesture.getDeletionStartArea());
+ assertEquals(DELETION_END_RECTANGLE, gesture.getDeletionEndArea());
+ assertEquals(FALLBACK_TEXT, gesture.getFallbackText());
+ }
+}
diff --git a/core/tests/coretests/src/android/view/inputmethod/InsertGestureTest.java b/core/tests/coretests/src/android/view/inputmethod/InsertGestureTest.java
new file mode 100644
index 0000000..47a724d
--- /dev/null
+++ b/core/tests/coretests/src/android/view/inputmethod/InsertGestureTest.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.graphics.PointF;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.ApiTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@ApiTest(apis = {"android.view.inputmethod.InsertGesture.Builder#setInsertionPoint",
+ "android.view.inputmethod.InsertGesture.Builder#setTextToInsert",
+ "android.view.inputmethod.InsertGesture.Builder#setFallbackText",
+ "android.view.inputmethod.InsertGesture.Builder#build"})
+public class InsertGestureTest {
+ private static final PointF INSERTION_POINT = new PointF(1, 2);
+ private static final String FALLBACK_TEXT = "fallback_text";
+ private static final String TEXT_TO_INSERT = "text";
+
+ @Test
+ public void testBuilder() {
+ InsertGesture.Builder builder = new InsertGesture.Builder();
+ InsertGesture gesture = builder.setInsertionPoint(INSERTION_POINT)
+ .setTextToInsert(TEXT_TO_INSERT)
+ .setFallbackText(FALLBACK_TEXT).build();
+ assertNotNull(gesture);
+ assertEquals(INSERTION_POINT, gesture.getInsertionPoint());
+ assertEquals(FALLBACK_TEXT, gesture.getFallbackText());
+ assertEquals(TEXT_TO_INSERT, gesture.getTextToInsert());
+ }
+}
diff --git a/core/tests/coretests/src/android/view/inputmethod/InsertModeGestureTest.java b/core/tests/coretests/src/android/view/inputmethod/InsertModeGestureTest.java
new file mode 100644
index 0000000..11ddba1
--- /dev/null
+++ b/core/tests/coretests/src/android/view/inputmethod/InsertModeGestureTest.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.graphics.PointF;
+import android.os.CancellationSignal;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.ApiTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@ApiTest(apis = {"android.view.inputmethod.InsertModeGesture.Builder#setInsertionPoint",
+ "android.view.inputmethod.InsertModeGesture.Builder#setCancellationSignal",
+ "android.view.inputmethod.InsertModeGesture.Builder#setFallbackText",
+ "android.view.inputmethod.InsertModeGesture.Builder#build"})
+public class InsertModeGestureTest {
+ private static final PointF INSERTION_POINT = new PointF(1, 2);
+ private static final String FALLBACK_TEXT = "fallback_text";
+ private static final CancellationSignal CANCELLATION_SIGNAL = new CancellationSignal();
+
+ @Test
+ public void testBuilder() {
+ InsertModeGesture.Builder builder = new InsertModeGesture.Builder();
+ InsertModeGesture gesture = builder.setInsertionPoint(INSERTION_POINT)
+ .setCancellationSignal(CANCELLATION_SIGNAL)
+ .setFallbackText(FALLBACK_TEXT).build();
+ assertNotNull(gesture);
+ assertEquals(INSERTION_POINT, gesture.getInsertionPoint());
+ assertEquals(FALLBACK_TEXT, gesture.getFallbackText());
+ assertEquals(CANCELLATION_SIGNAL, gesture.getCancellationSignal());
+ }
+}
diff --git a/core/tests/coretests/src/android/view/inputmethod/SelectGestureTest.java b/core/tests/coretests/src/android/view/inputmethod/SelectGestureTest.java
new file mode 100644
index 0000000..b2eb07c
--- /dev/null
+++ b/core/tests/coretests/src/android/view/inputmethod/SelectGestureTest.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.graphics.RectF;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.ApiTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@ApiTest(apis = {"android.view.inputmethod.SelectGesture.Builder#setGranularity",
+ "android.view.inputmethod.SelectGesture.Builder#setSelectionArea",
+ "android.view.inputmethod.SelectGesture.Builder#setFallbackText",
+ "android.view.inputmethod.SelectGesture.Builder#build"})
+public class SelectGestureTest {
+ private static final RectF SELECTION_RECTANGLE = new RectF(1, 2, 3, 4);
+ private static final String FALLBACK_TEXT = "fallback_text";
+
+ @Test
+ public void testBuilder() {
+ SelectGesture.Builder builder = new SelectGesture.Builder();
+ SelectGesture gesture = builder.setGranularity(HandwritingGesture.GRANULARITY_WORD)
+ .setSelectionArea(SELECTION_RECTANGLE)
+ .setFallbackText(FALLBACK_TEXT).build();
+ assertNotNull(gesture);
+ assertEquals(HandwritingGesture.GRANULARITY_WORD, gesture.getGranularity());
+ assertEquals(SELECTION_RECTANGLE, gesture.getSelectionArea());
+ assertEquals(FALLBACK_TEXT, gesture.getFallbackText());
+ }
+}
diff --git a/core/tests/coretests/src/android/view/inputmethod/SelectRangeGestureTest.java b/core/tests/coretests/src/android/view/inputmethod/SelectRangeGestureTest.java
new file mode 100644
index 0000000..df63a4a
--- /dev/null
+++ b/core/tests/coretests/src/android/view/inputmethod/SelectRangeGestureTest.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.view.inputmethod;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
+
+import android.graphics.RectF;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+import androidx.test.runner.AndroidJUnit4;
+
+import com.android.compatibility.common.util.ApiTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+@Presubmit
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+@ApiTest(apis = {"android.view.inputmethod.SelectRangeGesture.Builder#setGranularity",
+ "android.view.inputmethod.SelectRangeGesture.Builder#setSelectionStartArea",
+ "android.view.inputmethod.SelectRangeGesture.Builder#setSelectionEndArea",
+ "android.view.inputmethod.SelectRangeGesture.Builder#setFallbackText",
+ "android.view.inputmethod.SelectRangeGesture.Builder#build"})
+public class SelectRangeGestureTest {
+ private static final RectF SELECTION_START_RECTANGLE = new RectF(1, 2, 3, 4);
+ private static final RectF SELECTION_END_RECTANGLE = new RectF(0, 2, 3, 4);
+ private static final String FALLBACK_TEXT = "fallback_text";
+
+ @Test
+ public void testBuilder() {
+ SelectRangeGesture.Builder builder = new SelectRangeGesture.Builder();
+ SelectRangeGesture gesture = builder.setGranularity(HandwritingGesture.GRANULARITY_WORD)
+ .setSelectionStartArea(SELECTION_START_RECTANGLE)
+ .setSelectionEndArea(SELECTION_END_RECTANGLE)
+ .setFallbackText(FALLBACK_TEXT).build();
+ assertNotNull(gesture);
+ assertEquals(HandwritingGesture.GRANULARITY_WORD, gesture.getGranularity());
+ assertEquals(SELECTION_START_RECTANGLE, gesture.getSelectionStartArea());
+ assertEquals(SELECTION_END_RECTANGLE, gesture.getSelectionEndArea());
+ assertEquals(FALLBACK_TEXT, gesture.getFallbackText());
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java
new file mode 100644
index 0000000..e6f10ad
--- /dev/null
+++ b/core/tests/coretests/src/com/android/internal/util/FakeLatencyTrackerTest.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import static com.android.internal.util.FrameworkStatsLog.UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_VOICE_INTERACTION;
+import static com.android.internal.util.FrameworkStatsLog.UI_ACTION_LATENCY_REPORTED;
+import static com.android.internal.util.LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import java.util.List;
+
+/**
+ * This test class verifies the additional methods which {@link FakeLatencyTracker} exposes.
+ *
+ * <p>The typical {@link LatencyTracker} behavior test coverage is present in
+ * {@link LatencyTrackerTest}
+ */
+@RunWith(AndroidJUnit4.class)
+public class FakeLatencyTrackerTest {
+
+ private FakeLatencyTracker mFakeLatencyTracker;
+
+ @Before
+ public void setUp() throws Exception {
+ mFakeLatencyTracker = FakeLatencyTracker.create();
+ }
+
+ @Test
+ public void testForceEnabled() throws Exception {
+ mFakeLatencyTracker.logAction(ACTION_SHOW_VOICE_INTERACTION, 1234);
+
+ assertThat(mFakeLatencyTracker.getEventsWrittenToFrameworkStats(
+ ACTION_SHOW_VOICE_INTERACTION)).isEmpty();
+
+ mFakeLatencyTracker.forceEnabled(ACTION_SHOW_VOICE_INTERACTION, 1000);
+ mFakeLatencyTracker.logAction(ACTION_SHOW_VOICE_INTERACTION, 1234);
+ List<LatencyTracker.FrameworkStatsLogEvent> events =
+ mFakeLatencyTracker.getEventsWrittenToFrameworkStats(
+ ACTION_SHOW_VOICE_INTERACTION);
+ assertThat(events).hasSize(1);
+ assertThat(events.get(0).logCode).isEqualTo(UI_ACTION_LATENCY_REPORTED);
+ assertThat(events.get(0).statsdAction).isEqualTo(
+ UIACTION_LATENCY_REPORTED__ACTION__ACTION_SHOW_VOICE_INTERACTION);
+ assertThat(events.get(0).durationMillis).isEqualTo(1234);
+ }
+}
diff --git a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
index d1f0b5e..645324d 100644
--- a/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
+++ b/core/tests/coretests/src/com/android/internal/util/LatencyTrackerTest.java
@@ -16,19 +16,22 @@
package com.android.internal.util;
+import static android.provider.DeviceConfig.NAMESPACE_LATENCY_TRACKER;
import static android.text.TextUtils.formatSimple;
+import static com.android.internal.util.FrameworkStatsLog.UI_ACTION_LATENCY_REPORTED;
import static com.android.internal.util.LatencyTracker.STATSD_ACTION;
import static com.google.common.truth.Truth.assertThat;
import static com.google.common.truth.Truth.assertWithMessage;
import android.provider.DeviceConfig;
-import android.util.Log;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import androidx.test.filters.SmallTest;
+import com.android.internal.util.LatencyTracker.ActionProperties;
+
import com.google.common.truth.Expect;
import org.junit.Before;
@@ -38,7 +41,6 @@
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
-import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
@@ -49,27 +51,23 @@
@SmallTest
@RunWith(AndroidJUnit4.class)
public class LatencyTrackerTest {
- private static final String TAG = LatencyTrackerTest.class.getSimpleName();
private static final String ENUM_NAME_PREFIX = "UIACTION_LATENCY_REPORTED__ACTION__";
- private static final String ACTION_ENABLE_SUFFIX = "_enable";
- private static final Duration TEST_TIMEOUT = Duration.ofMillis(500);
@Rule
public final Expect mExpect = Expect.create();
+ // Fake is used because it tests the real logic of LatencyTracker, and it only fakes the
+ // outcomes (PerfettoTrigger and FrameworkStatsLog).
+ private FakeLatencyTracker mLatencyTracker;
+
@Before
- public void setUp() {
- DeviceConfig.deleteProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
- LatencyTracker.SETTINGS_ENABLED_KEY);
- getAllActions().forEach(action -> {
- DeviceConfig.deleteProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
- action.getName().toLowerCase() + ACTION_ENABLE_SUFFIX);
- });
+ public void setUp() throws Exception {
+ mLatencyTracker = FakeLatencyTracker.create();
}
@Test
public void testCujsMapToEnumsCorrectly() {
- List<Field> actions = getAllActions();
+ List<Field> actions = getAllActionFields();
Map<Integer, String> enumsMap = Arrays.stream(FrameworkStatsLog.class.getDeclaredFields())
.filter(f -> f.getName().startsWith(ENUM_NAME_PREFIX)
&& Modifier.isStatic(f.getModifiers())
@@ -101,7 +99,7 @@
@Test
public void testCujTypeEnumCorrectlyDefined() throws Exception {
- List<Field> cujEnumFields = getAllActions();
+ List<Field> cujEnumFields = getAllActionFields();
HashSet<Integer> allValues = new HashSet<>();
for (Field field : cujEnumFields) {
int fieldValue = field.getInt(null);
@@ -118,92 +116,242 @@
}
@Test
- public void testIsEnabled_globalEnabled() {
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ public void testIsEnabled_trueWhenGlobalEnabled() throws Exception {
+ DeviceConfig.setProperty(NAMESPACE_LATENCY_TRACKER,
LatencyTracker.SETTINGS_ENABLED_KEY, "true", false);
- LatencyTracker latencyTracker = new LatencyTracker();
- waitForLatencyTrackerToUpdateProperties(latencyTracker);
- assertThat(latencyTracker.isEnabled()).isTrue();
+ mLatencyTracker.waitForGlobalEnabledState(true);
+ mLatencyTracker.waitForAllPropertiesEnableState(true);
+
+ //noinspection deprecation
+ assertThat(mLatencyTracker.isEnabled()).isTrue();
}
@Test
- public void testIsEnabled_globalDisabled() {
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ public void testIsEnabled_falseWhenGlobalDisabled() throws Exception {
+ DeviceConfig.setProperty(NAMESPACE_LATENCY_TRACKER,
LatencyTracker.SETTINGS_ENABLED_KEY, "false", false);
- LatencyTracker latencyTracker = new LatencyTracker();
- waitForLatencyTrackerToUpdateProperties(latencyTracker);
- assertThat(latencyTracker.isEnabled()).isFalse();
+ mLatencyTracker.waitForGlobalEnabledState(false);
+ mLatencyTracker.waitForAllPropertiesEnableState(false);
+
+ //noinspection deprecation
+ assertThat(mLatencyTracker.isEnabled()).isFalse();
}
@Test
- public void testIsEnabledAction_useGlobalValueWhenActionEnableIsNotSet() {
- LatencyTracker latencyTracker = new LatencyTracker();
+ public void testIsEnabledAction_useGlobalValueWhenActionEnableIsNotSet()
+ throws Exception {
// using a single test action, but this applies to all actions
int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
- Log.i(TAG, "setting property=" + LatencyTracker.SETTINGS_ENABLED_KEY + ", value=true");
- latencyTracker.mDeviceConfigPropertiesUpdated.close();
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
+ DeviceConfig.deleteProperty(NAMESPACE_LATENCY_TRACKER,
+ "action_show_voice_interaction_enable");
+ mLatencyTracker.waitForAllPropertiesEnableState(false);
+ DeviceConfig.setProperty(NAMESPACE_LATENCY_TRACKER,
LatencyTracker.SETTINGS_ENABLED_KEY, "true", false);
- waitForLatencyTrackerToUpdateProperties(latencyTracker);
- assertThat(
- latencyTracker.isEnabled(action)).isTrue();
+ mLatencyTracker.waitForGlobalEnabledState(true);
+ mLatencyTracker.waitForAllPropertiesEnableState(true);
- Log.i(TAG, "setting property=" + LatencyTracker.SETTINGS_ENABLED_KEY
- + ", value=false");
- latencyTracker.mDeviceConfigPropertiesUpdated.close();
- DeviceConfig.setProperty(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
- LatencyTracker.SETTINGS_ENABLED_KEY, "false", false);
- waitForLatencyTrackerToUpdateProperties(latencyTracker);
- assertThat(latencyTracker.isEnabled(action)).isFalse();
+ assertThat(mLatencyTracker.isEnabled(action)).isTrue();
}
@Test
public void testIsEnabledAction_actionPropertyOverridesGlobalProperty()
- throws DeviceConfig.BadConfigException {
- LatencyTracker latencyTracker = new LatencyTracker();
+ throws Exception {
// using a single test action, but this applies to all actions
int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
- String actionEnableProperty = "action_show_voice_interaction" + ACTION_ENABLE_SUFFIX;
- Log.i(TAG, "setting property=" + actionEnableProperty + ", value=true");
+ DeviceConfig.setProperty(NAMESPACE_LATENCY_TRACKER,
+ LatencyTracker.SETTINGS_ENABLED_KEY, "false", false);
+ mLatencyTracker.waitForGlobalEnabledState(false);
- latencyTracker.mDeviceConfigPropertiesUpdated.close();
- Map<String, String> properties = new HashMap<String, String>() {{
- put(LatencyTracker.SETTINGS_ENABLED_KEY, "false");
- put(actionEnableProperty, "true");
- }};
+ Map<String, String> deviceConfigProperties = new HashMap<>();
+ deviceConfigProperties.put("action_show_voice_interaction_enable", "true");
+ deviceConfigProperties.put("action_show_voice_interaction_sample_interval", "1");
+ deviceConfigProperties.put("action_show_voice_interaction_trace_threshold", "-1");
DeviceConfig.setProperties(
- new DeviceConfig.Properties(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
- properties));
- waitForLatencyTrackerToUpdateProperties(latencyTracker);
- assertThat(latencyTracker.isEnabled(action)).isTrue();
+ new DeviceConfig.Properties(NAMESPACE_LATENCY_TRACKER,
+ deviceConfigProperties));
- latencyTracker.mDeviceConfigPropertiesUpdated.close();
- Log.i(TAG, "setting property=" + actionEnableProperty + ", value=false");
- properties.put(LatencyTracker.SETTINGS_ENABLED_KEY, "true");
- properties.put(actionEnableProperty, "false");
- DeviceConfig.setProperties(
- new DeviceConfig.Properties(DeviceConfig.NAMESPACE_LATENCY_TRACKER,
- properties));
- waitForLatencyTrackerToUpdateProperties(latencyTracker);
- assertThat(latencyTracker.isEnabled(action)).isFalse();
+ mLatencyTracker.waitForMatchingActionProperties(
+ new ActionProperties(action, true /* enabled */, 1 /* samplingInterval */,
+ -1 /* traceThreshold */));
+
+ assertThat(mLatencyTracker.isEnabled(action)).isTrue();
}
- private void waitForLatencyTrackerToUpdateProperties(LatencyTracker latencyTracker) {
- try {
- Thread.sleep(TEST_TIMEOUT.toMillis());
- } catch (InterruptedException e) {
- e.printStackTrace();
- }
- assertThat(latencyTracker.mDeviceConfigPropertiesUpdated.block(
- TEST_TIMEOUT.toMillis())).isTrue();
+ @Test
+ public void testLogsWhenEnabled() throws Exception {
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ Map<String, String> deviceConfigProperties = new HashMap<>();
+ deviceConfigProperties.put("action_show_voice_interaction_enable", "true");
+ deviceConfigProperties.put("action_show_voice_interaction_sample_interval", "1");
+ deviceConfigProperties.put("action_show_voice_interaction_trace_threshold", "-1");
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties(NAMESPACE_LATENCY_TRACKER,
+ deviceConfigProperties));
+ mLatencyTracker.waitForMatchingActionProperties(
+ new ActionProperties(action, true /* enabled */, 1 /* samplingInterval */,
+ -1 /* traceThreshold */));
+
+ mLatencyTracker.logAction(action, 1234);
+ assertThat(mLatencyTracker.getEventsWrittenToFrameworkStats(action)).hasSize(1);
+ LatencyTracker.FrameworkStatsLogEvent frameworkStatsLog =
+ mLatencyTracker.getEventsWrittenToFrameworkStats(action).get(0);
+ assertThat(frameworkStatsLog.logCode).isEqualTo(UI_ACTION_LATENCY_REPORTED);
+ assertThat(frameworkStatsLog.statsdAction).isEqualTo(STATSD_ACTION[action]);
+ assertThat(frameworkStatsLog.durationMillis).isEqualTo(1234);
+
+ mLatencyTracker.clearEvents();
+
+ mLatencyTracker.onActionStart(action);
+ mLatencyTracker.onActionEnd(action);
+ // assert that action was logged, but we cannot confirm duration logged
+ assertThat(mLatencyTracker.getEventsWrittenToFrameworkStats(action)).hasSize(1);
+ frameworkStatsLog = mLatencyTracker.getEventsWrittenToFrameworkStats(action).get(0);
+ assertThat(frameworkStatsLog.logCode).isEqualTo(UI_ACTION_LATENCY_REPORTED);
+ assertThat(frameworkStatsLog.statsdAction).isEqualTo(STATSD_ACTION[action]);
}
- private List<Field> getAllActions() {
- return Arrays.stream(LatencyTracker.class.getDeclaredFields())
- .filter(field -> field.getName().startsWith("ACTION_")
- && Modifier.isStatic(field.getModifiers())
- && field.getType() == int.class)
- .collect(Collectors.toList());
+ @Test
+ public void testDoesNotLogWhenDisabled() throws Exception {
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ DeviceConfig.setProperty(NAMESPACE_LATENCY_TRACKER, "action_show_voice_interaction_enable",
+ "false", false);
+ mLatencyTracker.waitForActionEnabledState(action, false);
+ assertThat(mLatencyTracker.isEnabled(action)).isFalse();
+
+ mLatencyTracker.logAction(action, 1234);
+ assertThat(mLatencyTracker.getEventsWrittenToFrameworkStats(action)).isEmpty();
+
+ mLatencyTracker.onActionStart(action);
+ mLatencyTracker.onActionEnd(action);
+ assertThat(mLatencyTracker.getEventsWrittenToFrameworkStats(action)).isEmpty();
+ }
+
+ @Test
+ public void testOnActionEndDoesNotLogWithoutOnActionStart()
+ throws Exception {
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ DeviceConfig.setProperty(NAMESPACE_LATENCY_TRACKER, "action_show_voice_interaction_enable",
+ "true", false);
+ mLatencyTracker.waitForActionEnabledState(action, true);
+ assertThat(mLatencyTracker.isEnabled(action)).isTrue();
+
+ mLatencyTracker.onActionEnd(action);
+ assertThat(mLatencyTracker.getEventsWrittenToFrameworkStats(action)).isEmpty();
+ }
+
+ @Test
+ public void testOnActionEndDoesNotLogWhenCanceled()
+ throws Exception {
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ DeviceConfig.setProperty(NAMESPACE_LATENCY_TRACKER, "action_show_voice_interaction_enable",
+ "true", false);
+ mLatencyTracker.waitForActionEnabledState(action, true);
+ assertThat(mLatencyTracker.isEnabled(action)).isTrue();
+
+ mLatencyTracker.onActionStart(action);
+ mLatencyTracker.onActionCancel(action);
+ mLatencyTracker.onActionEnd(action);
+ assertThat(mLatencyTracker.getEventsWrittenToFrameworkStats(action)).isEmpty();
+ }
+
+ @Test
+ public void testNeverTriggersPerfettoWhenThresholdNegative()
+ throws Exception {
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ Map<String, String> deviceConfigProperties = new HashMap<>();
+ deviceConfigProperties.put("action_show_voice_interaction_enable", "true");
+ deviceConfigProperties.put("action_show_voice_interaction_sample_interval", "1");
+ deviceConfigProperties.put("action_show_voice_interaction_trace_threshold", "-1");
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties(NAMESPACE_LATENCY_TRACKER,
+ deviceConfigProperties));
+ mLatencyTracker.waitForMatchingActionProperties(
+ new ActionProperties(action, true /* enabled */, 1 /* samplingInterval */,
+ -1 /* traceThreshold */));
+
+ mLatencyTracker.onActionStart(action);
+ mLatencyTracker.onActionEnd(action);
+ assertThat(mLatencyTracker.getTriggeredPerfettoTraceNames()).isEmpty();
+ }
+
+ @Test
+ public void testNeverTriggersPerfettoWhenDisabled()
+ throws Exception {
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ Map<String, String> deviceConfigProperties = new HashMap<>();
+ deviceConfigProperties.put("action_show_voice_interaction_enable", "false");
+ deviceConfigProperties.put("action_show_voice_interaction_sample_interval", "1");
+ deviceConfigProperties.put("action_show_voice_interaction_trace_threshold", "1");
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties(NAMESPACE_LATENCY_TRACKER,
+ deviceConfigProperties));
+ mLatencyTracker.waitForMatchingActionProperties(
+ new ActionProperties(action, false /* enabled */, 1 /* samplingInterval */,
+ 1 /* traceThreshold */));
+
+ mLatencyTracker.onActionStart(action);
+ mLatencyTracker.onActionEnd(action);
+ assertThat(mLatencyTracker.getTriggeredPerfettoTraceNames()).isEmpty();
+ }
+
+ @Test
+ public void testTriggersPerfettoWhenAboveThreshold()
+ throws Exception {
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ Map<String, String> deviceConfigProperties = new HashMap<>();
+ deviceConfigProperties.put("action_show_voice_interaction_enable", "true");
+ deviceConfigProperties.put("action_show_voice_interaction_sample_interval", "1");
+ deviceConfigProperties.put("action_show_voice_interaction_trace_threshold", "1");
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties(NAMESPACE_LATENCY_TRACKER,
+ deviceConfigProperties));
+ mLatencyTracker.waitForMatchingActionProperties(
+ new ActionProperties(action, true /* enabled */, 1 /* samplingInterval */,
+ 1 /* traceThreshold */));
+
+ mLatencyTracker.onActionStart(action);
+ // We need to sleep here to ensure that the end call is past the set trace threshold (1ms)
+ Thread.sleep(5 /* millis */);
+ mLatencyTracker.onActionEnd(action);
+ assertThat(mLatencyTracker.getTriggeredPerfettoTraceNames()).hasSize(1);
+ assertThat(mLatencyTracker.getTriggeredPerfettoTraceNames().get(0)).isEqualTo(
+ "com.android.telemetry.latency-tracker-ACTION_SHOW_VOICE_INTERACTION");
+ }
+
+ @Test
+ public void testNeverTriggersPerfettoWhenBelowThreshold()
+ throws Exception {
+ // using a single test action, but this applies to all actions
+ int action = LatencyTracker.ACTION_SHOW_VOICE_INTERACTION;
+ Map<String, String> deviceConfigProperties = new HashMap<>();
+ deviceConfigProperties.put("action_show_voice_interaction_enable", "true");
+ deviceConfigProperties.put("action_show_voice_interaction_sample_interval", "1");
+ deviceConfigProperties.put("action_show_voice_interaction_trace_threshold", "1000");
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties(NAMESPACE_LATENCY_TRACKER,
+ deviceConfigProperties));
+ mLatencyTracker.waitForMatchingActionProperties(
+ new ActionProperties(action, true /* enabled */, 1 /* samplingInterval */,
+ 1000 /* traceThreshold */));
+
+ mLatencyTracker.onActionStart(action);
+ // No sleep here to ensure that end call comes before 1000ms threshold
+ mLatencyTracker.onActionEnd(action);
+ assertThat(mLatencyTracker.getTriggeredPerfettoTraceNames()).isEmpty();
+ }
+
+ private List<Field> getAllActionFields() {
+ return Arrays.stream(LatencyTracker.class.getDeclaredFields()).filter(
+ field -> field.getName().startsWith("ACTION_") && Modifier.isStatic(
+ field.getModifiers()) && field.getType() == int.class).collect(
+ Collectors.toList());
}
private int getIntFieldChecked(Field field) {
diff --git a/core/tests/coretests/src/com/android/internal/util/OWNERS b/core/tests/coretests/src/com/android/internal/util/OWNERS
index d832745..dda11fb 100644
--- a/core/tests/coretests/src/com/android/internal/util/OWNERS
+++ b/core/tests/coretests/src/com/android/internal/util/OWNERS
@@ -1,2 +1,3 @@
per-file *Notification* = file:/services/core/java/com/android/server/notification/OWNERS
-per-file *ContrastColor* = file:/services/core/java/com/android/server/notification/OWNERS
\ No newline at end of file
+per-file *ContrastColor* = file:/services/core/java/com/android/server/notification/OWNERS
+per-file *LatencyTracker* = file:/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
diff --git a/core/tests/coretests/testdoubles/Android.bp b/core/tests/coretests/testdoubles/Android.bp
new file mode 100644
index 0000000..35f6911
--- /dev/null
+++ b/core/tests/coretests/testdoubles/Android.bp
@@ -0,0 +1,19 @@
+package {
+ // See: http://go/android-license-faq
+ // A large-scale-change added 'default_applicable_licenses' to import
+ // all of the 'license_kinds' from "frameworks_base_license"
+ // to get the below license kinds:
+ // SPDX-license-identifier-Apache-2.0
+ // SPDX-license-identifier-BSD
+ // legacy_unencumbered
+ default_applicable_licenses: ["frameworks_base_license"],
+}
+
+filegroup {
+ name: "FrameworksCoreTestDoubles-sources",
+ srcs: ["src/**/*.java"],
+ visibility: [
+ "//frameworks/base/core/tests/coretests",
+ "//frameworks/base/services/tests/voiceinteractiontests",
+ ],
+}
diff --git a/core/tests/coretests/testdoubles/OWNERS b/core/tests/coretests/testdoubles/OWNERS
new file mode 100644
index 0000000..baf92ec
--- /dev/null
+++ b/core/tests/coretests/testdoubles/OWNERS
@@ -0,0 +1 @@
+per-file *LatencyTracker* = file:/core/java/com/android/internal/util/LATENCY_TRACKER_OWNERS
diff --git a/core/tests/coretests/testdoubles/src/com/android/internal/util/FakeLatencyTracker.java b/core/tests/coretests/testdoubles/src/com/android/internal/util/FakeLatencyTracker.java
new file mode 100644
index 0000000..306ecde
--- /dev/null
+++ b/core/tests/coretests/testdoubles/src/com/android/internal/util/FakeLatencyTracker.java
@@ -0,0 +1,285 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.internal.util;
+
+import static com.android.internal.util.LatencyTracker.ActionProperties.ENABLE_SUFFIX;
+import static com.android.internal.util.LatencyTracker.ActionProperties.SAMPLE_INTERVAL_SUFFIX;
+import static com.android.internal.util.LatencyTracker.ActionProperties.TRACE_THRESHOLD_SUFFIX;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.os.ConditionVariable;
+import android.provider.DeviceConfig;
+import android.util.Log;
+import android.util.SparseArray;
+
+import androidx.annotation.Nullable;
+
+import com.android.internal.annotations.GuardedBy;
+
+import com.google.common.collect.ImmutableMap;
+
+import java.time.Duration;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.concurrent.atomic.AtomicReference;
+
+public final class FakeLatencyTracker extends LatencyTracker {
+
+ private static final String TAG = "FakeLatencyTracker";
+ private static final Duration FORCE_UPDATE_TIMEOUT = Duration.ofSeconds(1);
+
+ private final Object mLock = new Object();
+ @GuardedBy("mLock")
+ private final Map<Integer, List<FrameworkStatsLogEvent>> mLatenciesLogged;
+ @GuardedBy("mLock")
+ private final List<String> mPerfettoTraceNamesTriggered;
+ private final AtomicReference<SparseArray<ActionProperties>> mLastPropertiesUpdate =
+ new AtomicReference<>();
+ @Nullable
+ @GuardedBy("mLock")
+ private Callable<Boolean> mShouldClosePropertiesUpdatedCallable = null;
+ private final ConditionVariable mDeviceConfigPropertiesUpdated = new ConditionVariable();
+
+ public static FakeLatencyTracker create() throws Exception {
+ Log.i(TAG, "create");
+ disableForAllActions();
+ FakeLatencyTracker fakeLatencyTracker = new FakeLatencyTracker();
+ // always return the fake in the disabled state and let the client control the desired state
+ fakeLatencyTracker.waitForGlobalEnabledState(false);
+ fakeLatencyTracker.waitForAllPropertiesEnableState(false);
+ return fakeLatencyTracker;
+ }
+
+ FakeLatencyTracker() {
+ super();
+ mLatenciesLogged = new HashMap<>();
+ mPerfettoTraceNamesTriggered = new ArrayList<>();
+ }
+
+ private static void disableForAllActions() throws DeviceConfig.BadConfigException {
+ Map<String, String> properties = new HashMap<>();
+ properties.put(LatencyTracker.SETTINGS_ENABLED_KEY, "false");
+ for (int action : STATSD_ACTION) {
+ Log.d(TAG, "disabling action=" + action + ", property=" + getNameOfAction(
+ action).toLowerCase(Locale.ROOT) + ENABLE_SUFFIX);
+ properties.put(getNameOfAction(action).toLowerCase(Locale.ROOT) + ENABLE_SUFFIX,
+ "false");
+ }
+
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties(DeviceConfig.NAMESPACE_LATENCY_TRACKER, properties));
+ }
+
+ public void forceEnabled(int action, int traceThresholdMillis)
+ throws Exception {
+ String actionName = getNameOfAction(STATSD_ACTION[action]).toLowerCase(Locale.ROOT);
+ String actionEnableProperty = actionName + ENABLE_SUFFIX;
+ String actionSampleProperty = actionName + SAMPLE_INTERVAL_SUFFIX;
+ String actionTraceProperty = actionName + TRACE_THRESHOLD_SUFFIX;
+ Log.i(TAG, "setting property=" + actionTraceProperty + ", value=" + traceThresholdMillis);
+ Log.i(TAG, "setting property=" + actionEnableProperty + ", value=true");
+
+ Map<String, String> properties = new HashMap<>(ImmutableMap.of(
+ actionEnableProperty, "true",
+ // Fake forces to sample every event
+ actionSampleProperty, String.valueOf(1),
+ actionTraceProperty, String.valueOf(traceThresholdMillis)
+ ));
+ DeviceConfig.setProperties(
+ new DeviceConfig.Properties(DeviceConfig.NAMESPACE_LATENCY_TRACKER, properties));
+ waitForMatchingActionProperties(
+ new ActionProperties(action, true /* enabled */, 1 /* samplingInterval */,
+ traceThresholdMillis));
+ }
+
+ public List<FrameworkStatsLogEvent> getEventsWrittenToFrameworkStats(@Action int action) {
+ synchronized (mLock) {
+ Log.i(TAG, "getEventsWrittenToFrameworkStats: mLatenciesLogged=" + mLatenciesLogged);
+ return mLatenciesLogged.getOrDefault(action, Collections.emptyList());
+ }
+ }
+
+ public List<String> getTriggeredPerfettoTraceNames() {
+ synchronized (mLock) {
+ return mPerfettoTraceNamesTriggered;
+ }
+ }
+
+ public void clearEvents() {
+ synchronized (mLock) {
+ mLatenciesLogged.clear();
+ mPerfettoTraceNamesTriggered.clear();
+ }
+ }
+
+ @Override
+ public void onDeviceConfigPropertiesUpdated(SparseArray<ActionProperties> actionProperties) {
+ Log.d(TAG, "onDeviceConfigPropertiesUpdated: " + actionProperties);
+ mLastPropertiesUpdate.set(actionProperties);
+ synchronized (mLock) {
+ if (mShouldClosePropertiesUpdatedCallable != null) {
+ try {
+ boolean shouldClosePropertiesUpdated =
+ mShouldClosePropertiesUpdatedCallable.call();
+ Log.i(TAG, "shouldClosePropertiesUpdatedCallable callable result="
+ + shouldClosePropertiesUpdated);
+ if (shouldClosePropertiesUpdated) {
+ Log.i(TAG, "shouldClosePropertiesUpdatedCallable=true, opening condition");
+ mShouldClosePropertiesUpdatedCallable = null;
+ mDeviceConfigPropertiesUpdated.open();
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "exception when calling callable", e);
+ throw new RuntimeException(e);
+ }
+ } else {
+ Log.i(TAG, "no conditional callable set, opening condition");
+ mDeviceConfigPropertiesUpdated.open();
+ }
+ }
+ }
+
+ @Override
+ public void onTriggerPerfetto(String triggerName) {
+ synchronized (mLock) {
+ mPerfettoTraceNamesTriggered.add(triggerName);
+ }
+ }
+
+ @Override
+ public void onLogToFrameworkStats(FrameworkStatsLogEvent event) {
+ synchronized (mLock) {
+ Log.i(TAG, "onLogToFrameworkStats: event=" + event);
+ List<FrameworkStatsLogEvent> eventList = mLatenciesLogged.getOrDefault(event.action,
+ new ArrayList<>());
+ eventList.add(event);
+ mLatenciesLogged.put(event.action, eventList);
+ }
+ }
+
+ public void waitForAllPropertiesEnableState(boolean enabledState) throws Exception {
+ Log.i(TAG, "waitForAllPropertiesEnableState: enabledState=" + enabledState);
+ synchronized (mLock) {
+ Log.i(TAG, "closing condition");
+ mDeviceConfigPropertiesUpdated.close();
+ // Update the callable to only close the properties updated condition when all the
+ // desired properties have been updated. The DeviceConfig callbacks may happen multiple
+ // times so testing the resulting updates is required.
+ mShouldClosePropertiesUpdatedCallable = () -> {
+ Log.i(TAG, "verifying if last properties update has all properties enable="
+ + enabledState);
+ SparseArray<ActionProperties> newProperties = mLastPropertiesUpdate.get();
+ if (newProperties != null) {
+ for (int i = 0; i < newProperties.size(); i++) {
+ if (newProperties.get(i).isEnabled() != enabledState) {
+ return false;
+ }
+ }
+ }
+ return true;
+ };
+ if (mShouldClosePropertiesUpdatedCallable.call()) {
+ return;
+ }
+ }
+ Log.i(TAG, "waiting for condition");
+ assertThat(mDeviceConfigPropertiesUpdated.block(FORCE_UPDATE_TIMEOUT.toMillis())).isTrue();
+ }
+
+ public void waitForMatchingActionProperties(ActionProperties actionProperties)
+ throws Exception {
+ Log.i(TAG, "waitForMatchingActionProperties: actionProperties=" + actionProperties);
+ synchronized (mLock) {
+ Log.i(TAG, "closing condition");
+ mDeviceConfigPropertiesUpdated.close();
+ // Update the callable to only close the properties updated condition when all the
+ // desired properties have been updated. The DeviceConfig callbacks may happen multiple
+ // times so testing the resulting updates is required.
+ mShouldClosePropertiesUpdatedCallable = () -> {
+ Log.i(TAG, "verifying if last properties update contains matching property ="
+ + actionProperties);
+ SparseArray<ActionProperties> newProperties = mLastPropertiesUpdate.get();
+ if (newProperties != null) {
+ if (newProperties.size() > 0) {
+ return newProperties.get(actionProperties.getAction()).equals(
+ actionProperties);
+ }
+ }
+ return false;
+ };
+ if (mShouldClosePropertiesUpdatedCallable.call()) {
+ return;
+ }
+ }
+ Log.i(TAG, "waiting for condition");
+ assertThat(mDeviceConfigPropertiesUpdated.block(FORCE_UPDATE_TIMEOUT.toMillis())).isTrue();
+ }
+
+ public void waitForActionEnabledState(int action, boolean enabledState) throws Exception {
+ Log.i(TAG, "waitForActionEnabledState:"
+ + " action=" + action + ", enabledState=" + enabledState);
+ synchronized (mLock) {
+ Log.i(TAG, "closing condition");
+ mDeviceConfigPropertiesUpdated.close();
+ // Update the callable to only close the properties updated condition when all the
+ // desired properties have been updated. The DeviceConfig callbacks may happen multiple
+ // times so testing the resulting updates is required.
+ mShouldClosePropertiesUpdatedCallable = () -> {
+ Log.i(TAG, "verifying if last properties update contains action=" + action
+ + ", enabledState=" + enabledState);
+ SparseArray<ActionProperties> newProperties = mLastPropertiesUpdate.get();
+ if (newProperties != null) {
+ if (newProperties.size() > 0) {
+ return newProperties.get(action).isEnabled() == enabledState;
+ }
+ }
+ return false;
+ };
+ if (mShouldClosePropertiesUpdatedCallable.call()) {
+ return;
+ }
+ }
+ Log.i(TAG, "waiting for condition");
+ assertThat(mDeviceConfigPropertiesUpdated.block(FORCE_UPDATE_TIMEOUT.toMillis())).isTrue();
+ }
+
+ public void waitForGlobalEnabledState(boolean enabledState) throws Exception {
+ Log.i(TAG, "waitForGlobalEnabledState: enabledState=" + enabledState);
+ synchronized (mLock) {
+ Log.i(TAG, "closing condition");
+ mDeviceConfigPropertiesUpdated.close();
+ // Update the callable to only close the properties updated condition when all the
+ // desired properties have been updated. The DeviceConfig callbacks may happen multiple
+ // times so testing the resulting updates is required.
+ mShouldClosePropertiesUpdatedCallable = () -> {
+ //noinspection deprecation
+ return isEnabled() == enabledState;
+ };
+ if (mShouldClosePropertiesUpdatedCallable.call()) {
+ return;
+ }
+ }
+ Log.i(TAG, "waiting for condition");
+ assertThat(mDeviceConfigPropertiesUpdated.block(FORCE_UPDATE_TIMEOUT.toMillis())).isTrue();
+ }
+}
diff --git a/data/etc/TEST_MAPPING b/data/etc/TEST_MAPPING
index 1a5db2f..5927720 100644
--- a/data/etc/TEST_MAPPING
+++ b/data/etc/TEST_MAPPING
@@ -2,10 +2,10 @@
"presubmit": [
{
"file_patterns": ["(/|^)platform.xml"],
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.RuntimePermissionProperties"
+ "include-filter": "android.permissionpolicy.cts.RuntimePermissionProperties"
}
]
}
diff --git a/data/etc/com.android.emergency.xml b/data/etc/com.android.emergency.xml
index 2d6ae2e..19c52a6 100644
--- a/data/etc/com.android.emergency.xml
+++ b/data/etc/com.android.emergency.xml
@@ -20,6 +20,7 @@
<permission name="android.permission.CALL_PRIVILEGED"/>
<permission name="android.permission.MANAGE_USERS"/>
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
+ <permission name="android.permission.SCHEDULE_EXACT_ALARM"/>
<permission name="android.permission.START_ACTIVITIES_FROM_BACKGROUND"/>
<!-- Required to update emergency gesture settings -->
<permission name="android.permission.WRITE_SECURE_SETTINGS"/>
diff --git a/data/etc/com.android.systemui.xml b/data/etc/com.android.systemui.xml
index fe639ff..922dbb5 100644
--- a/data/etc/com.android.systemui.xml
+++ b/data/etc/com.android.systemui.xml
@@ -51,6 +51,7 @@
<permission name="android.permission.READ_NETWORK_USAGE_HISTORY"/>
<permission name="android.permission.READ_PRIVILEGED_PHONE_STATE"/>
<permission name="android.permission.READ_PRECISE_PHONE_STATE"/>
+ <permission name="android.permission.READ_WALLPAPER_INTERNAL"/>
<permission name="android.permission.REAL_GET_TASKS"/>
<permission name="android.permission.REQUEST_NETWORK_SCORES"/>
<permission name="android.permission.RECEIVE_MEDIA_RESOURCE_USAGE"/>
diff --git a/data/etc/privapp-permissions-platform.xml b/data/etc/privapp-permissions-platform.xml
index 5d303cf..0faf62e 100644
--- a/data/etc/privapp-permissions-platform.xml
+++ b/data/etc/privapp-permissions-platform.xml
@@ -321,6 +321,7 @@
<permission name="android.permission.REGISTER_CONNECTION_MANAGER"/>
<permission name="android.permission.REGISTER_SIM_SUBSCRIPTION"/>
<permission name="android.permission.RETRIEVE_WINDOW_CONTENT"/>
+ <permission name="android.permission.SCHEDULE_EXACT_ALARM"/>
<permission name="android.permission.SET_ALWAYS_FINISH"/>
<permission name="android.permission.SET_ANIMATION_SCALE"/>
<permission name="android.permission.SET_DEBUG_APP"/>
diff --git a/data/etc/services.core.protolog.json b/data/etc/services.core.protolog.json
index ffc5ff2..5549f88 100644
--- a/data/etc/services.core.protolog.json
+++ b/data/etc/services.core.protolog.json
@@ -259,12 +259,6 @@
"group": "WM_DEBUG_BOOT",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-1878839956": {
- "message": "Marking app token %s with replacing windows.",
- "level": "DEBUG",
- "group": "WM_DEBUG_ADD_REMOVE",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"-1872288685": {
"message": "applyAnimation: anim=%s nextAppTransition=%s transit=%s isEntrance=%b Callers=%s",
"level": "VERBOSE",
@@ -463,12 +457,6 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/Task.java"
},
- "-1698815688": {
- "message": "Resetting app token %s of replacing window marks.",
- "level": "DEBUG",
- "group": "WM_DEBUG_ADD_REMOVE",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"-1679411993": {
"message": "setVr2dDisplayId called for: %d",
"level": "DEBUG",
@@ -481,12 +469,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-1661704580": {
- "message": "Attempted to set replacing window on non-existing app token %s",
- "level": "WARN",
- "group": "WM_ERROR",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"-1647332198": {
"message": "remove RecentTask %s when finishing user %d",
"level": "INFO",
@@ -613,12 +595,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-1515151503": {
- "message": ">>> OPEN TRANSACTION removeReplacedWindows",
- "level": "INFO",
- "group": "WM_SHOW_TRANSACTIONS",
- "at": "com\/android\/server\/wm\/RootWindowContainer.java"
- },
"-1501564055": {
"message": "Organized TaskFragment is not ready= %s",
"level": "VERBOSE",
@@ -691,12 +667,6 @@
"group": "WM_DEBUG_TASKS",
"at": "com\/android\/server\/wm\/ActivityTaskManagerService.java"
},
- "-1471946192": {
- "message": "Marking app token %s with replacing child windows.",
- "level": "DEBUG",
- "group": "WM_DEBUG_ADD_REMOVE",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"-1471518109": {
"message": "Set animatingExit: reason=onAppVisibilityChanged win=%s",
"level": "DEBUG",
@@ -919,12 +889,6 @@
"group": "WM_DEBUG_BACK_PREVIEW",
"at": "com\/android\/server\/wm\/BackNavigationController.java"
},
- "-1270731689": {
- "message": "Attempted to set replacing window on app token with no content %s",
- "level": "WARN",
- "group": "WM_ERROR",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"-1263316010": {
"message": "Computed rotation=%s (%d) for display id=%d based on lastOrientation=%s (%d) and oldRotation=%s (%d)",
"level": "VERBOSE",
@@ -1417,12 +1381,6 @@
"group": "WM_DEBUG_ORIENTATION",
"at": "com\/android\/server\/wm\/DisplayRotationCompatPolicy.java"
},
- "-799003045": {
- "message": "Set animatingExit: reason=remove\/replaceWindow win=%s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_ANIM",
- "at": "com\/android\/server\/wm\/WindowState.java"
- },
"-787664727": {
"message": "Cannot launch dream activity due to invalid state. dream component: %s packageName: %s",
"level": "ERROR",
@@ -1453,6 +1411,12 @@
"group": "WM_DEBUG_WINDOW_TRANSITIONS",
"at": "com\/android\/server\/wm\/Transition.java"
},
+ "-778347463": {
+ "message": "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b mHasSurface=%b surfaceShowing=%b animating=%b app-animation=%b mDisplayFrozen=%b callers=%s",
+ "level": "VERBOSE",
+ "group": "WM_DEBUG_APP_TRANSITIONS",
+ "at": "com\/android\/server\/wm\/WindowState.java"
+ },
"-775004869": {
"message": "Not a match: %s",
"level": "DEBUG",
@@ -1963,12 +1927,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "-320419645": {
- "message": "Removing replaced window: %s",
- "level": "DEBUG",
- "group": "WM_DEBUG_ADD_REMOVE",
- "at": "com\/android\/server\/wm\/WindowState.java"
- },
"-319689203": {
"message": "Reparenting to original parent: %s for %s",
"level": "INFO",
@@ -2335,12 +2293,6 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/RemoteAnimationController.java"
},
- "38267433": {
- "message": "Attempted to reset replacing window on non-existing app token %s",
- "level": "WARN",
- "group": "WM_ERROR",
- "at": "com\/android\/server\/wm\/WindowManagerService.java"
- },
"45285419": {
"message": "startingWindow was set but startingSurface==null, couldn't remove",
"level": "VERBOSE",
@@ -2989,12 +2941,6 @@
"group": "WM_DEBUG_REMOTE_ANIMATIONS",
"at": "com\/android\/server\/wm\/RemoteAnimationController.java"
},
- "594260654": {
- "message": "Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b mHasSurface=%b surfaceShowing=%b animating=%b app-animation=%b mWillReplaceWindow=%b mDisplayFrozen=%b callers=%s",
- "level": "VERBOSE",
- "group": "WM_DEBUG_APP_TRANSITIONS",
- "at": "com\/android\/server\/wm\/WindowState.java"
- },
"600140673": {
"message": "checkBootAnimationComplete: Waiting for anim complete",
"level": "INFO",
@@ -3829,12 +3775,6 @@
"group": "WM_ERROR",
"at": "com\/android\/server\/wm\/WindowManagerService.java"
},
- "1423592961": {
- "message": "<<< CLOSE TRANSACTION removeReplacedWindows",
- "level": "INFO",
- "group": "WM_SHOW_TRANSACTIONS",
- "at": "com\/android\/server\/wm\/RootWindowContainer.java"
- },
"1430336882": {
"message": "findFocusedWindow: focusedApp windows not focusable using new focus @ %s",
"level": "VERBOSE",
@@ -3901,12 +3841,6 @@
"group": "WM_DEBUG_ADD_REMOVE",
"at": "com\/android\/server\/wm\/WindowState.java"
},
- "1515161239": {
- "message": "removeDeadWindows: %s",
- "level": "WARN",
- "group": "WM_DEBUG_ADD_REMOVE",
- "at": "com\/android\/server\/wm\/ActivityRecord.java"
- },
"1518495446": {
"message": "removeWindowToken: Attempted to remove non-existing token: %s",
"level": "WARN",
@@ -4273,12 +4207,6 @@
"group": "WM_DEBUG_WINDOW_ORGANIZER",
"at": "com\/android\/server\/wm\/TaskOrganizerController.java"
},
- "1921821199": {
- "message": "Preserving %s until the new one is added",
- "level": "VERBOSE",
- "group": "WM_DEBUG_ADD_REMOVE",
- "at": "com\/android\/server\/wm\/WindowState.java"
- },
"1928325128": {
"message": "Run showImeRunner",
"level": "DEBUG",
@@ -4489,12 +4417,6 @@
"group": "WM_DEBUG_APP_TRANSITIONS",
"at": "com\/android\/server\/wm\/AppTransitionController.java"
},
- "2114149926": {
- "message": "Not removing %s because app died while it's visible",
- "level": "VERBOSE",
- "group": "WM_DEBUG_ADD_REMOVE",
- "at": "com\/android\/server\/wm\/WindowState.java"
- },
"2117696413": {
"message": "moveTaskToFront: moving taskId=%d",
"level": "DEBUG",
diff --git a/data/fonts/fonts.xml b/data/fonts/fonts.xml
index e7ddc88..0563519 100644
--- a/data/fonts/fonts.xml
+++ b/data/fonts/fonts.xml
@@ -251,7 +251,7 @@
<alias name="courier new" to="serif-monospace" />
<family name="casual">
- <font weight="400" style="normal">ComingSoon.ttf</font>
+ <font weight="400" style="normal" postScriptName="ComingSoon-Regular">ComingSoon.ttf</font>
</family>
<family name="cursive">
diff --git a/data/keyboards/Generic.kl b/data/keyboards/Generic.kl
index 247d484..e27cd97 100644
--- a/data/keyboards/Generic.kl
+++ b/data/keyboards/Generic.kl
@@ -424,6 +424,10 @@
key 582 VOICE_ASSIST
# Linux KEY_ASSISTANT
key 583 ASSIST
+key 656 MACRO_1
+key 657 MACRO_2
+key 658 MACRO_3
+key 659 MACRO_4
# Keys defined by HID usages
key usage 0x0c0067 WINDOW
diff --git a/keystore/java/android/security/keystore2/KeyStoreCryptoOperationUtils.java b/keystore/java/android/security/keystore2/KeyStoreCryptoOperationUtils.java
index 6fa1a69..372e4cb 100644
--- a/keystore/java/android/security/keystore2/KeyStoreCryptoOperationUtils.java
+++ b/keystore/java/android/security/keystore2/KeyStoreCryptoOperationUtils.java
@@ -40,7 +40,6 @@
import java.security.SecureRandom;
import java.util.ArrayList;
import java.util.List;
-import java.util.Random;
/**
* Assorted utility methods for implementing crypto operations on top of KeyStore.
@@ -50,7 +49,6 @@
abstract class KeyStoreCryptoOperationUtils {
private static volatile SecureRandom sRng;
- private static final Random sRandom = new Random();
private KeyStoreCryptoOperationUtils() {}
@@ -213,7 +211,7 @@
} else {
// Keystore won't give us an operation challenge if the operation doesn't
// need user authorization. So we make our own.
- return sRandom.nextLong();
+ return getRng().nextLong();
}
}
}
diff --git a/libs/WindowManager/Shell/res/color/unfold_background.xml b/libs/WindowManager/Shell/res/color/unfold_background.xml
new file mode 100644
index 0000000..e33eb12
--- /dev/null
+++ b/libs/WindowManager/Shell/res/color/unfold_background.xml
@@ -0,0 +1,4 @@
+<?xml version="1.0" encoding="utf-8"?>
+<selector xmlns:android="http://schemas.android.com/apk/res/android">
+ <item android:color="@android:color/system_neutral1_500" android:lStar="5" />
+</selector>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml b/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
index 27e0b18..5d77713 100644
--- a/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
+++ b/libs/WindowManager/Shell/res/drawable/decor_handle_dark.xml
@@ -14,13 +14,12 @@
~ limitations under the License.
-->
<vector xmlns:android="http://schemas.android.com/apk/res/android"
- android:width="24dp"
- android:height="24dp"
- android:viewportWidth="24"
- android:viewportHeight="24"
- android:tint="@color/decor_button_dark_color">
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24">
<group android:translateY="8.0">
<path
- android:fillColor="@android:color/white" android:pathData="M3,5V3H21V5Z"/>
+ android:fillColor="@android:color/black" android:pathData="M3,5V3H21V5Z"/>
</group>
</vector>
diff --git a/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml
new file mode 100644
index 0000000..3e0297a
--- /dev/null
+++ b/libs/WindowManager/Shell/res/drawable/ic_baseline_expand_more_24.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License
+ -->
+<vector android:height="24dp" android:tint="#000000"
+ android:viewportHeight="24" android:viewportWidth="24"
+ android:width="24dp" xmlns:android="http://schemas.android.com/apk/res/android">
+ <path android:fillColor="@android:color/black" android:pathData="M16.59,8.59L12,13.17 7.41,8.59 6,10l6,6 6,-6z"/>
+</vector>
diff --git a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
index 298ad30..8d1da0f7 100644
--- a/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/bubble_manage_menu.xml
@@ -63,11 +63,11 @@
android:tint="@color/bubbles_icon_tint"/>
<TextView
+ android:id="@+id/bubble_manage_menu_dont_bubble_text"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
- android:textAppearance="@*android:style/TextAppearance.DeviceDefault"
- android:text="@string/bubbles_dont_bubble_conversation" />
+ android:textAppearance="@*android:style/TextAppearance.DeviceDefault" />
</LinearLayout>
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
new file mode 100644
index 0000000..35562b6
--- /dev/null
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_app_controls_window_decor.xml
@@ -0,0 +1,93 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2022 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
+ android:id="@+id/desktop_mode_caption"
+ android:layout_width="match_parent"
+ android:layout_height="wrap_content"
+ android:gravity="center_horizontal"
+ android:orientation="horizontal"
+ android:background="@drawable/desktop_mode_decor_title">
+
+ <LinearLayout
+ android:id="@+id/open_menu_button"
+ android:layout_width="wrap_content"
+ android:layout_height="match_parent"
+ android:orientation="horizontal"
+ android:clickable="true"
+ android:focusable="true"
+ android:paddingStart="8dp"
+ android:background="?android:selectableItemBackgroundBorderless">
+
+ <ImageView
+ android:id="@+id/application_icon"
+ android:layout_width="24dp"
+ android:layout_height="24dp"
+ android:layout_margin="4dp"
+ android:layout_gravity="center_vertical"
+ android:contentDescription="@string/app_icon_text" />
+
+ <TextView
+ android:id="@+id/application_name"
+ android:layout_width="0dp"
+ android:layout_height="match_parent"
+ android:minWidth="80dp"
+ android:textColor="@color/desktop_mode_caption_app_name_dark"
+ android:textSize="14sp"
+ android:textFontWeight="500"
+ android:gravity="center_vertical"
+ android:layout_weight="1"
+ android:paddingStart="4dp"
+ android:paddingEnd="4dp"
+ tools:text="Gmail"/>
+
+ <ImageButton
+ android:id="@+id/expand_menu_button"
+ android:layout_width="32dp"
+ android:layout_height="32dp"
+ android:padding="4dp"
+ android:contentDescription="@string/collapse_menu_text"
+ android:src="@drawable/ic_baseline_expand_more_24"
+ android:tint="@color/desktop_mode_caption_expand_button_dark"
+ android:background="@null"
+ android:scaleType="fitCenter"
+ android:clickable="false"
+ android:focusable="false"
+ android:layout_gravity="center_vertical"/>
+
+ </LinearLayout>
+
+ <View
+ android:id="@+id/caption_handle"
+ android:layout_width="wrap_content"
+ android:layout_height="40dp"
+ android:layout_weight="1"/>
+
+ <ImageButton
+ android:id="@+id/close_window"
+ android:layout_width="40dp"
+ android:layout_height="40dp"
+ android:padding="4dp"
+ android:layout_marginEnd="8dp"
+ android:contentDescription="@string/close_button_text"
+ android:src="@drawable/decor_close_button_dark"
+ android:scaleType="fitCenter"
+ android:gravity="end"
+ android:background="?android:selectableItemBackgroundBorderless"
+ android:tint="@color/desktop_mode_caption_close_button_dark"/>
+</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
index f9aeb6a..ac13eae 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_decor_handle_menu.xml
@@ -50,7 +50,7 @@
android:layout_marginEnd="10dp"
android:contentDescription="@string/collapse_menu_text"
android:layout_alignParentEnd="true"
- android:background="@drawable/caption_collapse_menu_button"
+ android:background="@drawable/ic_baseline_expand_more_24"
android:layout_centerVertical="true"/>
</RelativeLayout>
<LinearLayout
diff --git a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml b/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
similarity index 67%
rename from libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
rename to libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
index 29cf151..5ab159c 100644
--- a/libs/WindowManager/Shell/res/layout/desktop_mode_window_decor.xml
+++ b/libs/WindowManager/Shell/res/layout/desktop_mode_focused_window_decor.xml
@@ -16,26 +16,21 @@
-->
<com.android.wm.shell.windowdecor.WindowDecorLinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
+ xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/desktop_mode_caption"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:background="@drawable/desktop_mode_decor_title">
- <Button
- style="@style/CaptionButtonStyle"
- android:id="@+id/back_button"
- android:contentDescription="@string/back_button_text"
- android:background="@drawable/decor_back_button_dark"/>
- <Button
+
+ <ImageButton
android:id="@+id/caption_handle"
android:layout_width="128dp"
- android:layout_height="32dp"
- android:layout_margin="5dp"
+ android:layout_height="42dp"
android:contentDescription="@string/handle_text"
- android:background="@drawable/decor_handle_dark"/>
- <Button
- style="@style/CaptionButtonStyle"
- android:id="@+id/close_window"
- android:contentDescription="@string/close_button_text"
- android:background="@drawable/decor_close_button_dark"/>
+ android:src="@drawable/decor_handle_dark"
+ tools:tint="@color/desktop_mode_caption_handle_bar_dark"
+ android:scaleType="fitXY"
+ android:background="?android:selectableItemBackground"/>
+
</com.android.wm.shell.windowdecor.WindowDecorLinearLayout>
\ No newline at end of file
diff --git a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
index 413cfd7..a993469 100644
--- a/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
+++ b/libs/WindowManager/Shell/res/layout/letterbox_education_dialog_layout.xml
@@ -1,5 +1,5 @@
<!--
- ~ Copyright (C) 2022 The Android Open Source Project
+ ~ Copyright (C) 2023 The Android Open Source Project
~
~ Licensed under the Apache License, Version 2.0 (the "License");
~ you may not use this file except in compliance with the License.
@@ -13,7 +13,7 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogLayout
+<com.android.wm.shell.compatui.LetterboxEduDialogLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
style="@style/LetterboxDialog">
@@ -78,13 +78,13 @@
android:orientation="horizontal"
android:paddingTop="48dp">
- <com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout
+ <com.android.wm.shell.compatui.LetterboxEduDialogActionLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
app:icon="@drawable/letterbox_education_ic_reposition"
app:text="@string/letterbox_education_reposition_text"/>
- <com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogActionLayout
+ <com.android.wm.shell.compatui.LetterboxEduDialogActionLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart=
@@ -118,4 +118,4 @@
</FrameLayout>
-</com.android.wm.shell.compatui.letterboxedu.LetterboxEduDialogLayout>
+</com.android.wm.shell.compatui.LetterboxEduDialogLayout>
diff --git a/libs/WindowManager/Shell/res/values-af/strings.xml b/libs/WindowManager/Shell/res/values-af/strings.xml
index 76e9fd5..0897712 100644
--- a/libs/WindowManager/Shell/res/values-af/strings.xml
+++ b/libs/WindowManager/Shell/res/values-af/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Beweeg na regs onder"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-instellings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Maak borrel toe"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Moenie dat gesprek \'n borrel word nie"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Klets met borrels"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nuwe gesprekke verskyn as swerwende ikone, of borrels Tik op borrel om dit oop te maak. Sleep om dit te skuif."</string>
diff --git a/libs/WindowManager/Shell/res/values-am/strings.xml b/libs/WindowManager/Shell/res/values-am/strings.xml
index 969af09..bc58e20 100644
--- a/libs/WindowManager/Shell/res/values-am/strings.xml
+++ b/libs/WindowManager/Shell/res/values-am/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ታችኛውን ቀኝ ያንቀሳቅሱ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"የ<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ቅንብሮች"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"አረፋን አሰናብት"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ውይይቶችን በአረፋ አታሳይ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"አረፋዎችን በመጠቀም ይወያዩ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"አዲስ ውይይቶች እንደ ተንሳፋፊ አዶዎች ወይም አረፋዎች ሆነው ይታያሉ። አረፋን ለመክፈት መታ ያድርጉ። ለመውሰድ ይጎትቱት።"</string>
diff --git a/libs/WindowManager/Shell/res/values-ar/strings.xml b/libs/WindowManager/Shell/res/values-ar/strings.xml
index 94014bc..8fe0fb9 100644
--- a/libs/WindowManager/Shell/res/values-ar/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ar/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"نقل إلى أسفل اليسار"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"إعدادات <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"إغلاق فقاعة المحادثة"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"عدم عرض المحادثة كفقاعة محادثة"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"الدردشة باستخدام فقاعات المحادثات"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"تظهر المحادثات الجديدة كرموز عائمة أو كفقاعات. انقر لفتح فقاعة المحادثة، واسحبها لتحريكها."</string>
diff --git a/libs/WindowManager/Shell/res/values-as/strings.xml b/libs/WindowManager/Shell/res/values-as/strings.xml
index 519b5cd..2aaf924 100644
--- a/libs/WindowManager/Shell/res/values-as/strings.xml
+++ b/libs/WindowManager/Shell/res/values-as/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"তলৰ সোঁফালে নিয়ক"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ছেটিং"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"বাবল অগ্ৰাহ্য কৰক"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"বাৰ্তালাপ বাবল নকৰিব"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bubbles ব্যৱহাৰ কৰি চাট কৰক"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"নতুন বাৰ্তালাপ উপঙি থকা চিহ্নসমূহ অথবা bubbles হিচাপে প্ৰদর্শিত হয়। Bubbles খুলিবলৈ টিপক। এইটো স্থানান্তৰ কৰিবলৈ টানি নিয়ক।"</string>
diff --git a/libs/WindowManager/Shell/res/values-az/strings.xml b/libs/WindowManager/Shell/res/values-az/strings.xml
index 5f7db28..ad6e618 100644
--- a/libs/WindowManager/Shell/res/values-az/strings.xml
+++ b/libs/WindowManager/Shell/res/values-az/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Aşağıya sağa köçürün"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ayarları"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Yumrucuğu ləğv edin"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Söhbəti yumrucuqda göstərmə"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Yumrucuqlardan istifadə edərək söhbət edin"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Yeni söhbətlər üzən nişanlar və ya yumrucuqlar kimi görünür. Yumrucuğu açmaq üçün toxunun. Hərəkət etdirmək üçün sürüşdürün."</string>
diff --git a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
index 0f54e86..1dd09f5 100644
--- a/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-b+sr+Latn/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Premesti dole desno"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Podešavanja za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Odbaci oblačić"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne koristi oblačiće za konverzaciju"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Ćaskajte u oblačićima"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nove konverzacije se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da biste otvorili oblačić. Prevucite da biste ga premestili."</string>
diff --git a/libs/WindowManager/Shell/res/values-be/strings.xml b/libs/WindowManager/Shell/res/values-be/strings.xml
index bf1113d..cda6e39 100644
--- a/libs/WindowManager/Shell/res/values-be/strings.xml
+++ b/libs/WindowManager/Shell/res/values-be/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Перамясціць правей і ніжэй"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Налады \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Адхіліць апавяшчэнне"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не паказваць размову ў выглядзе ўсплывальных апавяшчэнняў"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Усплывальныя апавяшчэнні"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Новыя размовы будуць паказвацца як рухомыя значкі ці ўсплывальныя апавяшчэнні. Націсніце, каб адкрыць усплывальнае апавяшчэнне. Перацягніце яго, каб перамясціць."</string>
diff --git a/libs/WindowManager/Shell/res/values-bg/strings.xml b/libs/WindowManager/Shell/res/values-bg/strings.xml
index 996280e..b5d4eb1 100644
--- a/libs/WindowManager/Shell/res/values-bg/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bg/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Преместване долу вдясно"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Настройки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Отхвърляне на балончетата"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Без балончета за разговора"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Чат с балончета"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Новите разговори се показват като плаващи икони, или балончета. Докоснете балонче, за да го отворите, или го плъзнете, за да го преместите."</string>
diff --git a/libs/WindowManager/Shell/res/values-bn/strings.xml b/libs/WindowManager/Shell/res/values-bn/strings.xml
index 582b9a7..5c95f9e 100644
--- a/libs/WindowManager/Shell/res/values-bn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bn/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"নিচে ডান দিকে সরান"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> সেটিংস"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"বাবল খারিজ করুন"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"কথোপকথন বাবল হিসেবে দেখাবে না"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"বাবল ব্যবহার করে চ্যাট করুন"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"নতুন কথোপকথন ভেসে থাকা আইকন বা বাবল হিসেবে দেখানো হয়। বাবল খুলতে ট্যাপ করুন। সেটি সরাতে ধরে টেনে আনুন।"</string>
diff --git a/libs/WindowManager/Shell/res/values-bs/strings.xml b/libs/WindowManager/Shell/res/values-bs/strings.xml
index 29d4ac4..f9ff29c 100644
--- a/libs/WindowManager/Shell/res/values-bs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-bs/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Pomjerite dolje desno"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Postavke aplikacije <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Odbaci oblačić"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nemoj prikazivati razgovor u oblačićima"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatajte koristeći oblačiće"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novi razgovori se prikazuju kao plutajuće ikone ili oblačići. Dodirnite da otvorite oblačić. Prevucite da ga premjestite."</string>
diff --git a/libs/WindowManager/Shell/res/values-ca/strings.xml b/libs/WindowManager/Shell/res/values-ca/strings.xml
index a55d7b7..b54e60d 100644
--- a/libs/WindowManager/Shell/res/values-ca/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ca/strings.xml
@@ -58,7 +58,7 @@
<string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"Inicia el mode d\'una mà"</string>
<string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"Surt del mode d\'una mà"</string>
<string name="bubbles_settings_button_description" msgid="1301286017420516912">"Configuració de les bombolles: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Menú addicional"</string>
+ <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"Menú de desbordament"</string>
<string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"Torna a afegir a la pila"</string>
<string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> de: <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
<string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> (<xliff:g id="APP_NAME">%2$s</xliff:g>) i <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> més"</string>
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mou a baix a la dreta"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Configuració de l\'aplicació <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ignora la bombolla"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"No mostris la conversa com a bombolla"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Xateja amb bombolles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Les converses noves es mostren com a icones flotants o bombolles. Toca per obrir una bombolla. Arrossega-la per moure-la."</string>
diff --git a/libs/WindowManager/Shell/res/values-cs/strings.xml b/libs/WindowManager/Shell/res/values-cs/strings.xml
index 38f911d..d6e4f9f 100644
--- a/libs/WindowManager/Shell/res/values-cs/strings.xml
+++ b/libs/WindowManager/Shell/res/values-cs/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Přesunout vpravo dolů"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Nastavení <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Zavřít bublinu"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nezobrazovat konverzaci v bublinách"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatujte pomocí bublin"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nové konverzace se zobrazují jako plovoucí ikony, neboli bubliny. Klepnutím bublinu otevřete. Přetažením ji posunete."</string>
diff --git a/libs/WindowManager/Shell/res/values-da/strings.xml b/libs/WindowManager/Shell/res/values-da/strings.xml
index ca15128..da8723f 100644
--- a/libs/WindowManager/Shell/res/values-da/strings.xml
+++ b/libs/WindowManager/Shell/res/values-da/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Flyt ned til højre"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Indstillinger for <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Afvis boble"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Vis ikke samtaler i bobler"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat ved hjælp af bobler"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nye samtaler vises som svævende ikoner eller bobler. Tryk for at åbne boblen. Træk for at flytte den."</string>
diff --git a/libs/WindowManager/Shell/res/values-de/strings.xml b/libs/WindowManager/Shell/res/values-de/strings.xml
index 916fa85..11090e0 100644
--- a/libs/WindowManager/Shell/res/values-de/strings.xml
+++ b/libs/WindowManager/Shell/res/values-de/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Nach unten rechts verschieben"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Einstellungen für <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Bubble schließen"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Unterhaltung nicht als Bubble anzeigen"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bubbles zum Chatten verwenden"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Neue Unterhaltungen erscheinen als unverankerte Symbole, „Bubbles“ genannt. Wenn du eine Bubble öffnen möchtest, tippe sie an. Wenn du sie verschieben möchtest, zieh an ihr."</string>
diff --git a/libs/WindowManager/Shell/res/values-el/strings.xml b/libs/WindowManager/Shell/res/values-el/strings.xml
index 58d19f7..1eca52a 100644
--- a/libs/WindowManager/Shell/res/values-el/strings.xml
+++ b/libs/WindowManager/Shell/res/values-el/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Μετακίνηση κάτω δεξιά"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Ρυθμίσεις <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Παράβλ. για συννεφ."</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Να μην γίνει προβολή της συζήτησης σε συννεφάκια."</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Συζητήστε χρησιμοποιώντας συννεφάκια."</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Οι νέες συζητήσεις εμφανίζονται ως κινούμενα εικονίδια ή συννεφάκια. Πατήστε για να ανοίξετε το συννεφάκι. Σύρετε για να το μετακινήσετε."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
index d5da5c6..8493434 100644
--- a/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rAU/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
index c1f1549..33f5333 100644
--- a/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rCA/strings.xml
@@ -68,6 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Don’t bubble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
index d5da5c6..8493434 100644
--- a/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rGB/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
index d5da5c6..8493434 100644
--- a/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rIN/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
index 5968df5..69823f9 100644
--- a/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
+++ b/libs/WindowManager/Shell/res/values-en-rXC/strings.xml
@@ -68,6 +68,7 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Move bottom right"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> settings"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dismiss bubble"</string>
+ <string name="bubbles_dont_bubble" msgid="3216183855437329223">"Don’t bubble"</string>
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Don’t bubble conversation"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat using bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"New conversations appear as floating icons, or bubbles. Tap to open bubble. Drag to move it."</string>
diff --git a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
index e9b0522..b017591 100644
--- a/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es-rUS/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Ubicar abajo a la derecha"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Descartar burbuja"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"No mostrar la conversación en burbuja"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat con burbujas"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Las conversaciones nuevas aparecen como elementos flotantes o burbujas. Presiona para abrir la burbuja. Arrástrala para moverla."</string>
diff --git a/libs/WindowManager/Shell/res/values-es/strings.xml b/libs/WindowManager/Shell/res/values-es/strings.xml
index 2c32e71..986a2c8 100644
--- a/libs/WindowManager/Shell/res/values-es/strings.xml
+++ b/libs/WindowManager/Shell/res/values-es/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mover abajo a la derecha"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Ajustes de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Cerrar burbuja"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"No mostrar conversación en burbuja"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatea con burbujas"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Las conversaciones nuevas aparecen como iconos flotantes llamados \"burbujas\". Toca una burbuja para abrirla. Arrástrala para moverla."</string>
diff --git a/libs/WindowManager/Shell/res/values-et/strings.xml b/libs/WindowManager/Shell/res/values-et/strings.xml
index 6ba77c3..b84c4f2 100644
--- a/libs/WindowManager/Shell/res/values-et/strings.xml
+++ b/libs/WindowManager/Shell/res/values-et/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Teisalda alla paremale"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Rakenduse <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> seaded"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Sule mull"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ära kuva vestlust mullina"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Vestelge mullide abil"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Uued vestlused kuvatakse hõljuvate ikoonidena ehk mullidena. Puudutage mulli avamiseks. Lohistage mulli, et seda liigutada."</string>
diff --git a/libs/WindowManager/Shell/res/values-eu/strings.xml b/libs/WindowManager/Shell/res/values-eu/strings.xml
index ef11e47..a297219 100644
--- a/libs/WindowManager/Shell/res/values-eu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-eu/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Eraman behealdera, eskuinetara"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> aplikazioaren ezarpenak"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Baztertu burbuila"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ez erakutsi elkarrizketak burbuila gisa"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Txateatu burbuilen bidez"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Elkarrizketa berriak ikono gainerakor edo burbuila gisa agertzen dira. Sakatu burbuila irekitzeko. Arrasta ezazu mugitzeko."</string>
diff --git a/libs/WindowManager/Shell/res/values-fa/strings.xml b/libs/WindowManager/Shell/res/values-fa/strings.xml
index b0cfd32..b379428 100644
--- a/libs/WindowManager/Shell/res/values-fa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fa/strings.xml
@@ -58,7 +58,7 @@
<string name="accessibility_action_start_one_handed" msgid="5070337354072861426">"آغاز «حالت یکدستی»"</string>
<string name="accessibility_action_stop_one_handed" msgid="1369940261782179442">"خروج از «حالت یکدستی»"</string>
<string name="bubbles_settings_button_description" msgid="1301286017420516912">"تنظیمات برای حبابکهای <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
- <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"لبریزشده"</string>
+ <string name="bubble_overflow_button_content_description" msgid="8160974472718594382">"سرریز"</string>
<string name="bubble_accessibility_action_add_back" msgid="1830101076853540953">"افزودن برگشت به پشته"</string>
<string name="bubble_content_description_single" msgid="8495748092720065813">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> از <xliff:g id="APP_NAME">%2$s</xliff:g>"</string>
<string name="bubble_content_description_stack" msgid="8071515017164630429">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> از <xliff:g id="APP_NAME">%2$s</xliff:g> و <xliff:g id="BUBBLE_COUNT">%3$d</xliff:g> مورد بیشتر"</string>
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"انتقال به پایین سمت چپ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"تنظیمات <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"رد کردن حبابک"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"مکالمه در حباب نشان داده نشود"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"گپ بااستفاده از حبابکها"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"مکالمههای جدید بهصورت نمادهای شناور یا حبابکها نشان داده میشوند. برای باز کردن حبابکها ضربه بزنید. برای جابهجایی، آن را بکشید."</string>
diff --git a/libs/WindowManager/Shell/res/values-fi/strings.xml b/libs/WindowManager/Shell/res/values-fi/strings.xml
index 90a196b..14b3556 100644
--- a/libs/WindowManager/Shell/res/values-fi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fi/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Siirrä oikeaan alareunaan"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: asetukset"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ohita kupla"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Älä näytä kuplia keskusteluista"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chattaile kuplien avulla"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Uudet keskustelut näkyvät kelluvina kuvakkeina tai kuplina. Avaa kupla napauttamalla. Siirrä sitä vetämällä."</string>
diff --git a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
index bc82f51..df3e345 100644
--- a/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr-rCA/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Déplacer dans coin inf. droit"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ignorer la bulle"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne pas afficher les conversations dans des bulles"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Clavarder en utilisant des bulles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes (de bulles). Touchez une bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
diff --git a/libs/WindowManager/Shell/res/values-fr/strings.xml b/libs/WindowManager/Shell/res/values-fr/strings.xml
index 61b7fad..7e3eae0 100644
--- a/libs/WindowManager/Shell/res/values-fr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-fr/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Déplacer en bas à droite"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Paramètres <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Fermer la bulle"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne pas afficher la conversation dans une bulle"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatter en utilisant des bulles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Les nouvelles conversations s\'affichent sous forme d\'icônes flottantes ou de bulles. Appuyez sur la bulle pour l\'ouvrir. Faites-la glisser pour la déplacer."</string>
diff --git a/libs/WindowManager/Shell/res/values-gl/strings.xml b/libs/WindowManager/Shell/res/values-gl/strings.xml
index 4825198..a63930d 100644
--- a/libs/WindowManager/Shell/res/values-gl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gl/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mover á parte inferior dereita"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Configuración de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ignorar burbulla"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Non mostrar a conversa como burbulla"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatear usando burbullas"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"As conversas novas aparecen como iconas flotantes ou burbullas. Toca para abrir a burbulla e arrastra para movela."</string>
diff --git a/libs/WindowManager/Shell/res/values-gu/strings.xml b/libs/WindowManager/Shell/res/values-gu/strings.xml
index c1eedf8..f3a3162 100644
--- a/libs/WindowManager/Shell/res/values-gu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-gu/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"નીચે જમણે ખસેડો"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> સેટિંગ"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"બબલને છોડી દો"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"વાતચીતને બબલ કરશો નહીં"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"બબલનો ઉપયોગ કરીને ચૅટ કરો"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"નવી વાતચીત ફ્લોટિંગ આઇકન અથવા બબલ જેવી દેખાશે. બબલને ખોલવા માટે ટૅપ કરો. તેને ખસેડવા માટે ખેંચો."</string>
diff --git a/libs/WindowManager/Shell/res/values-hi/strings.xml b/libs/WindowManager/Shell/res/values-hi/strings.xml
index a12a779..134fb97 100644
--- a/libs/WindowManager/Shell/res/values-hi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hi/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"सबसे नीचे दाईं ओर ले जाएं"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> की सेटिंग"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"बबल खारिज करें"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"बातचीत को बबल न करें"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"बबल्स का इस्तेमाल करके चैट करें"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"नई बातचीत फ़्लोटिंग आइकॉन या बबल्स की तरह दिखेंगी. बबल को खोलने के लिए टैप करें. इसे एक जगह से दूसरी जगह ले जाने के लिए खींचें और छोड़ें."</string>
diff --git a/libs/WindowManager/Shell/res/values-hr/strings.xml b/libs/WindowManager/Shell/res/values-hr/strings.xml
index 3ce055e..f0a8dee 100644
--- a/libs/WindowManager/Shell/res/values-hr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hr/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Premjestite u donji desni kut"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Postavke za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Odbaci oblačić"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Zaustavi razgovor u oblačićima"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Oblačići u chatu"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novi razgovori pojavljuju se kao pomične ikone ili oblačići. Dodirnite za otvaranje oblačića. Povucite da biste ga premjestili."</string>
diff --git a/libs/WindowManager/Shell/res/values-hu/strings.xml b/libs/WindowManager/Shell/res/values-hu/strings.xml
index dc91661..ea43370 100644
--- a/libs/WindowManager/Shell/res/values-hu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hu/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Áthelyezés le és jobbra"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> beállításai"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Buborék elvetése"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ne jelenjen meg a beszélgetés buborékban"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Buborékokat használó csevegés"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Az új beszélgetések lebegő ikonként, vagyis buborékként jelennek meg. A buborék megnyitásához koppintson rá. Áthelyezéshez húzza a kívánt helyre."</string>
diff --git a/libs/WindowManager/Shell/res/values-hy/strings.xml b/libs/WindowManager/Shell/res/values-hy/strings.xml
index 5c58634..4ea668c 100644
--- a/libs/WindowManager/Shell/res/values-hy/strings.xml
+++ b/libs/WindowManager/Shell/res/values-hy/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Տեղափոխել ներքև՝ աջ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – կարգավորումներ"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Փակել ամպիկը"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Զրույցը չցուցադրել ամպիկի տեսքով"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Զրույցի ամպիկներ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Նոր զրույցները կհայտնվեն լողացող պատկերակների կամ ամպիկների տեսքով։ Հպեք՝ ամպիկը բացելու համար։ Քաշեք՝ այն տեղափոխելու համար։"</string>
diff --git a/libs/WindowManager/Shell/res/values-in/strings.xml b/libs/WindowManager/Shell/res/values-in/strings.xml
index c863c70..df2f2df 100644
--- a/libs/WindowManager/Shell/res/values-in/strings.xml
+++ b/libs/WindowManager/Shell/res/values-in/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Pindahkan ke kanan bawah"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Setelan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Tutup balon"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Jangan gunakan percakapan balon"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat dalam tampilan balon"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Percakapan baru muncul sebagai ikon mengambang, atau balon. Ketuk untuk membuka balon. Tarik untuk memindahkannya."</string>
diff --git a/libs/WindowManager/Shell/res/values-is/strings.xml b/libs/WindowManager/Shell/res/values-is/strings.xml
index 9f1936c..a6301b3 100644
--- a/libs/WindowManager/Shell/res/values-is/strings.xml
+++ b/libs/WindowManager/Shell/res/values-is/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Færðu neðst til hægri"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Stillingar <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Loka blöðru"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ekki setja samtal í blöðru"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Spjalla með blöðrum"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Ný samtöl birtast sem fljótandi tákn eða blöðrur. Ýttu til að opna blöðru. Dragðu hana til að færa."</string>
diff --git a/libs/WindowManager/Shell/res/values-it/strings.xml b/libs/WindowManager/Shell/res/values-it/strings.xml
index 2a955d5..3755116 100644
--- a/libs/WindowManager/Shell/res/values-it/strings.xml
+++ b/libs/WindowManager/Shell/res/values-it/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Sposta in basso a destra"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Impostazioni <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ignora bolla"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Non mettere la conversazione nella bolla"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatta utilizzando le bolle"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Le nuove conversazioni vengono mostrate come icone mobili o bolle. Tocca per aprire la bolla. Trascinala per spostarla."</string>
diff --git a/libs/WindowManager/Shell/res/values-iw/strings.xml b/libs/WindowManager/Shell/res/values-iw/strings.xml
index b1e7151..b925970 100644
--- a/libs/WindowManager/Shell/res/values-iw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-iw/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"העברה לפינה הימנית התחתונה"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"הגדרות <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"סגירת בועה"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"אין להציג בועות לשיחה"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"לדבר בבועות"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"שיחות חדשות מופיעות כסמלים צפים, או בועות. יש להקיש כדי לפתוח בועה. יש לגרור כדי להזיז אותה."</string>
diff --git a/libs/WindowManager/Shell/res/values-ja/strings.xml b/libs/WindowManager/Shell/res/values-ja/strings.xml
index a765d8c..b7c30a3 100644
--- a/libs/WindowManager/Shell/res/values-ja/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ja/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"右下に移動"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> の設定"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"バブルを閉じる"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"会話をバブルで表示しない"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"チャットでバブルを使う"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"新しい会話はフローティング アイコン(バブル)として表示されます。タップするとバブルが開きます。ドラッグしてバブルを移動できます。"</string>
diff --git a/libs/WindowManager/Shell/res/values-ka/strings.xml b/libs/WindowManager/Shell/res/values-ka/strings.xml
index 51f0522..e1d1de4 100644
--- a/libs/WindowManager/Shell/res/values-ka/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ka/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"გადაანაცვ. ქვემოთ და მარჯვნივ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-ის პარამეტრები"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ბუშტის დახურვა"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"აიკრძალოს საუბრის ბუშტები"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ჩეთი ბუშტების გამოყენებით"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ახალი საუბრები გამოჩნდება როგორც მოტივტივე ხატულები ან ბუშტები. შეეხეთ ბუშტის გასახსნელად. გადაიტანეთ ჩავლებით."</string>
diff --git a/libs/WindowManager/Shell/res/values-kk/strings.xml b/libs/WindowManager/Shell/res/values-kk/strings.xml
index 4fe2604..de952ad 100644
--- a/libs/WindowManager/Shell/res/values-kk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kk/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Төменгі оң жаққа жылжыту"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> параметрлері"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Қалқымалы хабарды жабу"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Әңгіменің қалқыма хабары көрсетілмесін"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Қалқыма хабарлар арқылы сөйлесу"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Жаңа әңгімелер қалқыма белгішелер немесе хабарлар түрінде көрсетіледі. Қалқыма хабарды ашу үшін түртіңіз. Жылжыту үшін сүйреңіз."</string>
diff --git a/libs/WindowManager/Shell/res/values-km/strings.xml b/libs/WindowManager/Shell/res/values-km/strings.xml
index f590055..762f3a8 100644
--- a/libs/WindowManager/Shell/res/values-km/strings.xml
+++ b/libs/WindowManager/Shell/res/values-km/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ផ្លាស់ទីទៅផ្នែកខាងក្រោមខាងស្ដាំ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"ការកំណត់ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ច្រានចោលពពុះ"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"កុំបង្ហាញការសន្ទនាជាពពុះ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ជជែកដោយប្រើពពុះ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ការសន្ទនាថ្មីៗបង្ហាញជាពពុះ ឬរូបអណ្ដែត។ ចុច ដើម្បីបើកពពុះ។ អូស ដើម្បីផ្លាស់ទីពពុះនេះ។"</string>
diff --git a/libs/WindowManager/Shell/res/values-kn/strings.xml b/libs/WindowManager/Shell/res/values-kn/strings.xml
index 22030eb..f9582ff 100644
--- a/libs/WindowManager/Shell/res/values-kn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-kn/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ಕೆಳಗಿನ ಬಲಭಾಗಕ್ಕೆ ಸರಿಸಿ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ಬಬಲ್ ವಜಾಗೊಳಿಸಿ"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ಸಂಭಾಷಣೆಯನ್ನು ಬಬಲ್ ಮಾಡಬೇಡಿ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ಬಬಲ್ಸ್ ಬಳಸಿ ಚಾಟ್ ಮಾಡಿ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ಹೊಸ ಸಂಭಾಷಣೆಗಳು ತೇಲುವ ಐಕಾನ್ಗಳು ಅಥವಾ ಬಬಲ್ಸ್ ಆಗಿ ಗೋಚರಿಸುತ್ತವೆ. ಬಬಲ್ ತೆರೆಯಲು ಟ್ಯಾಪ್ ಮಾಡಿ. ಅದನ್ನು ಡ್ರ್ಯಾಗ್ ಮಾಡಲು ಎಳೆಯಿರಿ."</string>
diff --git a/libs/WindowManager/Shell/res/values-ko/strings.xml b/libs/WindowManager/Shell/res/values-ko/strings.xml
index 4f4d0c5..2b30aab 100644
--- a/libs/WindowManager/Shell/res/values-ko/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ko/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"오른쪽 하단으로 이동"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> 설정"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"대화창 닫기"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"대화를 대화창으로 표시하지 않기"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"대화창으로 채팅하기"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"새로운 대화가 플로팅 아이콘인 대화창으로 표시됩니다. 대화창을 열려면 탭하세요. 드래그하여 이동할 수 있습니다."</string>
diff --git a/libs/WindowManager/Shell/res/values-ky/strings.xml b/libs/WindowManager/Shell/res/values-ky/strings.xml
index 4305e90..27b89b7 100644
--- a/libs/WindowManager/Shell/res/values-ky/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ky/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Төмөнкү оң жакка жылдыруу"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> параметрлери"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Калкып чыкма билдирмени жабуу"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Жазышууда калкып чыкма билдирмелер көрүнбөсүн"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Калкып чыкма билдирмелер аркылуу маектешүү"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Жаңы жазышуулар калкыма сүрөтчөлөр же калкып чыкма билдирмелер түрүндө көрүнөт. Калкып чыкма билдирмелерди ачуу үчүн таптап коюңуз. Жылдыруу үчүн сүйрөңүз."</string>
diff --git a/libs/WindowManager/Shell/res/values-lo/strings.xml b/libs/WindowManager/Shell/res/values-lo/strings.xml
index 1926b33..6aae84c 100644
--- a/libs/WindowManager/Shell/res/values-lo/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lo/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ຍ້າຍຂວາລຸ່ມ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"ການຕັ້ງຄ່າ <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ປິດຟອງໄວ້"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ຢ່າໃຊ້ຟອງໃນການສົນທະນາ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ສົນທະນາໂດຍໃຊ້ຟອງ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ການສົນທະນາໃໝ່ຈະປາກົດເປັນໄອຄອນ ຫຼື ຟອງແບບລອຍ. ແຕະເພື່ອເປີດຟອງ. ລາກເພື່ອຍ້າຍມັນ."</string>
diff --git a/libs/WindowManager/Shell/res/values-lt/strings.xml b/libs/WindowManager/Shell/res/values-lt/strings.xml
index d3dc1b0..3f2a17b 100644
--- a/libs/WindowManager/Shell/res/values-lt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lt/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Perkelti į apačią dešinėje"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"„<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>“ nustatymai"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Atsisakyti burbulo"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nerodyti pokalbio burbule"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Pokalbis naudojant burbulus"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nauji pokalbiai rodomi kaip slankiosios piktogramos arba burbulai. Palieskite, kad atidarytumėte burbulą. Vilkite, kad perkeltumėte."</string>
diff --git a/libs/WindowManager/Shell/res/values-lv/strings.xml b/libs/WindowManager/Shell/res/values-lv/strings.xml
index 74ec371..ae85c1f 100644
--- a/libs/WindowManager/Shell/res/values-lv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-lv/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Pārvietot apakšpusē pa labi"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Lietotnes <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> iestatījumi"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Nerādīt burbuli"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nerādīt sarunu burbuļos"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Tērzēšana, izmantojot burbuļus"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Jaunas sarunas tiek rādītas kā peldošas ikonas vai burbuļi. Pieskarieties, lai atvērtu burbuli. Velciet, lai to pārvietotu."</string>
diff --git a/libs/WindowManager/Shell/res/values-mk/strings.xml b/libs/WindowManager/Shell/res/values-mk/strings.xml
index a809aa7..133eedb1 100644
--- a/libs/WindowManager/Shell/res/values-mk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mk/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Премести долу десно"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Поставки за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Отфрли балонче"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не прикажувај го разговорот во балончиња"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Разговор во балончиња"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Новите разговори ќе се појавуваат како лебдечки икони или балончиња. Допрете за отворање на балончето. Повлечете за да го преместите."</string>
diff --git a/libs/WindowManager/Shell/res/values-ml/strings.xml b/libs/WindowManager/Shell/res/values-ml/strings.xml
index ffa73b0..c38609e 100644
--- a/libs/WindowManager/Shell/res/values-ml/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ml/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ചുവടെ വലതുഭാഗത്തേക്ക് നീക്കുക"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ക്രമീകരണം"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ബബിൾ ഡിസ്മിസ് ചെയ്യൂ"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"സംഭാഷണം ബബിൾ ചെയ്യരുത്"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ബബിളുകൾ ഉപയോഗിച്ച് ചാറ്റ് ചെയ്യുക"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"പുതിയ സംഭാഷണങ്ങൾ ഫ്ലോട്ടിംഗ് ഐക്കണുകളോ ബബിളുകളോ ആയി ദൃശ്യമാവുന്നു. ബബിൾ തുറക്കാൻ ടാപ്പ് ചെയ്യൂ. ഇത് നീക്കാൻ വലിച്ചിടുക."</string>
diff --git a/libs/WindowManager/Shell/res/values-mn/strings.xml b/libs/WindowManager/Shell/res/values-mn/strings.xml
index 8b15bf9..e0b4141 100644
--- a/libs/WindowManager/Shell/res/values-mn/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mn/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Баруун доош зөөх"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-н тохиргоо"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Бөмбөлгийг хаах"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Харилцан яриаг бүү бөмбөлөг болго"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Бөмбөлөг ашиглан чатлаарай"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Шинэ харилцан яриа нь хөвөгч дүрс тэмдэг эсвэл бөмбөлөг хэлбэрээр харагддаг. Бөмбөлгийг нээхийн тулд товшино уу. Түүнийг зөөхийн тулд чирнэ үү."</string>
diff --git a/libs/WindowManager/Shell/res/values-mr/strings.xml b/libs/WindowManager/Shell/res/values-mr/strings.xml
index 3e30871..f85fe1b 100644
--- a/libs/WindowManager/Shell/res/values-mr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-mr/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"तळाशी उजवीकडे हलवा"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> सेटिंग्ज"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"बबल डिसमिस करा"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"संभाषणाला बबल करू नका"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"बबल वापरून चॅट करा"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"नवीन संभाषणे फ्लोटिंग आयकन किंवा बबल म्हणून दिसतात. बबल उघडण्यासाठी टॅप करा. हे हलवण्यासाठी ड्रॅग करा."</string>
diff --git a/libs/WindowManager/Shell/res/values-ms/strings.xml b/libs/WindowManager/Shell/res/values-ms/strings.xml
index 259930c..6f22599 100644
--- a/libs/WindowManager/Shell/res/values-ms/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ms/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Alihkan ke bawah sebelah kanan"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Tetapan <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ketepikan gelembung"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Jangan jadikan perbualan dalam bentuk gelembung"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bersembang menggunakan gelembung"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Perbualan baharu muncul sebagai ikon terapung atau gelembung. Ketik untuk membuka gelembung. Seret untuk mengalihkan gelembung tersebut."</string>
diff --git a/libs/WindowManager/Shell/res/values-my/strings.xml b/libs/WindowManager/Shell/res/values-my/strings.xml
index 5e5f79a..5a88cd0 100644
--- a/libs/WindowManager/Shell/res/values-my/strings.xml
+++ b/libs/WindowManager/Shell/res/values-my/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ညာအောက်ခြေသို့ ရွှေ့ပါ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ဆက်တင်များ"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ပူဖောင်းကွက် ပယ်ရန်"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"စကားဝိုင်းကို ပူဖောင်းကွက် မပြုလုပ်ပါနှင့်"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ပူဖောင်းကွက် သုံး၍ ချတ်လုပ်ခြင်း"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"စကားဝိုင်းအသစ်များကို မျောနေသည့် သင်္ကေတများ သို့မဟုတ် ပူဖောင်းကွက်များအဖြစ် မြင်ရပါမည်။ ပူဖောင်းကွက်ကိုဖွင့်ရန် တို့ပါ။ ရွှေ့ရန် ၎င်းကို ဖိဆွဲပါ။"</string>
diff --git a/libs/WindowManager/Shell/res/values-nb/strings.xml b/libs/WindowManager/Shell/res/values-nb/strings.xml
index 2c53a7c..da5f4ca 100644
--- a/libs/WindowManager/Shell/res/values-nb/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nb/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Flytt til nederst til høyre"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>-innstillinger"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Lukk boblen"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ikke vis samtaler i bobler"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat med bobler"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nye samtaler vises som flytende ikoner eller bobler. Trykk for å åpne en boble. Dra for å flytte den."</string>
diff --git a/libs/WindowManager/Shell/res/values-ne/strings.xml b/libs/WindowManager/Shell/res/values-ne/strings.xml
index 38dbd15..6b164e9 100644
--- a/libs/WindowManager/Shell/res/values-ne/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ne/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"पुछारमा दायाँतिर सार्नुहोस्"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> का सेटिङहरू"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"बबल खारेज गर्नुहोस्"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"वार्तालाप बबलको रूपमा नदेखाइयोस्"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"बबलहरू प्रयोग गरी कुराकानी गर्नुहोस्"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"नयाँ वार्तालापहरू तैरने आइकन वा बबलका रूपमा देखिन्छन्। बबल खोल्न ट्याप गर्नुहोस्। बबल सार्न सो बबललाई ड्र्याग गर्नुहोस्।"</string>
diff --git a/libs/WindowManager/Shell/res/values-nl/strings.xml b/libs/WindowManager/Shell/res/values-nl/strings.xml
index 9cb7ddc..2d02ed5 100644
--- a/libs/WindowManager/Shell/res/values-nl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-nl/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Naar rechtsonder verplaatsen"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Instellingen voor <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Bubbel sluiten"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Gesprekken niet in bubbels tonen"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatten met bubbels"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nieuwe gesprekken worden als zwevende iconen of bubbels getoond. Tik om een bubbel te openen. Sleep om een bubbel te verplaatsen."</string>
diff --git a/libs/WindowManager/Shell/res/values-or/strings.xml b/libs/WindowManager/Shell/res/values-or/strings.xml
index c3bed0a..6400283 100644
--- a/libs/WindowManager/Shell/res/values-or/strings.xml
+++ b/libs/WindowManager/Shell/res/values-or/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ତଳ ଡାହାଣକୁ ନିଅନ୍ତୁ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ସେଟିଂସ୍"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ବବଲ୍ ଖାରଜ କରନ୍ତୁ"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ବାର୍ତ୍ତାଳାପକୁ ବବଲ୍ କରନ୍ତୁ ନାହିଁ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ବବଲଗୁଡ଼ିକୁ ବ୍ୟବହାର କରି ଚାଟ୍ କରନ୍ତୁ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ନୂଆ ବାର୍ତ୍ତାଳାପଗୁଡ଼ିକ ଫ୍ଲୋଟିଂ ଆଇକନ୍ କିମ୍ବା ବବଲ୍ ଭାବେ ଦେଖାଯିବ। ବବଲ୍ ଖୋଲିବାକୁ ଟାପ୍ କରନ୍ତୁ। ଏହାକୁ ମୁଭ୍ କରିବାକୁ ଟାଣନ୍ତୁ।"</string>
diff --git a/libs/WindowManager/Shell/res/values-pa/strings.xml b/libs/WindowManager/Shell/res/values-pa/strings.xml
index 5a1611d..d39fe95 100644
--- a/libs/WindowManager/Shell/res/values-pa/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pa/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ਹੇਠਾਂ ਵੱਲ ਸੱਜੇ ਲਿਜਾਓ"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ਸੈਟਿੰਗਾਂ"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ਬਬਲ ਨੂੰ ਖਾਰਜ ਕਰੋ"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ਗੱਲਬਾਤ \'ਤੇ ਬਬਲ ਨਾ ਲਾਓ"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"ਬਬਲ ਵਰਤਦੇ ਹੋਏ ਚੈਟ ਕਰੋ"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"ਨਵੀਆਂ ਗੱਲਾਂਬਾਤਾਂ ਫਲੋਟਿੰਗ ਪ੍ਰਤੀਕਾਂ ਜਾਂ ਬਬਲ ਦੇ ਰੂਪ ਵਿੱਚ ਦਿਸਦੀਆਂ ਹਨ। ਬਬਲ ਨੂੰ ਖੋਲ੍ਹਣ ਲਈ ਟੈਪ ਕਰੋ। ਇਸਨੂੰ ਲਿਜਾਣ ਲਈ ਘਸੀਟੋ।"</string>
diff --git a/libs/WindowManager/Shell/res/values-pl/strings.xml b/libs/WindowManager/Shell/res/values-pl/strings.xml
index 9f92538..680bd5d 100644
--- a/libs/WindowManager/Shell/res/values-pl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pl/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Przenieś w prawy dolny róg"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> – ustawienia"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Zamknij dymek"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nie wyświetlaj rozmowy jako dymka"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Czatuj, korzystając z dymków"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nowe rozmowy będą wyświetlane jako pływające ikony lub dymki. Kliknij, by otworzyć dymek. Przeciągnij, by go przenieść."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
index a46493c..c30b6f1 100644
--- a/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rBR/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mover para canto inferior direito"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Configurações de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dispensar balão"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Não criar balões de conversa"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Converse usando balões"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novas conversas aparecerão como ícones flutuantes, ou balões. Toque para abrir o balão. Arraste para movê-lo."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
index 7413a5b..00f4aa0 100644
--- a/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt-rPT/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mover parte inferior direita"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Definições de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ignorar balão"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Não apresentar a conversa em balões"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Converse no chat através de balões"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"As novas conversas aparecem como ícones flutuantes ou balões. Toque para abrir o balão. Arraste para o mover."</string>
diff --git a/libs/WindowManager/Shell/res/values-pt/strings.xml b/libs/WindowManager/Shell/res/values-pt/strings.xml
index a46493c..c30b6f1 100644
--- a/libs/WindowManager/Shell/res/values-pt/strings.xml
+++ b/libs/WindowManager/Shell/res/values-pt/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mover para canto inferior direito"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Configurações de <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Dispensar balão"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Não criar balões de conversa"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Converse usando balões"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novas conversas aparecerão como ícones flutuantes, ou balões. Toque para abrir o balão. Arraste para movê-lo."</string>
diff --git a/libs/WindowManager/Shell/res/values-ro/strings.xml b/libs/WindowManager/Shell/res/values-ro/strings.xml
index 0d30257..4cfb1fa 100644
--- a/libs/WindowManager/Shell/res/values-ro/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ro/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Mută în dreapta jos"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Setări <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Închide balonul"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nu afișa conversația în balon"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chat cu baloane"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Conversațiile noi apar ca pictograme flotante sau baloane. Atinge pentru a deschide balonul. Trage pentru a-l muta."</string>
diff --git a/libs/WindowManager/Shell/res/values-ru/strings.xml b/libs/WindowManager/Shell/res/values-ru/strings.xml
index f632f03..741a5d1 100644
--- a/libs/WindowManager/Shell/res/values-ru/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ru/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Перенести в правый нижний угол"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>: настройки"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Скрыть всплывающий чат"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не показывать всплывающий чат для разговора"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Всплывающие чаты"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Новые разговоры будут появляться в виде плавающих значков, или всплывающих чатов. Чтобы открыть чат, нажмите на него, а чтобы переместить – перетащите."</string>
diff --git a/libs/WindowManager/Shell/res/values-si/strings.xml b/libs/WindowManager/Shell/res/values-si/strings.xml
index 7825432..680f138 100644
--- a/libs/WindowManager/Shell/res/values-si/strings.xml
+++ b/libs/WindowManager/Shell/res/values-si/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"පහළ දකුණට ගෙන යන්න"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> සැකසීම්"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"බුබුලු ඉවත ලන්න"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"සංවාදය බුබුලු නොදමන්න"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"බුබුලු භාවිතයෙන් කතාබහ කරන්න"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"නව සංවාද පාවෙන අයිකන හෝ බුබුලු ලෙස දිස් වේ. බුබුල විවෘත කිරීමට තට්ටු කරන්න. එය ගෙන යාමට අදින්න."</string>
diff --git a/libs/WindowManager/Shell/res/values-sk/strings.xml b/libs/WindowManager/Shell/res/values-sk/strings.xml
index 21641e5..4b89ab1 100644
--- a/libs/WindowManager/Shell/res/values-sk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sk/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Presunúť doprava nadol"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Nastavenia aplikácie <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Zavrieť bublinu"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Nezobrazovať konverzáciu ako bublinu"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Čet pomocou bublín"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nové konverzácie sa zobrazujú ako plávajúce ikony či bubliny. Bublinu otvoríte klepnutím. Premiestnite ju presunutím."</string>
diff --git a/libs/WindowManager/Shell/res/values-sl/strings.xml b/libs/WindowManager/Shell/res/values-sl/strings.xml
index 444a3c8..6eb83ed 100644
--- a/libs/WindowManager/Shell/res/values-sl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sl/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Premakni spodaj desno"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Nastavitve za <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Opusti oblaček"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Pogovora ne prikaži v oblačku"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Klepet z oblački"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Novi pogovori so prikazani kot lebdeče ikone ali oblački. Če želite odpreti oblaček, se ga dotaknite. Če ga želite premakniti, ga povlecite."</string>
diff --git a/libs/WindowManager/Shell/res/values-sq/strings.xml b/libs/WindowManager/Shell/res/values-sq/strings.xml
index 07bc2a3..e804c52 100644
--- a/libs/WindowManager/Shell/res/values-sq/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sq/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Lëvize poshtë djathtas"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Cilësimet e <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Hiqe flluskën"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Mos e vendos bisedën në flluskë"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bisedo duke përdorur flluskat"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Bisedat e reja shfaqen si ikona pluskuese ose flluska. Trokit për të hapur flluskën. Zvarrit për ta zhvendosur."</string>
diff --git a/libs/WindowManager/Shell/res/values-sr/strings.xml b/libs/WindowManager/Shell/res/values-sr/strings.xml
index 4d75626..9aafa87 100644
--- a/libs/WindowManager/Shell/res/values-sr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sr/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Премести доле десно"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Подешавања за <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Одбаци облачић"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не користи облачиће за конверзацију"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Ћаскајте у облачићима"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Нове конверзације се приказују као плутајуће иконе или облачићи. Додирните да бисте отворили облачић. Превуците да бисте га преместили."</string>
diff --git a/libs/WindowManager/Shell/res/values-sv/strings.xml b/libs/WindowManager/Shell/res/values-sv/strings.xml
index 9988e47..6316d52 100644
--- a/libs/WindowManager/Shell/res/values-sv/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sv/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Flytta längst ned till höger"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Inställningar för <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Stäng bubbla"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Visa inte konversationen i bubblor"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Chatta med bubblor"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Nya konversationer visas som flytande ikoner, så kallade bubblor. Tryck på bubblan om du vill öppna den. Dra den om du vill flytta den."</string>
diff --git a/libs/WindowManager/Shell/res/values-sw/strings.xml b/libs/WindowManager/Shell/res/values-sw/strings.xml
index 4937464..46bd638 100644
--- a/libs/WindowManager/Shell/res/values-sw/strings.xml
+++ b/libs/WindowManager/Shell/res/values-sw/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Sogeza chini kulia"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Mipangilio ya <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Ondoa kiputo"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Usiweke viputo kwenye mazungumzo"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Piga gumzo ukitumia viputo"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Mazungumzo mapya huonekena kama aikoni au viputo vinavyoelea. Gusa ili ufungue kiputo. Buruta ili ukisogeze."</string>
diff --git a/libs/WindowManager/Shell/res/values-ta/strings.xml b/libs/WindowManager/Shell/res/values-ta/strings.xml
index edadfb4..10f040b 100644
--- a/libs/WindowManager/Shell/res/values-ta/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ta/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"கீழே வலதுபுறமாக நகர்த்து"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> அமைப்புகள்"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"குமிழை அகற்று"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"உரையாடலைக் குமிழாக்காதே"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"குமிழ்களைப் பயன்படுத்தி அரட்டையடியுங்கள்"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"புதிய உரையாடல்கள் மிதக்கும் ஐகான்களாகவோ குமிழ்களாகவோ தோன்றும். குமிழைத் திறக்க தட்டவும். நகர்த்த இழுக்கவும்."</string>
diff --git a/libs/WindowManager/Shell/res/values-te/strings.xml b/libs/WindowManager/Shell/res/values-te/strings.xml
index 66b2051..512bd52 100644
--- a/libs/WindowManager/Shell/res/values-te/strings.xml
+++ b/libs/WindowManager/Shell/res/values-te/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"దిగవు కుడివైపునకు జరుపు"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> సెట్టింగ్లు"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"బబుల్ను విస్మరించు"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"సంభాషణను బబుల్ చేయవద్దు"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"బబుల్స్ను ఉపయోగించి చాట్ చేయండి"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"కొత్త సంభాషణలు తేలియాడే చిహ్నాలుగా లేదా బబుల్స్ లాగా కనిపిస్తాయి. బబుల్ని తెరవడానికి నొక్కండి. తరలించడానికి లాగండి."</string>
diff --git a/libs/WindowManager/Shell/res/values-th/strings.xml b/libs/WindowManager/Shell/res/values-th/strings.xml
index 67ae9b7..e533869 100644
--- a/libs/WindowManager/Shell/res/values-th/strings.xml
+++ b/libs/WindowManager/Shell/res/values-th/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"ย้ายไปด้านขาวล่าง"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"การตั้งค่า <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"ปิดบับเบิล"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"ไม่ต้องแสดงการสนทนาเป็นบับเบิล"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"แชทโดยใช้บับเบิล"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"การสนทนาใหม่ๆ จะปรากฏเป็นไอคอนแบบลอยหรือบับเบิล แตะเพื่อเปิดบับเบิล ลากเพื่อย้ายที่"</string>
diff --git a/libs/WindowManager/Shell/res/values-tl/strings.xml b/libs/WindowManager/Shell/res/values-tl/strings.xml
index 1275dd6..426e83a 100644
--- a/libs/WindowManager/Shell/res/values-tl/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tl/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Ilipat sa kanan sa ibaba"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Mga setting ng <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"I-dismiss ang bubble"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Huwag ipakita sa bubble ang mga pag-uusap"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Mag-chat gamit ang bubbles"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Lumalabas bilang mga nakalutang na icon o bubble ang mga bagong pag-uusap. I-tap para buksan ang bubble. I-drag para ilipat ito."</string>
diff --git a/libs/WindowManager/Shell/res/values-tr/strings.xml b/libs/WindowManager/Shell/res/values-tr/strings.xml
index 74a457f..969e403 100644
--- a/libs/WindowManager/Shell/res/values-tr/strings.xml
+++ b/libs/WindowManager/Shell/res/values-tr/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Sağ alta taşı"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ayarları"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Baloncuğu kapat"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Görüşmeyi baloncuk olarak görüntüleme"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Baloncukları kullanarak sohbet edin"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Yeni görüşmeler kayan simgeler veya baloncuk olarak görünür. Açmak için baloncuğa dokunun. Baloncuğu taşımak için sürükleyin."</string>
diff --git a/libs/WindowManager/Shell/res/values-uk/strings.xml b/libs/WindowManager/Shell/res/values-uk/strings.xml
index b1e29f4..e265e2f 100644
--- a/libs/WindowManager/Shell/res/values-uk/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uk/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Перемістити праворуч униз"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Налаштування параметра \"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>\""</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Закрити підказку"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Не показувати спливаючі чати для розмов"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Спливаючий чат"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Нові повідомлення чату з\'являються у вигляді спливаючих значків. Щоб відкрити чат, натисніть його, а щоб перемістити – перетягніть."</string>
diff --git a/libs/WindowManager/Shell/res/values-ur/strings.xml b/libs/WindowManager/Shell/res/values-ur/strings.xml
index 88240cb..f4373e6 100644
--- a/libs/WindowManager/Shell/res/values-ur/strings.xml
+++ b/libs/WindowManager/Shell/res/values-ur/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"نیچے دائیں جانب لے جائیں"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> ترتیبات"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"بلبلہ برخاست کریں"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"گفتگو بلبلہ نہ کریں"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"بلبلے کے ذریعے چیٹ کریں"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"نئی گفتگوئیں فلوٹنگ آئیکن یا بلبلے کے طور پر ظاہر ہوں گی۔ بلبلہ کھولنے کے لیے تھپتھپائیں۔ اسے منتقل کرنے کے لیے گھسیٹیں۔"</string>
diff --git a/libs/WindowManager/Shell/res/values-uz/strings.xml b/libs/WindowManager/Shell/res/values-uz/strings.xml
index 38f3a0dd..8c07814 100644
--- a/libs/WindowManager/Shell/res/values-uz/strings.xml
+++ b/libs/WindowManager/Shell/res/values-uz/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Quyi oʻngga surish"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> sozlamalari"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Bulutchani yopish"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Suhbatlar bulutchalar shaklida chiqmasin"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Bulutchalar yordamida subhatlashish"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Yangi xabarlar qalqib chiquvchi belgilar yoki bulutchalar kabi chiqadi. Xabarni ochish uchun bildirishnoma ustiga bosing. Xabarni qayta joylash uchun bildirishnomani suring."</string>
diff --git a/libs/WindowManager/Shell/res/values-vi/strings.xml b/libs/WindowManager/Shell/res/values-vi/strings.xml
index 576bd5b..bbb3639 100644
--- a/libs/WindowManager/Shell/res/values-vi/strings.xml
+++ b/libs/WindowManager/Shell/res/values-vi/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Chuyển tới dưới cùng bên phải"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"Cài đặt <xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Đóng bong bóng"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Dừng sử dụng bong bóng cho cuộc trò chuyện"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Trò chuyện bằng bong bóng trò chuyện"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Các cuộc trò chuyện mới sẽ xuất hiện dưới dạng biểu tượng nổi hoặc bong bóng trò chuyện. Nhấn để mở bong bóng trò chuyện. Kéo để di chuyển bong bóng trò chuyện."</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
index a6c6ac4..caca25a 100644
--- a/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rCN/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"移至右下角"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>设置"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"关闭对话泡"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"不以对话泡形式显示对话"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"使用对话泡聊天"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"新对话会以浮动图标或对话泡形式显示。点按即可打开对话泡。拖动即可移动对话泡。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
index d6df8c1..7a2d348 100644
--- a/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rHK/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"移去右下角"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"「<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>」設定"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"關閉小視窗氣泡"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"不要透過小視窗顯示對話"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"使用小視窗進行即時通訊"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"新對話會以浮動圖示 (小視窗) 顯示。輕按即可開啟小視窗。拖曳即可移動小視窗。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
index 64980c0..b0ccd8a 100644
--- a/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zh-rTW/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"移至右下方"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"「<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g>」設定"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"關閉對話框"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"不要以對話框形式顯示對話"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"透過對話框來聊天"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"新的對話會以浮動圖示或對話框形式顯示。輕觸即可開啟對話框,拖曳則可移動對話框。"</string>
diff --git a/libs/WindowManager/Shell/res/values-zu/strings.xml b/libs/WindowManager/Shell/res/values-zu/strings.xml
index abbec33..7787e77 100644
--- a/libs/WindowManager/Shell/res/values-zu/strings.xml
+++ b/libs/WindowManager/Shell/res/values-zu/strings.xml
@@ -68,6 +68,8 @@
<string name="bubble_accessibility_action_move_bottom_right" msgid="2107626346109206352">"Hambisa inkinobho ngakwesokudla"</string>
<string name="bubbles_app_settings" msgid="3617224938701566416">"<xliff:g id="NOTIFICATION_TITLE">%1$s</xliff:g> izilungiselelo"</string>
<string name="bubble_dismiss_text" msgid="8816558050659478158">"Cashisa ibhamuza"</string>
+ <!-- no translation found for bubbles_dont_bubble (3216183855437329223) -->
+ <skip />
<string name="bubbles_dont_bubble_conversation" msgid="310000317885712693">"Ungayibhamuzi ingxoxo"</string>
<string name="bubbles_user_education_title" msgid="2112319053732691899">"Xoxa usebenzisa amabhamuza"</string>
<string name="bubbles_user_education_description" msgid="4215862563054175407">"Izingxoxo ezintsha zivela njengezithonjana ezintantayo, noma amabhamuza. Thepha ukuze uvule ibhamuza. Hudula ukuze ulihambise."</string>
diff --git a/libs/WindowManager/Shell/res/values/colors.xml b/libs/WindowManager/Shell/res/values/colors.xml
index 6fb70006..2a03b03 100644
--- a/libs/WindowManager/Shell/res/values/colors.xml
+++ b/libs/WindowManager/Shell/res/values/colors.xml
@@ -54,4 +54,14 @@
<color name="splash_screen_bg_light">#FFFFFF</color>
<color name="splash_screen_bg_dark">#000000</color>
<color name="splash_window_background_default">@color/splash_screen_bg_light</color>
+
+ <!-- Desktop Mode -->
+ <color name="desktop_mode_caption_handle_bar_light">#EFF1F2</color>
+ <color name="desktop_mode_caption_handle_bar_dark">#1C1C17</color>
+ <color name="desktop_mode_caption_expand_button_light">#EFF1F2</color>
+ <color name="desktop_mode_caption_expand_button_dark">#48473A</color>
+ <color name="desktop_mode_caption_close_button_light">#EFF1F2</color>
+ <color name="desktop_mode_caption_close_button_dark">#1C1C17</color>
+ <color name="desktop_mode_caption_app_name_light">#EFF1F2</color>
+ <color name="desktop_mode_caption_app_name_dark">#1C1C17</color>
</resources>
diff --git a/libs/WindowManager/Shell/res/values/strings.xml b/libs/WindowManager/Shell/res/values/strings.xml
index 3082962..9f6cf79 100644
--- a/libs/WindowManager/Shell/res/values/strings.xml
+++ b/libs/WindowManager/Shell/res/values/strings.xml
@@ -146,6 +146,8 @@
<string name="bubbles_app_settings"><xliff:g id="notification_title" example="Android Messages">%1$s</xliff:g> settings</string>
<!-- Text used for the bubble dismiss area. Bubbles dragged to, or flung towards, this area will go away. [CHAR LIMIT=30] -->
<string name="bubble_dismiss_text">Dismiss bubble</string>
+ <!-- Button text to stop an app from bubbling [CHAR LIMIT=60]-->
+ <string name="bubbles_dont_bubble">Don\u2019t bubble</string>
<!-- Button text to stop a conversation from bubbling [CHAR LIMIT=60]-->
<string name="bubbles_dont_bubble_conversation">Don\u2019t bubble conversation</string>
<!-- Title text for the bubbles feature education cling shown when a bubble is on screen for the first time. [CHAR LIMIT=60]-->
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
index 22b841a..913239f7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/BackAnimationRunner.java
@@ -75,7 +75,7 @@
};
mWaitingAnimation = false;
try {
- mRunner.onAnimationStart(TRANSIT_OLD_UNSET, apps, wallpapers,
+ getRunner().onAnimationStart(TRANSIT_OLD_UNSET, apps, wallpapers,
nonApps, callback);
} catch (RemoteException e) {
Log.w(TAG, "Failed call onAnimationStart", e);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING
new file mode 100644
index 0000000..837d5ff
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/back/TEST_MAPPING
@@ -0,0 +1,32 @@
+{
+ "presubmit": [
+ {
+ "name": "WMShellUnitTests",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "include-filter": "com.android.wm.shell.back"
+ }
+ ]
+ },
+ {
+ "name": "CtsWindowManagerDeviceTestCases",
+ "options": [
+ {
+ "exclude-annotation": "androidx.test.filters.FlakyTest"
+ },
+ {
+ "include-filter": "android.server.wm.BackGestureInvokedTest"
+ },
+ {
+ "include-filter": "android.server.wm.BackNavigationTests"
+ },
+ {
+ "include-filter": "android.server.wm.OnBackInvokedCallbackGestureTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
index e24c228..85a353f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubble.java
@@ -206,12 +206,14 @@
public Bubble(Intent intent,
UserHandle user,
+ @Nullable Icon icon,
Executor mainExecutor) {
mKey = KEY_APP_BUBBLE;
mGroupKey = null;
mLocusId = null;
mFlags = 0;
mUser = user;
+ mIcon = icon;
mShowBubbleUpdateDot = false;
mMainExecutor = mainExecutor;
mTaskId = INVALID_TASK_ID;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
index ef53839..d2889e7 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleController.java
@@ -57,6 +57,7 @@
import android.content.res.Configuration;
import android.graphics.PixelFormat;
import android.graphics.Rect;
+import android.graphics.drawable.Icon;
import android.os.Binder;
import android.os.Handler;
import android.os.RemoteException;
@@ -1028,19 +1029,22 @@
* the bubble or bubble stack.
*
* Some notes:
- * - Only one app bubble is supported at a time
+ * - Only one app bubble is supported at a time, regardless of users. Multi-users support is
+ * tracked in b/273533235.
* - Calling this method with a different intent than the existing app bubble will do nothing
*
* @param intent the intent to display in the bubble expanded view.
+ * @param user the {@link UserHandle} of the user to start this activity for.
+ * @param icon the {@link Icon} to use for the bubble view.
*/
- public void showOrHideAppBubble(Intent intent) {
+ public void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon) {
if (intent == null || intent.getPackage() == null) {
Log.w(TAG, "App bubble failed to show, invalid intent: " + intent
+ ((intent != null) ? " with package: " + intent.getPackage() : " "));
return;
}
- PackageManager packageManager = getPackageManagerForUser(mContext, mCurrentUserId);
+ PackageManager packageManager = getPackageManagerForUser(mContext, user.getIdentifier());
if (!isResizableActivity(intent, packageManager, KEY_APP_BUBBLE)) return;
Bubble existingAppBubble = mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE);
@@ -1061,7 +1065,7 @@
}
} else {
// App bubble does not exist, lets add and expand it
- Bubble b = new Bubble(intent, UserHandle.of(mCurrentUserId), mMainExecutor);
+ Bubble b = new Bubble(intent, user, icon, mMainExecutor);
b.setShouldAutoExpand(true);
inflateAndAdd(b, /* suppressFlyout= */ true, /* showInShade= */ false);
}
@@ -1869,10 +1873,9 @@
}
@Override
- public void showOrHideAppBubble(Intent intent) {
- mMainExecutor.execute(() -> {
- BubbleController.this.showOrHideAppBubble(intent);
- });
+ public void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon) {
+ mMainExecutor.execute(
+ () -> BubbleController.this.showOrHideAppBubble(intent, user, icon));
}
@Override
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
index ecddbda..9ccd6eb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/BubbleExpandedView.java
@@ -229,6 +229,7 @@
options.setLaunchedFromBubble(true);
options.setPendingIntentBackgroundActivityStartMode(
MODE_BACKGROUND_ACTIVITY_START_ALLOWED);
+ options.setPendingIntentBackgroundActivityLaunchAllowedByPermission(true);
Intent fillInIntent = new Intent();
// Apply flags to make behaviour match documentLaunchMode=always.
@@ -236,12 +237,17 @@
fillInIntent.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK);
if (mBubble.isAppBubble()) {
- PendingIntent pi = PendingIntent.getActivity(mContext, 0,
+ Context context =
+ mContext.createContextAsUser(
+ mBubble.getUser(), Context.CONTEXT_RESTRICTED);
+ PendingIntent pi = PendingIntent.getActivity(
+ context,
+ /* requestCode= */ 0,
mBubble.getAppBubbleIntent()
.addFlags(FLAG_ACTIVITY_NEW_DOCUMENT)
.addFlags(FLAG_ACTIVITY_MULTIPLE_TASK),
PendingIntent.FLAG_IMMUTABLE,
- null);
+ /* options= */ null);
mTaskView.startActivity(pi, /* fillInIntent= */ null, options,
launchBounds);
} else if (!mIsOverflow && mBubble.hasMetadataShortcutId()) {
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 0b947c8..deb4fd5 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
@@ -844,6 +844,8 @@
private DismissView mDismissView;
private ViewGroup mManageMenu;
+ private TextView mManageDontBubbleText;
+ private ViewGroup mManageSettingsView;
private ImageView mManageSettingsIcon;
private TextView mManageSettingsText;
private boolean mShowingManage = false;
@@ -1217,7 +1219,11 @@
mUnbubbleConversationCallback.accept(mBubbleData.getSelectedBubble().getKey());
});
- mManageMenu.findViewById(R.id.bubble_manage_menu_settings_container).setOnClickListener(
+ mManageDontBubbleText = mManageMenu
+ .findViewById(R.id.bubble_manage_menu_dont_bubble_text);
+
+ mManageSettingsView = mManageMenu.findViewById(R.id.bubble_manage_menu_settings_container);
+ mManageSettingsView.setOnClickListener(
view -> {
showManageMenu(false /* show */);
final BubbleViewProvider bubble = mBubbleData.getSelectedBubble();
@@ -2868,10 +2874,19 @@
// name and icon.
if (show) {
final Bubble bubble = mBubbleData.getBubbleInStackWithKey(mExpandedBubble.getKey());
- if (bubble != null) {
+ if (bubble != null && !bubble.isAppBubble()) {
+ // Setup options for non app bubbles
+ mManageDontBubbleText.setText(R.string.bubbles_dont_bubble_conversation);
mManageSettingsIcon.setImageBitmap(bubble.getRawAppBadge());
mManageSettingsText.setText(getResources().getString(
R.string.bubbles_app_settings, bubble.getAppName()));
+ mManageSettingsView.setVisibility(VISIBLE);
+ } else {
+ // Setup options for app bubbles
+ mManageDontBubbleText.setText(R.string.bubbles_dont_bubble);
+ // App bubbles are not notification based
+ // so we don't show the option to go to notification settings
+ mManageSettingsView.setVisibility(GONE);
}
}
@@ -2936,6 +2951,15 @@
}
}
+ /**
+ * Checks whether manage menu notification settings action is available and visible
+ * Used for testing
+ */
+ @VisibleForTesting
+ public boolean isManageMenuSettingsVisible() {
+ return mManageSettingsView != null && mManageSettingsView.getVisibility() == VISIBLE;
+ }
+
private void updateExpandedBubble() {
if (DEBUG_BUBBLE_STACK_VIEW) {
Log.d(TAG, "updateExpandedBubble()");
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
index 4c0a93f..876a720 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/bubbles/Bubbles.java
@@ -26,6 +26,7 @@
import android.app.NotificationChannel;
import android.content.Intent;
import android.content.pm.UserInfo;
+import android.graphics.drawable.Icon;
import android.hardware.HardwareBuffer;
import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
@@ -129,12 +130,15 @@
* the bubble or bubble stack.
*
* Some notes:
- * - Only one app bubble is supported at a time
+ * - Only one app bubble is supported at a time, regardless of users. Multi-users support is
+ * tracked in b/273533235.
* - Calling this method with a different intent than the existing app bubble will do nothing
*
* @param intent the intent to display in the bubble expanded view.
+ * @param user the {@link UserHandle} of the user to start this activity for.
+ * @param icon the {@link Icon} to use for the bubble view.
*/
- void showOrHideAppBubble(Intent intent);
+ void showOrHideAppBubble(Intent intent, UserHandle user, @Nullable Icon icon);
/** @return true if the specified {@code taskId} corresponds to app bubble's taskId. */
boolean isAppBubbleTaskId(int taskId);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
index 76d9152..6950f24 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIController.java
@@ -42,7 +42,6 @@
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIWindowManager.CompatUIHintsState;
-import com.android.wm.shell.compatui.letterboxedu.LetterboxEduWindowManager;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
index fe95d04..170c0ee 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/CompatUIWindowManager.java
@@ -38,7 +38,6 @@
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.compatui.CompatUIController.CompatUICallback;
-import com.android.wm.shell.compatui.letterboxedu.LetterboxEduWindowManager;
import java.util.function.Consumer;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduDialogActionLayout.java
similarity index 95%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduDialogActionLayout.java
index 02197f6..9974295 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogActionLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduDialogActionLayout.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.compatui.letterboxedu;
+package com.android.wm.shell.compatui;
import android.content.Context;
import android.content.res.TypedArray;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduDialogLayout.java
similarity index 94%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduDialogLayout.java
index 9232f36..df2f6ce 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayout.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduDialogLayout.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.compatui.letterboxedu;
+package com.android.wm.shell.compatui;
import android.annotation.Nullable;
import android.content.Context;
@@ -26,7 +26,6 @@
import androidx.constraintlayout.widget.ConstraintLayout;
import com.android.wm.shell.R;
-import com.android.wm.shell.compatui.DialogContainerSupplier;
/**
* Container for Letterbox Education Dialog and background dim.
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
similarity index 97%
rename from libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
rename to libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
index c14c009..bfdbfe3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManager.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/compatui/LetterboxEduWindowManager.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.compatui.letterboxedu;
+package com.android.wm.shell.compatui;
import static android.provider.Settings.Secure.LAUNCHER_TASKBAR_EDUCATION_SHOWING;
@@ -36,8 +36,6 @@
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.compatui.CompatUIWindowManagerAbstract;
-import com.android.wm.shell.compatui.DialogAnimationController;
import com.android.wm.shell.transition.Transitions;
/**
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
index 3d5230d..57b5b8f 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellBaseModule.java
@@ -82,6 +82,7 @@
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.recents.RecentTasks;
import com.android.wm.shell.recents.RecentTasksController;
+import com.android.wm.shell.recents.RecentsTransitionHandler;
import com.android.wm.shell.splitscreen.SplitScreen;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.startingsurface.StartingSurface;
@@ -520,6 +521,9 @@
desktopModeTaskRepository, mainExecutor));
}
+ @BindsOptionalOf
+ abstract RecentsTransitionHandler optionalRecentsTransitionHandler();
+
//
// Shell transitions
//
@@ -803,6 +807,7 @@
Optional<UnfoldTransitionHandler> unfoldTransitionHandler,
Optional<FreeformComponents> freeformComponents,
Optional<RecentTasksController> recentTasksOptional,
+ Optional<RecentsTransitionHandler> recentsTransitionHandlerOptional,
Optional<OneHandedController> oneHandedControllerOptional,
Optional<HideDisplayCutoutController> hideDisplayCutoutControllerOptional,
Optional<ActivityEmbeddingController> activityEmbeddingOptional,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
index 7a83d10..cc0da28 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/dagger/WMShellModule.java
@@ -83,6 +83,7 @@
import com.android.wm.shell.pip.phone.PipSizeSpecHandler;
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.recents.RecentTasksController;
+import com.android.wm.shell.recents.RecentsTransitionHandler;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -528,9 +529,20 @@
ShellInit shellInit,
Optional<SplitScreenController> splitScreenOptional,
Optional<PipTouchHandler> pipTouchHandlerOptional,
+ Optional<RecentsTransitionHandler> recentsTransitionHandler,
Transitions transitions) {
return new DefaultMixedHandler(shellInit, transitions, splitScreenOptional,
- pipTouchHandlerOptional);
+ pipTouchHandlerOptional, recentsTransitionHandler);
+ }
+
+ @WMSingleton
+ @Provides
+ static RecentsTransitionHandler provideRecentsTransitionHandler(
+ ShellInit shellInit,
+ Transitions transitions,
+ Optional<RecentTasksController> recentTasksController) {
+ return new RecentsTransitionHandler(shellInit, transitions,
+ recentTasksController.orElse(null));
}
//
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
index 2d84d21..318a49a 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizer.java
@@ -21,6 +21,8 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_UNDEFINED;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_LANDSCAPE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_REVERSE_LANDSCAPE;
import static android.view.Display.DEFAULT_DISPLAY;
import android.app.ActivityManager;
@@ -33,6 +35,7 @@
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
+import android.view.Display;
import android.view.InsetsSource;
import android.view.InsetsState;
import android.view.SurfaceControl;
@@ -44,6 +47,7 @@
import androidx.annotation.NonNull;
+import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
import com.android.wm.shell.ShellTaskOrganizer;
import com.android.wm.shell.common.DisplayController;
@@ -80,6 +84,12 @@
private final DisplayController mDisplayController;
private final DisplayInsetsController mDisplayInsetsController;
+ /**
+ * The value of the {@link R.bool.config_reverseDefaultRotation} property which defines how
+ * {@link Display#getRotation} values are mapped to screen orientations
+ */
+ private final boolean mReverseDefaultRotationEnabled;
+
@VisibleForTesting
ActivityManager.RunningTaskInfo mLaunchRootTask;
@VisibleForTesting
@@ -188,6 +198,8 @@
mDisplayInsetsController = displayInsetsController;
mKidsModeSettingsObserver = kidsModeSettingsObserver;
shellInit.addInitCallback(this::onInit, this);
+ mReverseDefaultRotationEnabled = context.getResources().getBoolean(
+ R.bool.config_reverseDefaultRotation);
}
public KidsModeTaskOrganizer(
@@ -211,6 +223,8 @@
mDisplayController = displayController;
mDisplayInsetsController = displayInsetsController;
shellInit.addInitCallback(this::onInit, this);
+ mReverseDefaultRotationEnabled = context.getResources().getBoolean(
+ R.bool.config_reverseDefaultRotation);
}
/**
@@ -294,7 +308,14 @@
// Needed since many Kids apps aren't optimised to support both orientations and it will be
// hard for kids to understand the app compat mode.
// TODO(229961548): Remove ignoreOrientationRequest exception for Kids Mode once possible.
- setIsIgnoreOrientationRequestDisabled(true);
+ if (mReverseDefaultRotationEnabled) {
+ setOrientationRequestPolicy(/* isIgnoreOrientationRequestDisabled */ true,
+ /* fromOrientations */ new int[]{SCREEN_ORIENTATION_REVERSE_LANDSCAPE},
+ /* toOrientations */ new int[]{SCREEN_ORIENTATION_LANDSCAPE});
+ } else {
+ setOrientationRequestPolicy(/* isIgnoreOrientationRequestDisabled */ true,
+ /* fromOrientations */ null, /* toOrientations */ null);
+ }
final DisplayLayout displayLayout = mDisplayController.getDisplayLayout(DEFAULT_DISPLAY);
if (displayLayout != null) {
mDisplayWidth = displayLayout.width();
@@ -315,7 +336,8 @@
@VisibleForTesting
void disable() {
- setIsIgnoreOrientationRequestDisabled(false);
+ setOrientationRequestPolicy(/* isIgnoreOrientationRequestDisabled */ false,
+ /* fromOrientations */ null, /* toOrientations */ null);
mDisplayInsetsController.removeInsetsChangedListener(DEFAULT_DISPLAY,
mOnInsetsChangedListener);
mDisplayController.removeDisplayWindowListener(mOnDisplaysChangedListener);
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
index d961d86..78de5f3 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/IPip.aidl
@@ -75,4 +75,9 @@
* Sets the height and visibility of the Launcher keep clear area.
*/
oneway void setLauncherKeepClearAreaHeight(boolean visible, int height) = 6;
+
+ /**
+ * Sets the app icon size in pixel used by Launcher
+ */
+ oneway void setLauncherAppIconSize(int iconSizePx) = 7;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
index fe8ede6..1187126 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipAnimationController.java
@@ -371,10 +371,11 @@
new PipContentOverlay.PipSnapshotOverlay(snapshot, sourceRectHint));
}
- void setAppIconContentOverlay(Context context, Rect bounds, ActivityInfo activityInfo) {
+ void setAppIconContentOverlay(Context context, Rect bounds, ActivityInfo activityInfo,
+ int appIconSizePx) {
reattachContentOverlay(
new PipContentOverlay.PipAppIconOverlay(context, bounds,
- () -> new IconProvider(context).getIcon(activityInfo)));
+ new IconProvider(context).getIcon(activityInfo), appIconSizePx));
}
private void reattachContentOverlay(PipContentOverlay overlay) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
index f08742d..9a775df 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipBoundsState.java
@@ -86,6 +86,7 @@
private int mStashedState = STASH_TYPE_NONE;
private int mStashOffset;
private @Nullable PipReentryState mPipReentryState;
+ private final LauncherState mLauncherState = new LauncherState();
private final @Nullable PipSizeSpecHandler mPipSizeSpecHandler;
private @Nullable ComponentName mLastPipComponentName;
private final @NonNull MotionBoundsState mMotionBoundsState = new MotionBoundsState();
@@ -482,6 +483,10 @@
mOnPipExclusionBoundsChangeCallbacks.remove(onPipExclusionBoundsChangeCallback);
}
+ public LauncherState getLauncherState() {
+ return mLauncherState;
+ }
+
/** Source of truth for the current bounds of PIP that may be in motion. */
public static class MotionBoundsState {
/** The bounds used when PIP is in motion (e.g. during a drag or animation) */
@@ -534,6 +539,25 @@
}
}
+ /** Data class for Launcher state. */
+ public static final class LauncherState {
+ private int mAppIconSizePx;
+
+ public void setAppIconSizePx(int appIconSizePx) {
+ mAppIconSizePx = appIconSizePx;
+ }
+
+ public int getAppIconSizePx() {
+ return mAppIconSizePx;
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ final String innerPrefix = prefix + " ";
+ pw.println(prefix + LauncherState.class.getSimpleName());
+ pw.println(innerPrefix + "getAppIconSizePx=" + getAppIconSizePx());
+ }
+ }
+
static final class PipReentryState {
private static final String TAG = PipReentryState.class.getSimpleName();
@@ -587,6 +611,7 @@
} else {
mPipReentryState.dump(pw, innerPrefix);
}
+ mLauncherState.dump(pw, innerPrefix);
mMotionBoundsState.dump(pw, innerPrefix);
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java
index d228dfb..9fa57ca 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipContentOverlay.java
@@ -32,8 +32,6 @@
import android.view.SurfaceSession;
import android.window.TaskSnapshot;
-import java.util.function.Supplier;
-
/**
* Represents the content overlay used during the entering PiP animation.
*/
@@ -176,9 +174,8 @@
/** A {@link PipContentOverlay} shows app icon on solid color background. */
public static final class PipAppIconOverlay extends PipContentOverlay {
private static final String TAG = PipAppIconOverlay.class.getSimpleName();
- // Align with the practical / reasonable launcher:iconImageSize as in
- // vendor/unbundled_google/packages/NexusLauncher/res/xml/device_profiles.xml
- private static final int APP_ICON_SIZE_DP = 66;
+ // The maximum size for app icon in pixel.
+ private static final int MAX_APP_ICON_SIZE_DP = 72;
private final Context mContext;
private final int mAppIconSizePx;
@@ -188,14 +185,16 @@
private Bitmap mBitmap;
- public PipAppIconOverlay(Context context, Rect appBounds, Supplier<Drawable> iconSupplier) {
+ public PipAppIconOverlay(Context context, Rect appBounds,
+ Drawable appIcon, int appIconSizePx) {
mContext = context;
- mAppIconSizePx = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, APP_ICON_SIZE_DP,
- context.getResources().getDisplayMetrics());
+ final int maxAppIconSizePx = (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP,
+ MAX_APP_ICON_SIZE_DP, context.getResources().getDisplayMetrics());
+ mAppIconSizePx = Math.min(maxAppIconSizePx, appIconSizePx);
mAppBounds = new Rect(appBounds);
mBitmap = Bitmap.createBitmap(appBounds.width(), appBounds.height(),
Bitmap.Config.ARGB_8888);
- prepareAppIconOverlay(iconSupplier);
+ prepareAppIconOverlay(appIcon);
mLeash = new SurfaceControl.Builder(new SurfaceSession())
.setCallsite(TAG)
.setName(LAYER_NAME)
@@ -238,7 +237,7 @@
}
}
- private void prepareAppIconOverlay(Supplier<Drawable> iconSupplier) {
+ private void prepareAppIconOverlay(Drawable appIcon) {
final Canvas canvas = new Canvas();
canvas.setBitmap(mBitmap);
final TypedArray ta = mContext.obtainStyledAttributes(new int[] {
@@ -252,7 +251,6 @@
} finally {
ta.recycle();
}
- final Drawable appIcon = iconSupplier.get();
final Rect appIconBounds = new Rect(
mAppBounds.centerX() - mAppIconSizePx / 2,
mAppBounds.centerY() - mAppIconSizePx / 2,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
index d5b9c5e..c19d543 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTaskOrganizer.java
@@ -16,6 +16,7 @@
package com.android.wm.shell.pip;
+import static android.app.ActivityTaskManager.INVALID_TASK_ID;
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.app.WindowConfiguration.WINDOWING_MODE_PINNED;
import static android.app.WindowConfiguration.WINDOWING_MODE_UNDEFINED;
@@ -536,6 +537,15 @@
mPipTransitionController.startExitTransition(TRANSIT_EXIT_PIP, wct, destinationBounds);
return;
}
+ if (mSplitScreenOptional.isPresent()) {
+ // If pip activity will reparent to origin task case and if the origin task still under
+ // split root, just exit split screen here to ensure it could expand to fullscreen.
+ SplitScreenController split = mSplitScreenOptional.get();
+ if (split.isTaskInSplitScreen(mTaskInfo.lastParentTaskIdBeforePip)) {
+ split.exitSplitScreen(INVALID_TASK_ID,
+ SplitScreenController.EXIT_REASON_APP_FINISHED);
+ }
+ }
mSyncTransactionQueue.queue(wct);
mSyncTransactionQueue.runInSync(t -> {
// Make sure to grab the latest source hint rect as it could have been
@@ -1479,9 +1489,13 @@
applyFinishBoundsResize(wct, direction, false);
}
} else {
- final boolean isPipTopLeft =
- direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN && isPipToTopLeft();
- applyFinishBoundsResize(wct, direction, isPipTopLeft);
+ applyFinishBoundsResize(wct, direction, isPipToTopLeft());
+ // Use sync transaction to apply finish transaction for enter split case.
+ if (direction == TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
+ mSyncTransactionQueue.runInSync(t -> {
+ t.merge(tx);
+ });
+ }
}
finishResizeForMenu(destinationBounds);
@@ -1518,7 +1532,10 @@
mSurfaceTransactionHelper.round(tx, mLeash, isInPip());
wct.setBounds(mToken, taskBounds);
- wct.setBoundsChangeTransaction(mToken, tx);
+ // Pip to split should use sync transaction to sync split bounds change.
+ if (direction != TRANSITION_DIRECTION_LEAVE_PIP_TO_SPLIT_SCREEN) {
+ wct.setBoundsChangeTransaction(mToken, tx);
+ }
}
/**
@@ -1608,7 +1625,8 @@
if (SystemProperties.getBoolean(
"persist.wm.debug.enable_pip_app_icon_overlay", true)) {
animator.setAppIconContentOverlay(
- mContext, currentBounds, mTaskInfo.topActivityInfo);
+ mContext, currentBounds, mTaskInfo.topActivityInfo,
+ mPipBoundsState.getLauncherState().getAppIconSizePx());
} else {
animator.setColorContentOverlay(mContext);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
index 45bb73b..49a27c5 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/PipTransition.java
@@ -808,7 +808,8 @@
"persist.wm.debug.enable_pip_app_icon_overlay", true)
&& hasTopActivityInfo) {
animator.setAppIconContentOverlay(
- mContext, currentBounds, taskInfo.topActivityInfo);
+ mContext, currentBounds, taskInfo.topActivityInfo,
+ mPipBoundsState.getLauncherState().getAppIconSizePx());
} else {
animator.setColorContentOverlay(mContext);
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
index be9b529..748f4a19 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipController.java
@@ -104,7 +104,6 @@
import com.android.wm.shell.transition.Transitions;
import java.io.PrintWriter;
-import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
@@ -119,11 +118,13 @@
UserChangeListener {
private static final String TAG = "PipController";
+ private static final String LAUNCHER_KEEP_CLEAR_AREA_TAG = "hotseat";
+
private static final long PIP_KEEP_CLEAR_AREAS_DELAY =
SystemProperties.getLong("persist.wm.debug.pip_keep_clear_areas_delay", 200);
private boolean mEnablePipKeepClearAlgorithm =
- SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", false);
+ SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", true);
@VisibleForTesting
void setEnablePipKeepClearAlgorithm(boolean value) {
@@ -192,7 +193,7 @@
Rect destBounds = mPipKeepClearAlgorithm.adjust(mPipBoundsState,
mPipBoundsAlgorithm);
// only move if the bounds are actually different
- if (destBounds != mPipBoundsState.getBounds()) {
+ if (!destBounds.equals(mPipBoundsState.getBounds())) {
if (mPipTransitionState.hasEnteredPip()) {
// if already in PiP, schedule separate animation
mPipTaskOrganizer.scheduleAnimateResizePip(destBounds,
@@ -934,15 +935,17 @@
0, mPipBoundsState.getDisplayBounds().bottom - height,
mPipBoundsState.getDisplayBounds().right,
mPipBoundsState.getDisplayBounds().bottom);
- Set<Rect> restrictedKeepClearAreas = new HashSet<>(
- mPipBoundsState.getRestrictedKeepClearAreas());
- restrictedKeepClearAreas.add(rect);
- mPipBoundsState.setKeepClearAreas(restrictedKeepClearAreas,
- mPipBoundsState.getUnrestrictedKeepClearAreas());
+ mPipBoundsState.addNamedUnrestrictedKeepClearArea(LAUNCHER_KEEP_CLEAR_AREA_TAG, rect);
updatePipPositionForKeepClearAreas();
+ } else {
+ mPipBoundsState.removeNamedUnrestrictedKeepClearArea(LAUNCHER_KEEP_CLEAR_AREA_TAG);
}
}
+ private void setLauncherAppIconSize(int iconSizePx) {
+ mPipBoundsState.getLauncherState().setAppIconSizePx(iconSizePx);
+ }
+
private void setOnIsInPipStateChangedListener(Consumer<Boolean> callback) {
mOnIsInPipStateChangedListener = callback;
if (mOnIsInPipStateChangedListener != null) {
@@ -1287,26 +1290,26 @@
overlay.setUnreleasedWarningCallSite("PipController.stopSwipePipToHome");
}
executeRemoteCallWithTaskPermission(mController, "stopSwipePipToHome",
- (controller) -> {
- controller.stopSwipePipToHome(taskId, componentName, destinationBounds,
- overlay);
- });
+ (controller) -> controller.stopSwipePipToHome(
+ taskId, componentName, destinationBounds, overlay));
}
@Override
public void setShelfHeight(boolean visible, int height) {
executeRemoteCallWithTaskPermission(mController, "setShelfHeight",
- (controller) -> {
- controller.setShelfHeight(visible, height);
- });
+ (controller) -> controller.setShelfHeight(visible, height));
}
@Override
public void setLauncherKeepClearAreaHeight(boolean visible, int height) {
executeRemoteCallWithTaskPermission(mController, "setLauncherKeepClearAreaHeight",
- (controller) -> {
- controller.setLauncherKeepClearAreaHeight(visible, height);
- });
+ (controller) -> controller.setLauncherKeepClearAreaHeight(visible, height));
+ }
+
+ @Override
+ public void setLauncherAppIconSize(int iconSizePx) {
+ executeRemoteCallWithTaskPermission(mController, "setLauncherAppIconSize",
+ (controller) -> controller.setLauncherAppIconSize(iconSizePx));
}
@Override
@@ -1324,9 +1327,7 @@
@Override
public void setPipAnimationTypeToAlpha() {
executeRemoteCallWithTaskPermission(mController, "setPipAnimationTypeToAlpha",
- (controller) -> {
- controller.setPinnedStackAnimationType(ANIM_TYPE_ALPHA);
- });
+ (controller) -> controller.setPinnedStackAnimationType(ANIM_TYPE_ALPHA));
}
}
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
index 979b7c7..167c032 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipMenuView.java
@@ -282,7 +282,8 @@
public void onFocusTaskChanged(ActivityManager.RunningTaskInfo taskInfo) {
final boolean isSplitScreen = mSplitScreenControllerOptional.isPresent()
- && mSplitScreenControllerOptional.get().isTaskInSplitScreen(taskInfo.taskId);
+ && mSplitScreenControllerOptional.get().isTaskInSplitScreenForeground(
+ taskInfo.taskId);
mFocusedTaskAllowSplitScreen = isSplitScreen
|| (taskInfo.getWindowingMode() == WINDOWING_MODE_FULLSCREEN
&& taskInfo.supportsMultiWindow
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
index 0e8d13d..466da0e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/pip/phone/PipTouchHandler.java
@@ -71,8 +71,13 @@
private static final String TAG = "PipTouchHandler";
private static final float DEFAULT_STASH_VELOCITY_THRESHOLD = 18000.f;
- private static final boolean ENABLE_PIP_KEEP_CLEAR_ALGORITHM =
- SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", false);
+ private boolean mEnablePipKeepClearAlgorithm =
+ SystemProperties.getBoolean("persist.wm.debug.enable_pip_keep_clear_algorithm", true);
+
+ @VisibleForTesting
+ void setEnablePipKeepClearAlgorithm(boolean value) {
+ mEnablePipKeepClearAlgorithm = value;
+ }
// Allow PIP to resize to a slightly bigger state upon touch
private boolean mEnableResize;
@@ -427,7 +432,7 @@
if (mTouchState.isUserInteracting() && mTouchState.isDragging()) {
// Defer the update of the current movement bounds until after the user finishes
// touching the screen
- } else if (ENABLE_PIP_KEEP_CLEAR_ALGORITHM) {
+ } else if (mEnablePipKeepClearAlgorithm) {
// Ignore moving PiP if keep clear algorithm is enabled, since IME and shelf height
// now are accounted for in the keep clear algorithm calculations
} else {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
index 1a6c1d6..4048c5b 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/IRecentTasks.aidl
@@ -17,6 +17,11 @@
package com.android.wm.shell.recents;
import android.app.ActivityManager.RunningTaskInfo;
+import android.app.IApplicationThread;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.os.Bundle;
+import android.view.IRecentsAnimationRunner;
import com.android.wm.shell.recents.IRecentTasksListener;
import com.android.wm.shell.util.GroupedRecentTaskInfo;
@@ -45,4 +50,10 @@
* Gets the set of running tasks.
*/
RunningTaskInfo[] getRunningTasks(int maxNum) = 4;
+
+ /**
+ * Starts a recents transition.
+ */
+ oneway void startRecentsTransition(in PendingIntent intent, in Intent fillIn, in Bundle options,
+ IApplicationThread appThread, IRecentsAnimationRunner listener) = 5;
}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
index 0d9faa3..c5bfd87 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentTasksController.java
@@ -24,13 +24,18 @@
import android.app.ActivityManager;
import android.app.ActivityTaskManager;
+import android.app.IApplicationThread;
+import android.app.PendingIntent;
import android.app.TaskInfo;
import android.content.ComponentName;
import android.content.Context;
+import android.content.Intent;
+import android.os.Bundle;
import android.os.RemoteException;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
+import android.view.IRecentsAnimationRunner;
import androidx.annotation.BinderThread;
import androidx.annotation.NonNull;
@@ -79,6 +84,7 @@
private final TaskStackListenerImpl mTaskStackListener;
private final RecentTasksImpl mImpl = new RecentTasksImpl();
private final ActivityTaskManager mActivityTaskManager;
+ private RecentsTransitionHandler mTransitionHandler = null;
private IRecentTasksListener mListener;
private final boolean mIsDesktopMode;
@@ -150,6 +156,10 @@
mDesktopModeTaskRepository.ifPresent(it -> it.addActiveTaskListener(this));
}
+ void setTransitionHandler(RecentsTransitionHandler handler) {
+ mTransitionHandler = handler;
+ }
+
/**
* Adds a split pair. This call does not validate the taskIds, only that they are not the same.
*/
@@ -492,5 +502,18 @@
true /* blocking */);
return tasks[0];
}
+
+ @Override
+ public void startRecentsTransition(PendingIntent intent, Intent fillIn, Bundle options,
+ IApplicationThread appThread, IRecentsAnimationRunner listener) {
+ if (mController.mTransitionHandler == null) {
+ Slog.e(TAG, "Used shell-transitions startRecentsTransition without"
+ + " shell-transitions");
+ return;
+ }
+ executeRemoteCallWithTaskPermission(mController, "startRecentsTransition",
+ (controller) -> controller.mTransitionHandler.startRecentsTransition(
+ intent, fillIn, options, appThread, listener));
+ }
}
-}
\ No newline at end of file
+}
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
new file mode 100644
index 0000000..2ec64b0
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/recents/RecentsTransitionHandler.java
@@ -0,0 +1,760 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.wm.shell.recents;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.view.WindowManager.TRANSIT_CHANGE;
+import static android.view.WindowManager.TRANSIT_FLAG_KEYGUARD_LOCKED;
+import static android.view.WindowManager.TRANSIT_SLEEP;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+
+import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.ActivityManager;
+import android.app.ActivityTaskManager;
+import android.app.IApplicationThread;
+import android.app.PendingIntent;
+import android.content.Intent;
+import android.graphics.Rect;
+import android.os.Bundle;
+import android.os.IBinder;
+import android.os.RemoteException;
+import android.util.ArrayMap;
+import android.util.Slog;
+import android.view.IRecentsAnimationController;
+import android.view.IRecentsAnimationRunner;
+import android.view.RemoteAnimationTarget;
+import android.view.SurfaceControl;
+import android.window.PictureInPictureSurfaceTransaction;
+import android.window.TaskSnapshot;
+import android.window.TransitionInfo;
+import android.window.TransitionRequestInfo;
+import android.window.WindowContainerToken;
+import android.window.WindowContainerTransaction;
+
+import com.android.wm.shell.common.ShellExecutor;
+import com.android.wm.shell.sysui.ShellInit;
+import com.android.wm.shell.transition.Transitions;
+import com.android.wm.shell.util.TransitionUtil;
+
+import java.util.ArrayList;
+
+/**
+ * Handles the Recents (overview) animation. Only one of these can run at a time. A recents
+ * transition must be created via {@link #startRecentsTransition}. Anything else will be ignored.
+ */
+public class RecentsTransitionHandler implements Transitions.TransitionHandler {
+ private static final String TAG = "RecentsTransitionHandler";
+
+ private final Transitions mTransitions;
+ private final ShellExecutor mExecutor;
+ private IApplicationThread mAnimApp = null;
+ private final ArrayList<RecentsController> mControllers = new ArrayList<>();
+
+ /**
+ * List of other handlers which might need to mix recents with other things. These are checked
+ * in the order they are added. Ideally there should only be one.
+ */
+ private final ArrayList<RecentsMixedHandler> mMixers = new ArrayList<>();
+
+ public RecentsTransitionHandler(ShellInit shellInit, Transitions transitions,
+ @Nullable RecentTasksController recentTasksController) {
+ mTransitions = transitions;
+ mExecutor = transitions.getMainExecutor();
+ if (!Transitions.ENABLE_SHELL_TRANSITIONS) return;
+ if (recentTasksController == null) return;
+ shellInit.addInitCallback(() -> {
+ recentTasksController.setTransitionHandler(this);
+ transitions.addHandler(this);
+ }, this);
+ }
+
+ /** Register a mixer handler. {@see RecentsMixedHandler}*/
+ public void addMixer(RecentsMixedHandler mixer) {
+ mMixers.add(mixer);
+ }
+
+ /** Unregister a Mixed Handler */
+ public void removeMixer(RecentsMixedHandler mixer) {
+ mMixers.remove(mixer);
+ }
+
+ void startRecentsTransition(PendingIntent intent, Intent fillIn, Bundle options,
+ IApplicationThread appThread, IRecentsAnimationRunner listener) {
+ // only care about latest one.
+ mAnimApp = appThread;
+ WindowContainerTransaction wct = new WindowContainerTransaction();
+ wct.sendPendingIntent(intent, fillIn, options);
+ final RecentsController controller = new RecentsController(listener);
+ RecentsMixedHandler mixer = null;
+ Transitions.TransitionHandler mixedHandler = null;
+ for (int i = 0; i < mMixers.size(); ++i) {
+ mixedHandler = mMixers.get(i).handleRecentsRequest(wct);
+ if (mixedHandler != null) {
+ mixer = mMixers.get(i);
+ break;
+ }
+ }
+ final IBinder transition = mTransitions.startTransition(TRANSIT_TO_FRONT, wct,
+ mixedHandler == null ? this : mixedHandler);
+ if (mixer != null) {
+ mixer.setRecentsTransition(transition);
+ }
+ if (transition == null) {
+ controller.cancel();
+ return;
+ }
+ controller.setTransition(transition);
+ mControllers.add(controller);
+ }
+
+ @Override
+ public WindowContainerTransaction handleRequest(IBinder transition,
+ TransitionRequestInfo request) {
+ // do not directly handle requests. Only entry point should be via startRecentsTransition
+ return null;
+ }
+
+ private int findController(IBinder transition) {
+ for (int i = mControllers.size() - 1; i >= 0; --i) {
+ if (mControllers.get(i).mTransition == transition) return i;
+ }
+ return -1;
+ }
+
+ @Override
+ public boolean startAnimation(IBinder transition, TransitionInfo info,
+ SurfaceControl.Transaction startTransaction,
+ SurfaceControl.Transaction finishTransaction,
+ Transitions.TransitionFinishCallback finishCallback) {
+ final int controllerIdx = findController(transition);
+ if (controllerIdx < 0) return false;
+ final RecentsController controller = mControllers.get(controllerIdx);
+ Transitions.setRunningRemoteTransitionDelegate(mAnimApp);
+ mAnimApp = null;
+ if (!controller.start(info, startTransaction, finishTransaction, finishCallback)) {
+ return false;
+ }
+ return true;
+ }
+
+ @Override
+ public void mergeAnimation(IBinder transition, TransitionInfo info,
+ SurfaceControl.Transaction t, IBinder mergeTarget,
+ Transitions.TransitionFinishCallback finishCallback) {
+ final int targetIdx = findController(mergeTarget);
+ if (targetIdx < 0) return;
+ final RecentsController controller = mControllers.get(targetIdx);
+ controller.merge(info, t, finishCallback);
+ }
+
+ @Override
+ public void onTransitionConsumed(IBinder transition, boolean aborted,
+ SurfaceControl.Transaction finishTransaction) {
+ final int idx = findController(transition);
+ if (idx < 0) return;
+ mControllers.get(idx).cancel();
+ }
+
+ /** There is only one of these and it gets reset on finish. */
+ private class RecentsController extends IRecentsAnimationController.Stub {
+ private IRecentsAnimationRunner mListener;
+ private IBinder.DeathRecipient mDeathHandler;
+ private Transitions.TransitionFinishCallback mFinishCB = null;
+ private SurfaceControl.Transaction mFinishTransaction = null;
+
+ /**
+ * List of tasks that we are switching away from via this transition. Upon finish, these
+ * pausing tasks will become invisible.
+ * These need to be ordered since the order must be restored if there is no task-switch.
+ */
+ private ArrayList<TaskState> mPausingTasks = null;
+
+ /**
+ * List of tasks that we are switching to. Upon finish, these will remain visible and
+ * on top.
+ */
+ private ArrayList<TaskState> mOpeningTasks = null;
+
+ private WindowContainerToken mPipTask = null;
+ private WindowContainerToken mRecentsTask = null;
+ private int mRecentsTaskId = -1;
+ private TransitionInfo mInfo = null;
+ private boolean mOpeningSeparateHome = false;
+ private ArrayMap<SurfaceControl, SurfaceControl> mLeashMap = null;
+ private PictureInPictureSurfaceTransaction mPipTransaction = null;
+ private IBinder mTransition = null;
+ private boolean mKeyguardLocked = false;
+ private boolean mWillFinishToHome = false;
+
+ /** The animation is idle, waiting for the user to choose a task to switch to. */
+ private static final int STATE_NORMAL = 0;
+
+ /** The user chose a new task to switch to and the animation is animating to it. */
+ private static final int STATE_NEW_TASK = 1;
+
+ /** The latest state that the recents animation is operating in. */
+ private int mState = STATE_NORMAL;
+
+ RecentsController(IRecentsAnimationRunner listener) {
+ mListener = listener;
+ mDeathHandler = () -> mExecutor.execute(() -> {
+ if (mListener == null) return;
+ if (mFinishCB != null) {
+ finish(mWillFinishToHome, false /* leaveHint */);
+ }
+ });
+ try {
+ mListener.asBinder().linkToDeath(mDeathHandler, 0 /* flags */);
+ } catch (RemoteException e) {
+ mListener = null;
+ }
+ }
+
+ void setTransition(IBinder transition) {
+ mTransition = transition;
+ }
+
+ void cancel() {
+ // restoring (to-home = false) involves submitting more WM changes, so by default, use
+ // toHome = true when canceling.
+ cancel(true /* toHome */);
+ }
+
+ void cancel(boolean toHome) {
+ if (mListener != null) {
+ try {
+ mListener.onAnimationCanceled(null, null);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error canceling recents animation", e);
+ }
+ }
+ if (mFinishCB != null) {
+ finish(toHome, false /* userLeave */);
+ } else {
+ cleanUp();
+ }
+ }
+
+ /**
+ * Sends a cancel message to the recents animation with snapshots. Used to trigger a
+ * "replace-with-screenshot" like behavior.
+ */
+ private boolean sendCancelWithSnapshots() {
+ int[] taskIds = null;
+ TaskSnapshot[] snapshots = null;
+ if (mPausingTasks.size() > 0) {
+ taskIds = new int[mPausingTasks.size()];
+ snapshots = new TaskSnapshot[mPausingTasks.size()];
+ try {
+ for (int i = 0; i < mPausingTasks.size(); ++i) {
+ snapshots[i] = ActivityTaskManager.getService().takeTaskSnapshot(
+ mPausingTasks.get(0).mTaskInfo.taskId);
+ }
+ } catch (RemoteException e) {
+ taskIds = null;
+ snapshots = null;
+ }
+ }
+ try {
+ mListener.onAnimationCanceled(taskIds, snapshots);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error canceling recents animation", e);
+ return false;
+ }
+ return true;
+ }
+
+ void cleanUp() {
+ if (mListener != null && mDeathHandler != null) {
+ mListener.asBinder().unlinkToDeath(mDeathHandler, 0 /* flags */);
+ mDeathHandler = null;
+ }
+ mListener = null;
+ mFinishCB = null;
+ // clean-up leash surfacecontrols and anything that might reference them.
+ if (mLeashMap != null) {
+ for (int i = 0; i < mLeashMap.size(); ++i) {
+ mLeashMap.valueAt(i).release();
+ }
+ mLeashMap = null;
+ }
+ mFinishTransaction = null;
+ mPausingTasks = null;
+ mOpeningTasks = null;
+ mInfo = null;
+ mTransition = null;
+ mControllers.remove(this);
+ }
+
+ boolean start(TransitionInfo info, SurfaceControl.Transaction t,
+ SurfaceControl.Transaction finishT, Transitions.TransitionFinishCallback finishCB) {
+ if (mListener == null || mTransition == null) {
+ cleanUp();
+ return false;
+ }
+ // First see if this is a valid recents transition.
+ boolean hasPausingTasks = false;
+ for (int i = 0; i < info.getChanges().size(); ++i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ if (TransitionUtil.isWallpaper(change)) continue;
+ if (TransitionUtil.isClosingType(change.getMode())) {
+ hasPausingTasks = true;
+ continue;
+ }
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) {
+ mRecentsTask = taskInfo.token;
+ mRecentsTaskId = taskInfo.taskId;
+ } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ mRecentsTask = taskInfo.token;
+ mRecentsTaskId = taskInfo.taskId;
+ }
+ }
+ if (mRecentsTask == null && !hasPausingTasks) {
+ // Recents is already running apparently, so this is a no-op.
+ Slog.e(TAG, "Tried to start recents while it is already running.");
+ cleanUp();
+ return false;
+ }
+
+ mInfo = info;
+ mFinishCB = finishCB;
+ mFinishTransaction = finishT;
+ mPausingTasks = new ArrayList<>();
+ mOpeningTasks = new ArrayList<>();
+ mLeashMap = new ArrayMap<>();
+ mKeyguardLocked = (info.getFlags() & TRANSIT_FLAG_KEYGUARD_LOCKED) != 0;
+
+ final ArrayList<RemoteAnimationTarget> apps = new ArrayList<>();
+ final ArrayList<RemoteAnimationTarget> wallpapers = new ArrayList<>();
+ TransitionUtil.LeafTaskFilter leafTaskFilter = new TransitionUtil.LeafTaskFilter();
+ // About layering: we divide up the "layer space" into 3 regions (each the size of
+ // the change count). This lets us categorize things into above/below/between
+ // while maintaining their relative ordering.
+ for (int i = 0; i < info.getChanges().size(); ++i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ if (TransitionUtil.isWallpaper(change)) {
+ final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
+ // wallpapers go into the "below" layer space
+ info.getChanges().size() - i, info, t, mLeashMap);
+ wallpapers.add(target);
+ // Make all the wallpapers opaque since we want them visible from the start
+ t.setAlpha(target.leash, 1);
+ } else if (leafTaskFilter.test(change)) {
+ // start by putting everything into the "below" layer space.
+ final RemoteAnimationTarget target = TransitionUtil.newTarget(change,
+ info.getChanges().size() - i, info, t, mLeashMap);
+ apps.add(target);
+ if (TransitionUtil.isClosingType(change.getMode())) {
+ // raise closing (pausing) task to "above" layer so it isn't covered
+ t.setLayer(target.leash, info.getChanges().size() * 3 - i);
+ mPausingTasks.add(new TaskState(change, target.leash));
+ if (taskInfo.pictureInPictureParams != null
+ && taskInfo.pictureInPictureParams.isAutoEnterEnabled()) {
+ mPipTask = taskInfo.token;
+ }
+ } else if (taskInfo != null
+ && taskInfo.topActivityType == ACTIVITY_TYPE_RECENTS) {
+ // There's a 3p launcher, so make sure recents goes above that.
+ t.setLayer(target.leash, info.getChanges().size() * 3 - i);
+ } else if (taskInfo != null && taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ // do nothing
+ } else if (TransitionUtil.isOpeningType(change.getMode())) {
+ mOpeningTasks.add(new TaskState(change, target.leash));
+ }
+ }
+ }
+ t.apply();
+ try {
+ mListener.onAnimationStart(this,
+ apps.toArray(new RemoteAnimationTarget[apps.size()]),
+ wallpapers.toArray(new RemoteAnimationTarget[wallpapers.size()]),
+ new Rect(0, 0, 0, 0), new Rect());
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error starting recents animation", e);
+ cancel();
+ }
+ return true;
+ }
+
+ @SuppressLint("NewApi")
+ void merge(TransitionInfo info, SurfaceControl.Transaction t,
+ Transitions.TransitionFinishCallback finishCallback) {
+ if (mFinishCB == null) {
+ // This was no-op'd (likely a repeated start) and we've already sent finish.
+ return;
+ }
+ if (info.getType() == TRANSIT_SLEEP) {
+ // A sleep event means we need to stop animations immediately, so cancel here.
+ cancel();
+ return;
+ }
+ ArrayList<TransitionInfo.Change> openingTasks = null;
+ ArrayList<TransitionInfo.Change> closingTasks = null;
+ mOpeningSeparateHome = false;
+ TransitionInfo.Change recentsOpening = null;
+ boolean foundRecentsClosing = false;
+ boolean hasChangingApp = false;
+ final TransitionUtil.LeafTaskFilter leafTaskFilter =
+ new TransitionUtil.LeafTaskFilter();
+ for (int i = 0; i < info.getChanges().size(); ++i) {
+ final TransitionInfo.Change change = info.getChanges().get(i);
+ final ActivityManager.RunningTaskInfo taskInfo = change.getTaskInfo();
+ final boolean isLeafTask = leafTaskFilter.test(change);
+ if (TransitionUtil.isOpeningType(change.getMode())) {
+ if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
+ recentsOpening = change;
+ } else if (isLeafTask) {
+ if (taskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ // This is usually a 3p launcher
+ mOpeningSeparateHome = true;
+ }
+ if (openingTasks == null) {
+ openingTasks = new ArrayList<>();
+ }
+ openingTasks.add(change);
+ }
+ } else if (TransitionUtil.isClosingType(change.getMode())) {
+ if (mRecentsTask != null && mRecentsTask.equals(change.getContainer())) {
+ foundRecentsClosing = true;
+ } else if (isLeafTask) {
+ if (closingTasks == null) {
+ closingTasks = new ArrayList<>();
+ }
+ closingTasks.add(change);
+ }
+ } else if (change.getMode() == TRANSIT_CHANGE) {
+ // Finish recents animation if the display is changed, so the default
+ // transition handler can play the animation such as rotation effect.
+ if (change.hasFlags(TransitionInfo.FLAG_IS_DISPLAY)) {
+ cancel(mWillFinishToHome);
+ return;
+ }
+ hasChangingApp = true;
+ }
+ }
+ if (hasChangingApp && foundRecentsClosing) {
+ // This happens when a visible app is expanding (usually PiP). In this case,
+ // that transition probably has a special-purpose animation, so finish recents
+ // now and let it do its animation (since recents is going to be occluded).
+ sendCancelWithSnapshots();
+ mExecutor.executeDelayed(
+ () -> finishInner(true /* toHome */, false /* userLeaveHint */), 0);
+ return;
+ }
+ if (recentsOpening != null) {
+ // the recents task re-appeared. This happens if the user gestures before the
+ // task-switch (NEW_TASK) animation finishes.
+ if (mState == STATE_NORMAL) {
+ Slog.e(TAG, "Returning to recents while recents is already idle.");
+ }
+ if (closingTasks == null || closingTasks.size() == 0) {
+ Slog.e(TAG, "Returning to recents without closing any opening tasks.");
+ }
+ // Setup may hide it initially since it doesn't know that overview was still active.
+ t.show(recentsOpening.getLeash());
+ t.setAlpha(recentsOpening.getLeash(), 1.f);
+ mState = STATE_NORMAL;
+ }
+ boolean didMergeThings = false;
+ if (closingTasks != null) {
+ // Cancelling a task-switch. Move the tasks back to mPausing from mOpening
+ for (int i = 0; i < closingTasks.size(); ++i) {
+ final TransitionInfo.Change change = closingTasks.get(i);
+ int openingIdx = TaskState.indexOf(mOpeningTasks, change);
+ if (openingIdx < 0) {
+ Slog.e(TAG, "Back to existing recents animation from an unrecognized "
+ + "task: " + change.getTaskInfo().taskId);
+ continue;
+ }
+ mPausingTasks.add(mOpeningTasks.remove(openingIdx));
+ didMergeThings = true;
+ }
+ }
+ RemoteAnimationTarget[] appearedTargets = null;
+ if (openingTasks != null && openingTasks.size() > 0) {
+ // Switching to some new tasks, add to mOpening and remove from mPausing. Also,
+ // enter NEW_TASK state since this will start the switch-to animation.
+ final int layer = mInfo.getChanges().size() * 3;
+ appearedTargets = new RemoteAnimationTarget[openingTasks.size()];
+ for (int i = 0; i < openingTasks.size(); ++i) {
+ final TransitionInfo.Change change = openingTasks.get(i);
+ int pausingIdx = TaskState.indexOf(mPausingTasks, change);
+ if (pausingIdx >= 0) {
+ // Something is showing/opening a previously-pausing app.
+ appearedTargets[i] = TransitionUtil.newTarget(
+ change, layer, mPausingTasks.get(pausingIdx).mLeash);
+ mOpeningTasks.add(mPausingTasks.remove(pausingIdx));
+ // Setup hides opening tasks initially, so make it visible again (since we
+ // are already showing it).
+ t.show(change.getLeash());
+ t.setAlpha(change.getLeash(), 1.f);
+ } else {
+ // We are receiving new opening tasks, so convert to onTasksAppeared.
+ appearedTargets[i] = TransitionUtil.newTarget(
+ change, layer, info, t, mLeashMap);
+ // reparent into the original `mInfo` since that's where we are animating.
+ final int rootIdx = TransitionUtil.rootIndexFor(change, mInfo);
+ t.reparent(appearedTargets[i].leash, mInfo.getRoot(rootIdx).getLeash());
+ t.setLayer(appearedTargets[i].leash, layer);
+ mOpeningTasks.add(new TaskState(change, appearedTargets[i].leash));
+ }
+ }
+ didMergeThings = true;
+ mState = STATE_NEW_TASK;
+ }
+ if (!didMergeThings) {
+ // Didn't recognize anything in incoming transition so don't merge it.
+ Slog.w(TAG, "Don't know how to merge this transition.");
+ return;
+ }
+ // At this point, we are accepting the merge.
+ t.apply();
+ // not using the incoming anim-only surfaces
+ info.releaseAnimSurfaces();
+ finishCallback.onTransitionFinished(null /* wct */, null /* wctCB */);
+ if (appearedTargets == null) return;
+ try {
+ mListener.onTasksAppeared(appearedTargets);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Error sending appeared tasks to recents animation", e);
+ }
+ }
+
+ @Override
+ public TaskSnapshot screenshotTask(int taskId) {
+ try {
+ return ActivityTaskManager.getService().takeTaskSnapshot(taskId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to screenshot task", e);
+ }
+ return null;
+ }
+
+ @Override
+ public void setInputConsumerEnabled(boolean enabled) {
+ mExecutor.execute(() -> {
+ if (mFinishCB == null || !enabled) return;
+ // transient launches don't receive focus automatically. Since we are taking over
+ // the gesture now, take focus explicitly.
+ // This also moves recents back to top if the user gestured before a switch
+ // animation finished.
+ try {
+ ActivityTaskManager.getService().setFocusedTask(mRecentsTaskId);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to set focused task", e);
+ }
+ });
+ }
+
+ @Override
+ public void setAnimationTargetsBehindSystemBars(boolean behindSystemBars) {
+ }
+
+ @Override
+ public void setFinishTaskTransaction(int taskId,
+ PictureInPictureSurfaceTransaction finishTransaction, SurfaceControl overlay) {
+ mExecutor.execute(() -> {
+ if (mFinishCB == null) return;
+ mPipTransaction = finishTransaction;
+ });
+ }
+
+ @Override
+ @SuppressLint("NewApi")
+ public void finish(boolean toHome, boolean sendUserLeaveHint) {
+ mExecutor.execute(() -> finishInner(toHome, sendUserLeaveHint));
+ }
+
+ private void finishInner(boolean toHome, boolean sendUserLeaveHint) {
+ if (mFinishCB == null) {
+ Slog.e(TAG, "Duplicate call to finish");
+ return;
+ }
+ final Transitions.TransitionFinishCallback finishCB = mFinishCB;
+ mFinishCB = null;
+
+ final SurfaceControl.Transaction t = mFinishTransaction;
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+
+ if (mKeyguardLocked && mRecentsTask != null) {
+ if (toHome) wct.reorder(mRecentsTask, true /* toTop */);
+ else wct.restoreTransientOrder(mRecentsTask);
+ }
+ if (!toHome && !mWillFinishToHome && mPausingTasks != null && mState == STATE_NORMAL) {
+ // The gesture is returning to the pausing-task(s) rather than continuing with
+ // recents, so end the transition by moving the app back to the top (and also
+ // re-showing it's task).
+ for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
+ // reverse order so that index 0 ends up on top
+ wct.reorder(mPausingTasks.get(i).mToken, true /* onTop */);
+ t.show(mPausingTasks.get(i).mTaskSurface);
+ }
+ if (!mKeyguardLocked && mRecentsTask != null) {
+ wct.restoreTransientOrder(mRecentsTask);
+ }
+ } else if (toHome && mOpeningSeparateHome && mPausingTasks != null) {
+ // Special situation where 3p launcher was changed during recents (this happens
+ // during tapltests...). Here we get both "return to home" AND "home opening".
+ // This is basically going home, but we have to restore the recents and home order.
+ for (int i = 0; i < mOpeningTasks.size(); ++i) {
+ final TaskState state = mOpeningTasks.get(i);
+ if (state.mTaskInfo.topActivityType == ACTIVITY_TYPE_HOME) {
+ // Make sure it is on top.
+ wct.reorder(state.mToken, true /* onTop */);
+ }
+ t.show(state.mTaskSurface);
+ }
+ for (int i = mPausingTasks.size() - 1; i >= 0; --i) {
+ t.hide(mPausingTasks.get(i).mTaskSurface);
+ }
+ if (!mKeyguardLocked && mRecentsTask != null) {
+ wct.restoreTransientOrder(mRecentsTask);
+ }
+ } else {
+ // The general case: committing to recents, going home, or switching tasks.
+ for (int i = 0; i < mOpeningTasks.size(); ++i) {
+ t.show(mOpeningTasks.get(i).mTaskSurface);
+ }
+ for (int i = 0; i < mPausingTasks.size(); ++i) {
+ if (!sendUserLeaveHint) {
+ // This means recents is not *actually* finishing, so of course we gotta
+ // do special stuff in WMCore to accommodate.
+ wct.setDoNotPip(mPausingTasks.get(i).mToken);
+ }
+ // Since we will reparent out of the leashes, pre-emptively hide the child
+ // surface to match the leash. Otherwise, there will be a flicker before the
+ // visibility gets committed in Core when using split-screen (in splitscreen,
+ // the leaf-tasks are not "independent" so aren't hidden by normal setup).
+ t.hide(mPausingTasks.get(i).mTaskSurface);
+ }
+ if (mPipTask != null && mPipTransaction != null && sendUserLeaveHint) {
+ t.show(mInfo.getChange(mPipTask).getLeash());
+ PictureInPictureSurfaceTransaction.apply(mPipTransaction,
+ mInfo.getChange(mPipTask).getLeash(), t);
+ mPipTask = null;
+ mPipTransaction = null;
+ }
+ }
+ cleanUp();
+ finishCB.onTransitionFinished(wct.isEmpty() ? null : wct, null /* wctCB */);
+ }
+
+ @Override
+ public void setDeferCancelUntilNextTransition(boolean defer, boolean screenshot) {
+ }
+
+ @Override
+ public void cleanupScreenshot() {
+ }
+
+ @Override
+ public void setWillFinishToHome(boolean willFinishToHome) {
+ mExecutor.execute(() -> {
+ mWillFinishToHome = willFinishToHome;
+ });
+ }
+
+ /**
+ * @see IRecentsAnimationController#removeTask
+ */
+ @Override
+ public boolean removeTask(int taskId) {
+ return false;
+ }
+
+ /**
+ * @see IRecentsAnimationController#detachNavigationBarFromApp
+ */
+ @Override
+ public void detachNavigationBarFromApp(boolean moveHomeToTop) {
+ mExecutor.execute(() -> {
+ if (mTransition == null) return;
+ try {
+ ActivityTaskManager.getService().detachNavigationBarFromApp(mTransition);
+ } catch (RemoteException e) {
+ Slog.e(TAG, "Failed to detach the navigation bar from app", e);
+ }
+ });
+ }
+
+ /**
+ * @see IRecentsAnimationController#animateNavigationBarToApp(long)
+ */
+ @Override
+ public void animateNavigationBarToApp(long duration) {
+ }
+ };
+
+ /** Utility class to track the state of a task as-seen by recents. */
+ private static class TaskState {
+ WindowContainerToken mToken;
+ ActivityManager.RunningTaskInfo mTaskInfo;
+
+ /** The surface/leash of the task provided by Core. */
+ SurfaceControl mTaskSurface;
+
+ /** The (local) animation-leash created for this task. */
+ SurfaceControl mLeash;
+
+ TaskState(TransitionInfo.Change change, SurfaceControl leash) {
+ mToken = change.getContainer();
+ mTaskInfo = change.getTaskInfo();
+ mTaskSurface = change.getLeash();
+ mLeash = leash;
+ }
+
+ static int indexOf(ArrayList<TaskState> list, TransitionInfo.Change change) {
+ for (int i = list.size() - 1; i >= 0; --i) {
+ if (list.get(i).mToken.equals(change.getContainer())) {
+ return i;
+ }
+ }
+ return -1;
+ }
+
+ public String toString() {
+ return "" + mToken + " : " + mLeash;
+ }
+ }
+
+ /**
+ * An interface for a mixed handler to receive information about recents requests (since these
+ * come into this handler directly vs from WMCore request).
+ */
+ public interface RecentsMixedHandler {
+ /**
+ * Called when a recents request comes in. The handler can add operations to outWCT. If
+ * the handler wants to "accept" the transition, it should return itself; otherwise, it
+ * should return `null`.
+ *
+ * If a mixed-handler accepts this recents, it will be the de-facto handler for this
+ * transition and is required to call the associated {@link #startAnimation},
+ * {@link #mergeAnimation}, and {@link #onTransitionConsumed} methods.
+ */
+ Transitions.TransitionHandler handleRecentsRequest(WindowContainerTransaction outWCT);
+
+ /**
+ * Reports the transition token associated with the accepted recents request. If there was
+ * a problem starting the request, this will be called with `null`.
+ */
+ void setRecentsTransition(@Nullable IBinder transition);
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
index 94b9e90..7d5ab84 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/SplitScreenController.java
@@ -31,7 +31,6 @@
import static com.android.wm.shell.common.split.SplitScreenUtils.isValidToSplit;
import static com.android.wm.shell.common.split.SplitScreenUtils.reverseSplitPosition;
import static com.android.wm.shell.common.split.SplitScreenUtils.samePackage;
-import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_SIDE;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
import static com.android.wm.shell.sysui.ShellSharedConstants.KEY_EXTRA_SHELL_SPLIT_SCREEN;
import static com.android.wm.shell.transition.Transitions.ENABLE_SHELL_TRANSITIONS;
@@ -89,7 +88,6 @@
import com.android.wm.shell.draganddrop.DragAndDropPolicy;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
import com.android.wm.shell.recents.RecentTasksController;
-import com.android.wm.shell.splitscreen.SplitScreen.StageType;
import com.android.wm.shell.sysui.KeyguardChangeListener;
import com.android.wm.shell.sysui.ShellCommandHandler;
import com.android.wm.shell.sysui.ShellController;
@@ -329,9 +327,14 @@
return mTaskOrganizer.getRunningTaskInfo(taskId);
}
+ /** Check task is under split or not by taskId. */
public boolean isTaskInSplitScreen(int taskId) {
- return isSplitScreenVisible()
- && mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED;
+ return mStageCoordinator.getStageOfTask(taskId) != STAGE_TYPE_UNDEFINED;
+ }
+
+ /** Check split is foreground and task is under split or not by taskId. */
+ public boolean isTaskInSplitScreenForeground(int taskId) {
+ return isTaskInSplitScreen(taskId) && isSplitScreenVisible();
}
public @SplitPosition int getSplitPosition(int taskId) {
@@ -339,8 +342,7 @@
}
public boolean moveToSideStage(int taskId, @SplitPosition int sideStagePosition) {
- return moveToStage(taskId, STAGE_TYPE_SIDE, sideStagePosition,
- new WindowContainerTransaction());
+ return moveToStage(taskId, sideStagePosition, new WindowContainerTransaction());
}
/**
@@ -351,13 +353,13 @@
mStageCoordinator.updateSurfaces(transaction);
}
- private boolean moveToStage(int taskId, @StageType int stageType,
- @SplitPosition int stagePosition, WindowContainerTransaction wct) {
+ private boolean moveToStage(int taskId, @SplitPosition int stagePosition,
+ WindowContainerTransaction wct) {
final ActivityManager.RunningTaskInfo task = mTaskOrganizer.getRunningTaskInfo(taskId);
if (task == null) {
throw new IllegalArgumentException("Unknown taskId" + taskId);
}
- return mStageCoordinator.moveToStage(task, stageType, stagePosition, wct);
+ return mStageCoordinator.moveToStage(task, stagePosition, wct);
}
public boolean removeFromSideStage(int taskId) {
@@ -382,10 +384,9 @@
}
public void enterSplitScreen(int taskId, boolean leftOrTop, WindowContainerTransaction wct) {
- final int stageType = isSplitScreenVisible() ? STAGE_TYPE_UNDEFINED : STAGE_TYPE_SIDE;
final int stagePosition =
leftOrTop ? SPLIT_POSITION_TOP_OR_LEFT : SPLIT_POSITION_BOTTOM_OR_RIGHT;
- moveToStage(taskId, stageType, stagePosition, wct);
+ moveToStage(taskId, stagePosition, wct);
}
public void exitSplitScreen(int toTopTaskId, @ExitReason int exitReason) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
index a5546e5..def945e 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/splitscreen/StageCoordinator.java
@@ -259,37 +259,6 @@
}
};
- private final SplitScreenTransitions.TransitionFinishedCallback
- mRecentTransitionFinishedCallback =
- new SplitScreenTransitions.TransitionFinishedCallback() {
- @Override
- public void onFinished(WindowContainerTransaction finishWct,
- SurfaceControl.Transaction finishT) {
- // Check if the recent transition is finished by returning to the current
- // split, so we
- // can restore the divider bar.
- for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
- final WindowContainerTransaction.HierarchyOp op =
- finishWct.getHierarchyOps().get(i);
- final IBinder container = op.getContainer();
- if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop()
- && (mMainStage.containsContainer(container)
- || mSideStage.containsContainer(container))) {
- updateSurfaceBounds(mSplitLayout, finishT,
- false /* applyResizingOffset */);
- setDividerVisibility(true, finishT);
- return;
- }
- }
-
- // Dismiss the split screen if it's not returning to split.
- prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, finishWct);
- setSplitsVisible(false);
- setDividerVisibility(false, finishT);
- logExit(EXIT_REASON_UNKNOWN);
- }
- };
-
protected StageCoordinator(Context context, int displayId, SyncTransactionQueue syncQueue,
ShellTaskOrganizer taskOrganizer, DisplayController displayController,
DisplayImeController displayImeController,
@@ -388,6 +357,11 @@
return mMainStage.isActive();
}
+ /** Checks if `transition` is a pending enter-split transition. */
+ public boolean isPendingEnter(IBinder transition) {
+ return mSplitTransitions.isPendingEnter(transition);
+ }
+
@StageType
int getStageOfTask(int taskId) {
if (mMainStage.containsTask(taskId)) {
@@ -399,56 +373,43 @@
return STAGE_TYPE_UNDEFINED;
}
- boolean moveToStage(ActivityManager.RunningTaskInfo task, @StageType int stageType,
- @SplitPosition int stagePosition, WindowContainerTransaction wct) {
+ boolean moveToStage(ActivityManager.RunningTaskInfo task, @SplitPosition int stagePosition,
+ WindowContainerTransaction wct) {
StageTaskListener targetStage;
int sideStagePosition;
- if (stageType == STAGE_TYPE_MAIN) {
- targetStage = mMainStage;
- sideStagePosition = reverseSplitPosition(stagePosition);
- } else if (stageType == STAGE_TYPE_SIDE) {
+ if (isSplitScreenVisible()) {
+ // If the split screen is foreground, retrieves target stage based on position.
+ targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage;
+ sideStagePosition = mSideStagePosition;
+ } else {
targetStage = mSideStage;
sideStagePosition = stagePosition;
- } else {
- if (isSplitScreenVisible()) {
- // If the split screen is activated, retrieves target stage based on position.
- targetStage = stagePosition == mSideStagePosition ? mSideStage : mMainStage;
- sideStagePosition = mSideStagePosition;
- } else {
- // Exit split if it running background.
- exitSplitScreen(null /* childrenToTop */, EXIT_REASON_RECREATE_SPLIT);
-
- targetStage = mSideStage;
- sideStagePosition = stagePosition;
- }
}
if (!isSplitActive()) {
- // prevent the fling divider to center transitioni if split screen didn't active.
- mIsDropEntering = true;
+ mSplitLayout.init();
+ prepareEnterSplitScreen(wct, task, stagePosition);
+ mSyncQueue.queue(wct);
+ mSyncQueue.runInSync(t -> {
+ updateSurfaceBounds(mSplitLayout, t, false /* applyResizingOffset */);
+ });
+ } else {
+ setSideStagePosition(sideStagePosition, wct);
+ targetStage.addTask(task, wct);
+ targetStage.evictAllChildren(wct);
+ if (!isSplitScreenVisible()) {
+ final StageTaskListener anotherStage = targetStage == mMainStage
+ ? mSideStage : mMainStage;
+ anotherStage.reparentTopTask(wct);
+ anotherStage.evictAllChildren(wct);
+ wct.reorder(mRootTaskInfo.token, true);
+ }
+ setRootForceTranslucent(false, wct);
+ mSyncQueue.queue(wct);
}
- setSideStagePosition(sideStagePosition, wct);
- final WindowContainerTransaction evictWct = new WindowContainerTransaction();
- targetStage.evictAllChildren(evictWct);
-
- // Apply surface bounds before animation start.
- SurfaceControl.Transaction startT = mTransactionPool.acquire();
- if (startT != null) {
- updateSurfaceBounds(mSplitLayout, startT, false /* applyResizingOffset */);
- startT.apply();
- mTransactionPool.release(startT);
- }
- // reparent the task to an invisible split root will make the activity invisible. Reorder
- // the root task to front to make the entering transition from pip to split smooth.
- wct.reorder(mRootTaskInfo.token, true);
- wct.reorder(targetStage.mRootTaskInfo.token, true);
- targetStage.addTask(task, wct);
-
- if (!evictWct.isEmpty()) {
- wct.merge(evictWct, true /* transfer */);
- }
- mTaskOrganizer.applyTransaction(wct);
+ // Due to drag already pip task entering split by this method so need to reset flag here.
+ mIsDropEntering = false;
return true;
}
@@ -2264,11 +2225,16 @@
}
} else if (isOpening && inFullscreen) {
final int activityType = triggerTask.getActivityType();
- if (activityType == ACTIVITY_TYPE_HOME
- || activityType == ACTIVITY_TYPE_RECENTS) {
- // Enter overview panel, so start recent transition.
- mSplitTransitions.setRecentTransition(transition, request.getRemoteTransition(),
- mRecentTransitionFinishedCallback);
+ if (activityType == ACTIVITY_TYPE_HOME || activityType == ACTIVITY_TYPE_RECENTS) {
+ if (request.getRemoteTransition() != null) {
+ // starting recents/home, so don't handle this and let it fall-through to
+ // the remote handler.
+ return null;
+ }
+ // Need to use the old stuff for non-remote animations, otherwise we don't
+ // exit split-screen.
+ mSplitTransitions.setRecentTransition(transition, null /* remote */,
+ this::onRecentsInSplitAnimationFinish);
}
}
} else {
@@ -2398,7 +2364,7 @@
shouldAnimate = startPendingEnterAnimation(
transition, info, startTransaction, finishTransaction);
} else if (mSplitTransitions.isPendingRecent(transition)) {
- shouldAnimate = startPendingRecentAnimation(transition, info, startTransaction);
+ onRecentsInSplitAnimationStart(startTransaction);
} else if (mSplitTransitions.isPendingDismiss(transition)) {
shouldAnimate = startPendingDismissAnimation(
mSplitTransitions.mPendingDismiss, info, startTransaction, finishTransaction);
@@ -2653,10 +2619,35 @@
return true;
}
- private boolean startPendingRecentAnimation(@NonNull IBinder transition,
- @NonNull TransitionInfo info, @NonNull SurfaceControl.Transaction t) {
+ /** Call this when starting the open-recents animation while split-screen is active. */
+ public void onRecentsInSplitAnimationStart(@NonNull SurfaceControl.Transaction t) {
setDividerVisibility(false, t);
- return true;
+ }
+
+ /** Call this when the recents animation during split-screen finishes. */
+ public void onRecentsInSplitAnimationFinish(WindowContainerTransaction finishWct,
+ SurfaceControl.Transaction finishT) {
+ // Check if the recent transition is finished by returning to the current
+ // split, so we can restore the divider bar.
+ for (int i = 0; i < finishWct.getHierarchyOps().size(); ++i) {
+ final WindowContainerTransaction.HierarchyOp op =
+ finishWct.getHierarchyOps().get(i);
+ final IBinder container = op.getContainer();
+ if (op.getType() == HIERARCHY_OP_TYPE_REORDER && op.getToTop()
+ && (mMainStage.containsContainer(container)
+ || mSideStage.containsContainer(container))) {
+ updateSurfaceBounds(mSplitLayout, finishT,
+ false /* applyResizingOffset */);
+ setDividerVisibility(true, finishT);
+ return;
+ }
+ }
+
+ // Dismiss the split screen if it's not returning to split.
+ prepareExitSplitScreen(STAGE_TYPE_UNDEFINED, finishWct);
+ setSplitsVisible(false);
+ setDividerVisibility(false, finishT);
+ logExit(EXIT_REASON_UNKNOWN);
}
private void addDividerBarToTransition(@NonNull TransitionInfo info,
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
index 2e86448..586cab0 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/transition/DefaultMixedHandler.java
@@ -18,6 +18,7 @@
import static android.app.WindowConfiguration.ACTIVITY_TYPE_HOME;
import static android.app.WindowConfiguration.ACTIVITY_TYPE_RECENTS;
+import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.view.WindowManager.TRANSIT_CHANGE;
import static android.view.WindowManager.TRANSIT_TO_BACK;
import static android.window.TransitionInfo.FLAG_IS_WALLPAPER;
@@ -25,6 +26,7 @@
import static com.android.wm.shell.common.split.SplitScreenConstants.FLAG_IS_DIVIDER_BAR;
import static com.android.wm.shell.splitscreen.SplitScreen.STAGE_TYPE_UNDEFINED;
import static com.android.wm.shell.splitscreen.SplitScreenController.EXIT_REASON_CHILD_TASK_ENTER_PIP;
+import static com.android.wm.shell.util.TransitionUtil.isOpeningType;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -41,6 +43,7 @@
import com.android.wm.shell.pip.PipTransitionController;
import com.android.wm.shell.pip.phone.PipTouchHandler;
import com.android.wm.shell.protolog.ShellProtoLogGroup;
+import com.android.wm.shell.recents.RecentsTransitionHandler;
import com.android.wm.shell.splitscreen.SplitScreenController;
import com.android.wm.shell.splitscreen.StageCoordinator;
import com.android.wm.shell.sysui.ShellInit;
@@ -53,10 +56,12 @@
* A handler for dealing with transitions involving multiple other handlers. For example: an
* activity in split-screen going into PiP.
*/
-public class DefaultMixedHandler implements Transitions.TransitionHandler {
+public class DefaultMixedHandler implements Transitions.TransitionHandler,
+ RecentsTransitionHandler.RecentsMixedHandler {
private final Transitions mPlayer;
private PipTransitionController mPipHandler;
+ private RecentsTransitionHandler mRecentsHandler;
private StageCoordinator mSplitHandler;
private static class MixedTransition {
@@ -68,14 +73,20 @@
/** Pip was entered while handling an intent with its own remoteTransition. */
static final int TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE = 3;
+ /** Recents transition while split-screen active. */
+ static final int TYPE_RECENTS_DURING_SPLIT = 4;
+
/** The default animation for this mixed transition. */
static final int ANIM_TYPE_DEFAULT = 0;
/** For ENTER_PIP_FROM_SPLIT, indicates that this is a to-home animation. */
static final int ANIM_TYPE_GOING_HOME = 1;
+ /** For RECENTS_DURING_SPLIT, is set when this turns into a pair->pair task switch. */
+ static final int ANIM_TYPE_PAIR_TO_PAIR = 1;
+
final int mType;
- int mAnimType = 0;
+ int mAnimType = ANIM_TYPE_DEFAULT;
final IBinder mTransition;
Transitions.TransitionHandler mLeftoversHandler = null;
@@ -114,7 +125,8 @@
public DefaultMixedHandler(@NonNull ShellInit shellInit, @NonNull Transitions player,
Optional<SplitScreenController> splitScreenControllerOptional,
- Optional<PipTouchHandler> pipTouchHandlerOptional) {
+ Optional<PipTouchHandler> pipTouchHandlerOptional,
+ Optional<RecentsTransitionHandler> recentsHandlerOptional) {
mPlayer = player;
if (Transitions.ENABLE_SHELL_TRANSITIONS && pipTouchHandlerOptional.isPresent()
&& splitScreenControllerOptional.isPresent()) {
@@ -126,6 +138,10 @@
if (mSplitHandler != null) {
mSplitHandler.setMixedHandler(this);
}
+ mRecentsHandler = recentsHandlerOptional.orElse(null);
+ if (mRecentsHandler != null) {
+ mRecentsHandler.addMixer(this);
+ }
}, this);
}
}
@@ -167,10 +183,54 @@
mixed.mLeftoversHandler = handler.first;
mActiveTransitions.add(mixed);
return handler.second;
+ } else if (mSplitHandler.isSplitActive()
+ && isOpeningType(request.getType())
+ && request.getTriggerTask() != null
+ && request.getTriggerTask().getWindowingMode() == WINDOWING_MODE_FULLSCREEN
+ && (request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_HOME
+ || request.getTriggerTask().getActivityType() == ACTIVITY_TYPE_RECENTS)
+ && request.getRemoteTransition() != null) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while "
+ + "Split-Screen is active, so treat it as Mixed.");
+ Pair<Transitions.TransitionHandler, WindowContainerTransaction> handler =
+ mPlayer.dispatchRequest(transition, request, this);
+ if (handler == null) {
+ android.util.Log.e(Transitions.TAG, " No handler for remote? This is unexpected"
+ + ", there should at-least be RemoteHandler.");
+ return null;
+ }
+ final MixedTransition mixed = new MixedTransition(
+ MixedTransition.TYPE_RECENTS_DURING_SPLIT, transition);
+ mixed.mLeftoversHandler = handler.first;
+ mActiveTransitions.add(mixed);
+ return handler.second;
}
return null;
}
+ @Override
+ public Transitions.TransitionHandler handleRecentsRequest(WindowContainerTransaction outWCT) {
+ if (mRecentsHandler != null && mSplitHandler.isSplitActive()) {
+ return this;
+ }
+ return null;
+ }
+
+ @Override
+ public void setRecentsTransition(IBinder transition) {
+ if (mSplitHandler.isSplitActive()) {
+ ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Got a recents request while "
+ + "Split-Screen is active, so treat it as Mixed.");
+ final MixedTransition mixed = new MixedTransition(
+ MixedTransition.TYPE_RECENTS_DURING_SPLIT, transition);
+ mixed.mLeftoversHandler = mRecentsHandler;
+ mActiveTransitions.add(mixed);
+ } else {
+ throw new IllegalStateException("Accepted a recents transition but don't know how to"
+ + " handle it");
+ }
+ }
+
private TransitionInfo subCopy(@NonNull TransitionInfo info,
@WindowManager.TransitionType int newType, boolean withChanges) {
final TransitionInfo out = new TransitionInfo(newType, withChanges ? info.getFlags() : 0);
@@ -216,6 +276,9 @@
} else if (mixed.mType == MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE) {
return animateOpenIntentWithRemoteAndPip(mixed, info, startTransaction,
finishTransaction, finishCallback);
+ } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) {
+ return animateRecentsDuringSplit(mixed, info, startTransaction, finishTransaction,
+ finishCallback);
} else {
mActiveTransitions.remove(mixed);
throw new IllegalStateException("Starting mixed animation without a known mixed type? "
@@ -240,13 +303,18 @@
info.getChanges().remove(i);
}
}
+ Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+ --mixed.mInFlightSubAnimations;
+ mixed.joinFinishArgs(wct, wctCB);
+ if (mixed.mInFlightSubAnimations > 0) return;
+ mActiveTransitions.remove(mixed);
+ finishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB);
+ };
if (pipChange == null) {
if (mixed.mLeftoversHandler != null) {
+ mixed.mInFlightSubAnimations = 1;
if (mixed.mLeftoversHandler.startAnimation(mixed.mTransition,
- info, startTransaction, finishTransaction, (wct, wctCB) -> {
- mActiveTransitions.remove(mixed);
- finishCallback.onTransitionFinished(wct, wctCB);
- })) {
+ info, startTransaction, finishTransaction, finishCB)) {
return true;
}
}
@@ -255,13 +323,6 @@
}
ProtoLog.v(ShellProtoLogGroup.WM_SHELL_TRANSITIONS, " Splitting PIP into a separate"
+ " animation because remote-animation likely doesn't support it");
- Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
- --mixed.mInFlightSubAnimations;
- mixed.joinFinishArgs(wct, wctCB);
- if (mixed.mInFlightSubAnimations > 0) return;
- mActiveTransitions.remove(mixed);
- finishCallback.onTransitionFinished(mixed.mFinishWCT, wctCB);
- };
// Split the transition into 2 parts: the pip part and the rest.
mixed.mInFlightSubAnimations = 2;
// make a new startTransaction because pip's startEnterAnimation "consumes" it so
@@ -441,12 +502,40 @@
return true;
}
+ private boolean animateRecentsDuringSplit(@NonNull final MixedTransition mixed,
+ @NonNull TransitionInfo info,
+ @NonNull SurfaceControl.Transaction startTransaction,
+ @NonNull SurfaceControl.Transaction finishTransaction,
+ @NonNull Transitions.TransitionFinishCallback finishCallback) {
+ // Split-screen is only interested in the recents transition finishing (and merging), so
+ // just wrap finish and start recents animation directly.
+ Transitions.TransitionFinishCallback finishCB = (wct, wctCB) -> {
+ mixed.mInFlightSubAnimations = 0;
+ mActiveTransitions.remove(mixed);
+ // If pair-to-pair switching, the post-recents clean-up isn't needed.
+ if (mixed.mAnimType != MixedTransition.ANIM_TYPE_PAIR_TO_PAIR) {
+ wct = wct != null ? wct : new WindowContainerTransaction();
+ mSplitHandler.onRecentsInSplitAnimationFinish(wct, finishTransaction);
+ }
+ mSplitHandler.onTransitionAnimationComplete();
+ finishCallback.onTransitionFinished(wct, wctCB);
+ };
+ mixed.mInFlightSubAnimations = 1;
+ mSplitHandler.onRecentsInSplitAnimationStart(startTransaction);
+ final boolean handled = mixed.mLeftoversHandler.startAnimation(mixed.mTransition, info,
+ startTransaction, finishTransaction, finishCB);
+ if (!handled) {
+ mActiveTransitions.remove(mixed);
+ }
+ return handled;
+ }
+
@Override
public void mergeAnimation(@NonNull IBinder transition, @NonNull TransitionInfo info,
@NonNull SurfaceControl.Transaction t, @NonNull IBinder mergeTarget,
@NonNull Transitions.TransitionFinishCallback finishCallback) {
for (int i = 0; i < mActiveTransitions.size(); ++i) {
- if (mActiveTransitions.get(i) != mergeTarget) continue;
+ if (mActiveTransitions.get(i).mTransition != mergeTarget) continue;
MixedTransition mixed = mActiveTransitions.get(i);
if (mixed.mInFlightSubAnimations <= 0) {
// Already done, so no need to end it.
@@ -474,6 +563,14 @@
mixed.mLeftoversHandler.mergeAnimation(transition, info, t, mergeTarget,
finishCallback);
}
+ } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) {
+ if (mSplitHandler.isPendingEnter(transition)) {
+ // Recents -> enter-split means that we are switching from one pair to
+ // another pair.
+ mixed.mAnimType = MixedTransition.ANIM_TYPE_PAIR_TO_PAIR;
+ }
+ mixed.mLeftoversHandler.mergeAnimation(transition, info, t, mergeTarget,
+ finishCallback);
} else {
throw new IllegalStateException("Playing a mixed transition with unknown type? "
+ mixed.mType);
@@ -493,6 +590,10 @@
if (mixed == null) return;
if (mixed.mType == MixedTransition.TYPE_ENTER_PIP_FROM_SPLIT) {
mPipHandler.onTransitionConsumed(transition, aborted, finishT);
+ } else if (mixed.mType == MixedTransition.TYPE_RECENTS_DURING_SPLIT) {
+ mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
+ } else if (mixed.mType == MixedTransition.TYPE_OPTIONS_REMOTE_AND_PIP_CHANGE) {
+ mixed.mLeftoversHandler.onTransitionConsumed(transition, aborted, finishT);
}
}
}
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 039bde9..b8b6d5b 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
@@ -534,7 +534,7 @@
}
if (info.getType() == TRANSIT_SLEEP) {
- if (activeIdx > 0) {
+ if (activeIdx > 0 || !mActiveTransitions.isEmpty() || mReadyTransitions.size() > 1) {
// Sleep starts a process of forcing all prior transitions to finish immediately
finishForSleep(null /* forceFinish */);
return;
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
index 86ca292..fe0a3fb 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/unfold/UnfoldBackgroundController.java
@@ -79,7 +79,7 @@
}
private float[] getBackgroundColor(Context context) {
- int colorInt = context.getResources().getColor(R.color.taskbar_background);
+ int colorInt = context.getResources().getColor(R.color.unfold_background);
return new float[]{
(float) red(colorInt) / 255.0F,
(float) green(colorInt) / 255.0F,
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 6b45149..d2a80471 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
@@ -166,7 +166,6 @@
}
decoration.relayout(taskInfo);
- setupCaptionColor(taskInfo, decoration);
}
@Override
@@ -252,7 +251,7 @@
}
} else if (id == R.id.back_button) {
mTaskOperations.injectBackKey();
- } else if (id == R.id.caption_handle) {
+ } else if (id == R.id.caption_handle || id == R.id.open_menu_button) {
decoration.createHandleMenu();
} else if (id == R.id.desktop_button) {
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(true));
@@ -262,7 +261,6 @@
mDesktopModeController.ifPresent(c -> c.setDesktopModeActive(false));
mDesktopTasksController.ifPresent(c -> c.moveToFullscreen(mTaskId));
decoration.closeHandleMenu();
- decoration.setButtonVisibility(false);
} else if (id == R.id.collapse_menu_button) {
decoration.closeHandleMenu();
}
@@ -556,13 +554,6 @@
}
}
- private void setupCaptionColor(RunningTaskInfo taskInfo,
- DesktopModeWindowDecoration decoration) {
- if (taskInfo == null || taskInfo.taskDescription == null) return;
- final int statusBarColor = taskInfo.taskDescription.getStatusBarColor();
- decoration.setCaptionColor(statusBarColor);
- }
-
private boolean shouldShowWindowDecor(RunningTaskInfo taskInfo) {
if (taskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM) return true;
return DesktopModeStatus.isProto2Enabled()
@@ -602,7 +593,6 @@
windowDecoration.setDragPositioningCallback(taskPositioner);
windowDecoration.setDragDetector(touchEventListener.mDragDetector);
windowDecoration.relayout(taskInfo, startT, finishT);
- setupCaptionColor(taskInfo, windowDecoration);
incrementEventReceiverTasks(taskInfo.displayId);
}
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 3c0ef96..43605e3 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
@@ -22,15 +22,10 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.res.ColorStateList;
import android.content.res.Configuration;
import android.content.res.Resources;
-import android.graphics.Color;
import android.graphics.Point;
import android.graphics.PointF;
-import android.graphics.drawable.Drawable;
-import android.graphics.drawable.GradientDrawable;
-import android.graphics.drawable.VectorDrawable;
import android.os.Handler;
import android.util.Log;
import android.view.Choreographer;
@@ -48,20 +43,24 @@
import com.android.wm.shell.common.SyncTransactionQueue;
import com.android.wm.shell.desktopmode.DesktopModeStatus;
import com.android.wm.shell.desktopmode.DesktopTasksController;
+import com.android.wm.shell.windowdecor.viewholder.DesktopModeAppControlsWindowDecorationViewHolder;
+import com.android.wm.shell.windowdecor.viewholder.DesktopModeFocusedWindowDecorationViewHolder;
+import com.android.wm.shell.windowdecor.viewholder.DesktopModeWindowDecorationViewHolder;
/**
* Defines visuals and behaviors of a window decoration of a caption bar and shadows. It works with
- * {@link DesktopModeWindowDecorViewModel}. The caption bar contains a handle, back button, and
- * close button.
+ * {@link DesktopModeWindowDecorViewModel}.
*
* The shadow's thickness is 20dp when the window is in focus and 5dp when the window isn't.
*/
public class DesktopModeWindowDecoration extends WindowDecoration<WindowDecorLinearLayout> {
private static final String TAG = "DesktopModeWindowDecoration";
+
private final Handler mHandler;
private final Choreographer mChoreographer;
private final SyncTransactionQueue mSyncQueue;
+ private DesktopModeWindowDecorationViewHolder mWindowDecorViewHolder;
private View.OnClickListener mOnCaptionButtonClickListener;
private View.OnTouchListener mOnCaptionTouchListener;
private DragPositioningCallback mDragPositioningCallback;
@@ -73,7 +72,6 @@
private final WindowDecoration.RelayoutResult<WindowDecorLinearLayout> mResult =
new WindowDecoration.RelayoutResult<>();
- private boolean mDesktopActive;
private AdditionalWindow mHandleMenu;
private final int mHandleMenuWidthId = R.dimen.freeform_decor_caption_menu_width;
private final int mHandleMenuShadowRadiusId = R.dimen.caption_menu_shadow_radius;
@@ -94,7 +92,6 @@
mHandler = handler;
mChoreographer = choreographer;
mSyncQueue = syncQueue;
- mDesktopActive = DesktopModeStatus.isActive(mContext);
}
@Override
@@ -152,9 +149,11 @@
final int outsetRightId = R.dimen.freeform_resize_handle;
final int outsetBottomId = R.dimen.freeform_resize_handle;
+ final int windowDecorLayoutId = getDesktopModeWindowDecorLayoutId(
+ taskInfo.getWindowingMode());
mRelayoutParams.reset();
mRelayoutParams.mRunningTaskInfo = taskInfo;
- mRelayoutParams.mLayoutResId = R.layout.desktop_mode_window_decor;
+ mRelayoutParams.mLayoutResId = windowDecorLayoutId;
mRelayoutParams.mCaptionHeightId = R.dimen.freeform_decor_caption_height;
mRelayoutParams.mShadowRadiusId = shadowRadiusID;
if (isDragResizeable) {
@@ -172,24 +171,28 @@
return;
}
if (oldRootView != mResult.mRootView) {
- setupRootView();
- }
-
- // If this task is not focused, do not show caption.
- setCaptionVisibility(mTaskInfo.isFocused);
-
- if (mTaskInfo.isFocused) {
- if (DesktopModeStatus.isProto2Enabled()) {
- updateButtonVisibility();
- } else if (DesktopModeStatus.isProto1Enabled()) {
- // Only handle should show if Desktop Mode is inactive.
- boolean desktopCurrentStatus = DesktopModeStatus.isActive(mContext);
- if (mDesktopActive != desktopCurrentStatus) {
- mDesktopActive = desktopCurrentStatus;
- setButtonVisibility(mDesktopActive);
- }
+ if (mRelayoutParams.mLayoutResId == R.layout.desktop_mode_focused_window_decor) {
+ mWindowDecorViewHolder = new DesktopModeFocusedWindowDecorationViewHolder(
+ mResult.mRootView,
+ mOnCaptionTouchListener,
+ mOnCaptionButtonClickListener
+ );
+ } else if (mRelayoutParams.mLayoutResId
+ == R.layout.desktop_mode_app_controls_window_decor) {
+ mWindowDecorViewHolder = new DesktopModeAppControlsWindowDecorationViewHolder(
+ mResult.mRootView,
+ mOnCaptionTouchListener,
+ mOnCaptionButtonClickListener
+ );
+ } else {
+ throw new IllegalArgumentException("Unexpected layout resource id");
}
}
+ mWindowDecorViewHolder.bindData(mTaskInfo);
+
+ if (!mTaskInfo.isFocused) {
+ closeHandleMenu();
+ }
if (!isDragResizeable) {
closeDragResizeListener();
@@ -219,24 +222,6 @@
mResult.mWidth, mResult.mHeight, resize_handle, resize_corner, touchSlop);
}
- /**
- * Sets up listeners when a new root view is created.
- */
- private void setupRootView() {
- final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- caption.setOnTouchListener(mOnCaptionTouchListener);
- final View handle = caption.findViewById(R.id.caption_handle);
- handle.setOnTouchListener(mOnCaptionTouchListener);
- handle.setOnClickListener(mOnCaptionButtonClickListener);
- if (DesktopModeStatus.isProto1Enabled()) {
- final View back = caption.findViewById(R.id.back_button);
- back.setOnClickListener(mOnCaptionButtonClickListener);
- final View close = caption.findViewById(R.id.close_window);
- close.setOnClickListener(mOnCaptionButtonClickListener);
- }
- updateButtonVisibility();
- }
-
private void setupHandleMenu() {
final View menu = mHandleMenu.mWindowViewHost.getView();
final View fullscreen = menu.findViewById(R.id.fullscreen_button);
@@ -255,98 +240,26 @@
collapse.setOnClickListener(mOnCaptionButtonClickListener);
menu.setOnTouchListener(mOnCaptionTouchListener);
- String packageName = mTaskInfo.baseActivity.getPackageName();
- PackageManager pm = mContext.getApplicationContext().getPackageManager();
- // TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
- try {
- ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName,
- PackageManager.ApplicationInfoFlags.of(0));
- final ImageView appIcon = menu.findViewById(R.id.application_icon);
- appIcon.setImageDrawable(pm.getApplicationIcon(applicationInfo));
- final TextView appName = menu.findViewById(R.id.application_name);
- appName.setText(pm.getApplicationLabel(applicationInfo));
- } catch (PackageManager.NameNotFoundException e) {
- Log.w(TAG, "Package not found: " + packageName, e);
- }
- }
-
- /**
- * Sets caption visibility based on task focus.
- * Note: Only applicable to Desktop Proto 1; Proto 2 only closes handle menu on focus loss
- * @param visible whether or not the caption should be visible
- */
- private void setCaptionVisibility(boolean visible) {
- if (!visible) closeHandleMenu();
- if (!DesktopModeStatus.isProto1Enabled()) return;
- final int v = visible ? View.VISIBLE : View.GONE;
- final View captionView = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- captionView.setVisibility(v);
-
- }
-
- /**
- * Sets the visibility of buttons and color of caption based on desktop mode status
- */
- void updateButtonVisibility() {
- if (DesktopModeStatus.isProto2Enabled()) {
- setButtonVisibility(mTaskInfo.getWindowingMode() == WINDOWING_MODE_FREEFORM);
- } else if (DesktopModeStatus.isProto1Enabled()) {
- mDesktopActive = DesktopModeStatus.isActive(mContext);
- setButtonVisibility(mDesktopActive);
- }
- }
-
- /**
- * Show or hide buttons
- */
- void setButtonVisibility(boolean visible) {
- final int visibility = visible && DesktopModeStatus.isProto1Enabled()
- ? View.VISIBLE : View.GONE;
- final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- final View back = caption.findViewById(R.id.back_button);
- final View close = caption.findViewById(R.id.close_window);
- back.setVisibility(visibility);
- close.setVisibility(visibility);
- final int buttonTintColorRes =
- mDesktopActive ? R.color.decor_button_dark_color
- : R.color.decor_button_light_color;
- final ColorStateList buttonTintColor =
- caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
- final View handle = caption.findViewById(R.id.caption_handle);
- final VectorDrawable handleBackground = (VectorDrawable) handle.getBackground();
- handleBackground.setTintList(buttonTintColor);
+ final ImageView appIcon = menu.findViewById(R.id.application_icon);
+ final TextView appName = menu.findViewById(R.id.application_name);
+ loadAppInfo(appName, appIcon);
}
boolean isHandleMenuActive() {
return mHandleMenu != null;
}
- void setCaptionColor(int captionColor) {
- if (mResult.mRootView == null) {
- return;
- }
-
- final View caption = mResult.mRootView.findViewById(R.id.desktop_mode_caption);
- final GradientDrawable captionDrawable = (GradientDrawable) caption.getBackground();
- captionDrawable.setColor(captionColor);
-
- final int buttonTintColorRes =
- Color.valueOf(captionColor).luminance() < 0.5
- ? R.color.decor_button_light_color
- : R.color.decor_button_dark_color;
- final ColorStateList buttonTintColor =
- caption.getResources().getColorStateList(buttonTintColorRes, null /* theme */);
-
- final View handle = caption.findViewById(R.id.caption_handle);
- final Drawable handleBackground = handle.getBackground();
- handleBackground.setTintList(buttonTintColor);
- if (DesktopModeStatus.isProto1Enabled()) {
- final View back = caption.findViewById(R.id.back_button);
- final Drawable backBackground = back.getBackground();
- backBackground.setTintList(buttonTintColor);
- final View close = caption.findViewById(R.id.close_window);
- final Drawable closeBackground = close.getBackground();
- closeBackground.setTintList(buttonTintColor);
+ private void loadAppInfo(TextView appNameTextView, ImageView appIconImageView) {
+ String packageName = mTaskInfo.realActivity.getPackageName();
+ PackageManager pm = mContext.getApplicationContext().getPackageManager();
+ try {
+ // TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
+ ApplicationInfo applicationInfo = pm.getApplicationInfo(packageName,
+ PackageManager.ApplicationInfoFlags.of(0));
+ appNameTextView.setText(pm.getApplicationLabel(applicationInfo));
+ appIconImageView.setImageDrawable(pm.getApplicationIcon(applicationInfo));
+ } catch (PackageManager.NameNotFoundException e) {
+ Log.w(TAG, "Package not found: " + packageName, e);
}
}
@@ -371,9 +284,18 @@
final int shadowRadius = loadDimensionPixelSize(resources, mHandleMenuShadowRadiusId);
final int cornerRadius = loadDimensionPixelSize(resources, mHandleMenuCornerRadiusId);
- final int x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
- - mResult.mDecorContainerOffsetX;
- final int y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
+ final int x, y;
+ if (mRelayoutParams.mLayoutResId
+ == R.layout.desktop_mode_app_controls_window_decor) {
+ // Align the handle menu to the left of the caption.
+ x = mRelayoutParams.mCaptionX - mResult.mDecorContainerOffsetX;
+ y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
+ } else {
+ // Position the handle menu at the center of the caption.
+ x = mRelayoutParams.mCaptionX + (captionWidth / 2) - (menuWidth / 2)
+ - mResult.mDecorContainerOffsetX;
+ y = mRelayoutParams.mCaptionY - mResult.mDecorContainerOffsetY;
+ }
mHandleMenuPosition.set(x, y);
String namePrefix = "Caption Menu";
mHandleMenu = addWindow(R.layout.desktop_mode_decor_handle_menu, namePrefix, t, x, y,
@@ -503,6 +425,15 @@
super.close();
}
+ private int getDesktopModeWindowDecorLayoutId(int windowingMode) {
+ if (DesktopModeStatus.isProto1Enabled()) {
+ return R.layout.desktop_mode_app_controls_window_decor;
+ }
+ return windowingMode == WINDOWING_MODE_FREEFORM
+ ? R.layout.desktop_mode_app_controls_window_decor
+ : R.layout.desktop_mode_focused_window_decor;
+ }
+
static class Factory {
DesktopModeWindowDecoration create(
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
index 0a9c331..8cb575c 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/DragResizeInputListener.java
@@ -103,6 +103,7 @@
null /* hostInputToken */,
FLAG_NOT_FOCUSABLE,
PRIVATE_FLAG_TRUSTED_OVERLAY,
+ 0 /* inputFeatures */,
TYPE_APPLICATION,
null /* windowToken */,
mFocusGrantToken,
@@ -208,6 +209,7 @@
mDecorationSurface,
FLAG_NOT_FOCUSABLE,
PRIVATE_FLAG_TRUSTED_OVERLAY,
+ 0 /* inputFeatures */,
touchRegion);
} catch (RemoteException e) {
e.rethrowFromSystemServer();
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
index ddd3b44..31e93ac 100644
--- a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/WindowDecoration.java
@@ -84,6 +84,7 @@
};
RunningTaskInfo mTaskInfo;
+ int mLayoutResId;
final SurfaceControl mTaskSurface;
Display mDisplay;
@@ -162,6 +163,8 @@
if (params.mRunningTaskInfo != null) {
mTaskInfo = params.mRunningTaskInfo;
}
+ final int oldLayoutResId = mLayoutResId;
+ mLayoutResId = params.mLayoutResId;
if (!mTaskInfo.isVisible) {
releaseViews();
@@ -178,7 +181,8 @@
final Configuration taskConfig = getConfigurationWithOverrides(mTaskInfo);
if (oldTaskConfig.densityDpi != taskConfig.densityDpi
|| mDisplay == null
- || mDisplay.getDisplayId() != mTaskInfo.displayId) {
+ || mDisplay.getDisplayId() != mTaskInfo.displayId
+ || oldLayoutResId != mLayoutResId) {
releaseViews();
if (!obtainDisplayOrRegisterListener()) {
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
new file mode 100644
index 0000000..95b5051
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeAppControlsWindowDecorationViewHolder.kt
@@ -0,0 +1,94 @@
+package com.android.wm.shell.windowdecor.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.pm.PackageManager
+import android.content.res.ColorStateList
+import android.graphics.drawable.GradientDrawable
+import android.util.Log
+import android.view.View
+import android.widget.ImageButton
+import android.widget.ImageView
+import android.widget.TextView
+import com.android.wm.shell.R
+
+/**
+ * A desktop mode window decoration used when the window is floating (i.e. freeform). It hosts
+ * finer controls such as a close window button and an "app info" section to pull up additional
+ * controls.
+ */
+internal class DesktopModeAppControlsWindowDecorationViewHolder(
+ rootView: View,
+ onCaptionTouchListener: View.OnTouchListener,
+ onCaptionButtonClickListener: View.OnClickListener
+) : DesktopModeWindowDecorationViewHolder(rootView) {
+
+ private val captionView: View = rootView.findViewById(R.id.desktop_mode_caption)
+ private val captionHandle: View = rootView.findViewById(R.id.caption_handle)
+ private val openMenuButton: View = rootView.findViewById(R.id.open_menu_button)
+ private val closeWindowButton: ImageButton = rootView.findViewById(R.id.close_window)
+ private val expandMenuButton: ImageButton = rootView.findViewById(R.id.expand_menu_button)
+ private val appNameTextView: TextView = rootView.findViewById(R.id.application_name)
+ private val appIconImageView: ImageView = rootView.findViewById(R.id.application_icon)
+
+ init {
+ captionView.setOnTouchListener(onCaptionTouchListener)
+ captionHandle.setOnTouchListener(onCaptionTouchListener)
+ openMenuButton.setOnClickListener(onCaptionButtonClickListener)
+ closeWindowButton.setOnClickListener(onCaptionButtonClickListener)
+ }
+
+ override fun bindData(taskInfo: RunningTaskInfo) {
+ bindAppInfo(taskInfo)
+
+ val captionDrawable = captionView.background as GradientDrawable
+ captionDrawable.setColor(taskInfo.taskDescription.statusBarColor)
+
+ closeWindowButton.imageTintList = ColorStateList.valueOf(
+ getCaptionCloseButtonColor(taskInfo))
+ expandMenuButton.imageTintList = ColorStateList.valueOf(
+ getCaptionExpandButtonColor(taskInfo))
+ appNameTextView.setTextColor(getCaptionAppNameTextColor(taskInfo))
+ }
+
+ private fun bindAppInfo(taskInfo: RunningTaskInfo) {
+ val packageName: String = taskInfo.realActivity.packageName
+ val pm: PackageManager = context.applicationContext.packageManager
+ try {
+ // TODO(b/268363572): Use IconProvider or BaseIconCache to set drawable/name.
+ val applicationInfo = pm.getApplicationInfo(packageName,
+ PackageManager.ApplicationInfoFlags.of(0))
+ appNameTextView.text = pm.getApplicationLabel(applicationInfo)
+ appIconImageView.setImageDrawable(pm.getApplicationIcon(applicationInfo))
+ } catch (e: PackageManager.NameNotFoundException) {
+ Log.w(TAG, "Package not found: $packageName", e)
+ }
+ }
+
+ private fun getCaptionAppNameTextColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_app_name_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_app_name_dark)
+ }
+ }
+
+ private fun getCaptionCloseButtonColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_close_button_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_close_button_dark)
+ }
+ }
+
+ private fun getCaptionExpandButtonColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_expand_button_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_expand_button_dark)
+ }
+ }
+
+ companion object {
+ private const val TAG = "DesktopModeAppControlsWindowDecorationViewHolder"
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt
new file mode 100644
index 0000000..47a12a0
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeFocusedWindowDecorationViewHolder.kt
@@ -0,0 +1,44 @@
+package com.android.wm.shell.windowdecor.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.res.ColorStateList
+import android.graphics.drawable.GradientDrawable
+import android.view.View
+import android.widget.ImageButton
+import com.android.wm.shell.R
+
+/**
+ * A desktop mode window decoration used when the window is in full "focus" (i.e. fullscreen). It
+ * hosts a simple handle bar from which to initiate a drag motion to enter desktop mode.
+ */
+internal class DesktopModeFocusedWindowDecorationViewHolder(
+ rootView: View,
+ onCaptionTouchListener: View.OnTouchListener,
+ onCaptionButtonClickListener: View.OnClickListener
+) : DesktopModeWindowDecorationViewHolder(rootView) {
+
+ private val captionView: View = rootView.findViewById(R.id.desktop_mode_caption)
+ private val captionHandle: ImageButton = rootView.findViewById(R.id.caption_handle)
+
+ init {
+ captionView.setOnTouchListener(onCaptionTouchListener)
+ captionHandle.setOnTouchListener(onCaptionTouchListener)
+ captionHandle.setOnClickListener(onCaptionButtonClickListener)
+ }
+
+ override fun bindData(taskInfo: RunningTaskInfo) {
+ val captionColor = taskInfo.taskDescription.statusBarColor
+ val captionDrawable = captionView.background as GradientDrawable
+ captionDrawable.setColor(captionColor)
+
+ captionHandle.imageTintList = ColorStateList.valueOf(getCaptionHandleBarColor(taskInfo))
+ }
+
+ private fun getCaptionHandleBarColor(taskInfo: RunningTaskInfo): Int {
+ return if (shouldUseLightCaptionColors(taskInfo)) {
+ context.getColor(R.color.desktop_mode_caption_handle_bar_light)
+ } else {
+ context.getColor(R.color.desktop_mode_caption_handle_bar_dark)
+ }
+ }
+}
diff --git a/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt
new file mode 100644
index 0000000..514ea52
--- /dev/null
+++ b/libs/WindowManager/Shell/src/com/android/wm/shell/windowdecor/viewholder/DesktopModeWindowDecorationViewHolder.kt
@@ -0,0 +1,28 @@
+package com.android.wm.shell.windowdecor.viewholder
+
+import android.app.ActivityManager.RunningTaskInfo
+import android.content.Context
+import android.graphics.Color
+import android.view.View
+
+/**
+ * Encapsulates the root [View] of a window decoration and its children to facilitate looking up
+ * children (via findViewById) and updating to the latest data from [RunningTaskInfo].
+ */
+internal abstract class DesktopModeWindowDecorationViewHolder(rootView: View) {
+ val context: Context = rootView.context
+
+ /**
+ * A signal to the view holder that new data is available and that the views should be updated
+ * to reflect it.
+ */
+ abstract fun bindData(taskInfo: RunningTaskInfo)
+
+ /**
+ * Whether the caption items should use the 'light' color variant so that there's good contrast
+ * with the caption background color.
+ */
+ protected fun shouldUseLightCaptionColors(taskInfo: RunningTaskInfo): Boolean {
+ return Color.valueOf(taskInfo.taskDescription.statusBarColor).luminance() < 0.5
+ }
+}
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
index 7cf7314..f52e877 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipOnUserLeaveHintTest.kt
@@ -16,7 +16,6 @@
package com.android.wm.shell.flicker.pip
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
@@ -73,7 +72,6 @@
super.pipAppWindowAlwaysVisible()
}
- @FlakyTest(bugId = 271878066)
@Presubmit
@Test
override fun pipAppLayerAlwaysVisible() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
index 1477ce0..e40e5ea 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/pip/EnterPipTransition.kt
@@ -16,7 +16,6 @@
package com.android.wm.shell.flicker.pip
-import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
import android.tools.common.datatypes.component.ComponentNameMatcher
@@ -42,7 +41,6 @@
}
/** Checks [pipApp] layer remains visible throughout the animation */
- @FlakyTest(bugId = 271878066)
@Presubmit
@Test
open fun pipAppLayerAlwaysVisible() {
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
index ffdb87f..5b06c9c 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromAllApps.kt
@@ -79,7 +79,8 @@
@IwTest(focusArea = "sysui")
@Presubmit
@Test
- fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = false)
+ fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = false,
+ appExistAtStart = false)
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
index 792e2b0..c840183 100644
--- a/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
+++ b/libs/WindowManager/Shell/tests/flicker/src/com/android/wm/shell/flicker/splitscreen/EnterSplitScreenByDragFromNotification.kt
@@ -82,7 +82,8 @@
@IwTest(focusArea = "sysui")
@Presubmit
@Test
- fun cujCompleted() = flicker.splitScreenEntered(primaryApp, secondaryApp, fromOtherApp = false)
+ fun cujCompleted() = flicker.splitScreenEntered(primaryApp, sendNotificationApp,
+ fromOtherApp = false)
@Presubmit
@Test
diff --git a/libs/WindowManager/Shell/tests/unittest/Android.bp b/libs/WindowManager/Shell/tests/unittest/Android.bp
index 2ac1dc0..57a6981 100644
--- a/libs/WindowManager/Shell/tests/unittest/Android.bp
+++ b/libs/WindowManager/Shell/tests/unittest/Android.bp
@@ -69,6 +69,8 @@
enabled: false,
},
+ test_suites: ["device-tests"],
+
platform_apis: true,
certificate: "platform",
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
index 6dae479..169b9bd 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/back/BackAnimationControllerTest.java
@@ -411,6 +411,53 @@
verify(mAnimatorCallback, never()).onBackInvoked();
}
+ @Test
+ public void testBackToActivity() throws RemoteException {
+ final CrossActivityAnimation animation = new CrossActivityAnimation(mContext,
+ mAnimationBackground);
+ verifySystemBackBehavior(
+ BackNavigationInfo.TYPE_CROSS_ACTIVITY, animation.mBackAnimationRunner);
+ }
+
+ @Test
+ public void testBackToTask() throws RemoteException {
+ final CrossTaskBackAnimation animation = new CrossTaskBackAnimation(mContext,
+ mAnimationBackground);
+ verifySystemBackBehavior(
+ BackNavigationInfo.TYPE_CROSS_TASK, animation.mBackAnimationRunner);
+ }
+
+ private void verifySystemBackBehavior(int type, BackAnimationRunner animation)
+ throws RemoteException {
+ final BackAnimationRunner animationRunner = spy(animation);
+ final IRemoteAnimationRunner runner = spy(animationRunner.getRunner());
+ final IOnBackInvokedCallback callback = spy(animationRunner.getCallback());
+
+ // Set up the monitoring objects.
+ doNothing().when(runner).onAnimationStart(anyInt(), any(), any(), any(), any());
+ doReturn(runner).when(animationRunner).getRunner();
+ doReturn(callback).when(animationRunner).getCallback();
+
+ mController.registerAnimation(type, animationRunner);
+
+ createNavigationInfo(type, true);
+
+ doMotionEvent(MotionEvent.ACTION_DOWN, 0);
+
+ // Check that back start and progress is dispatched when first move.
+ doMotionEvent(MotionEvent.ACTION_MOVE, 100);
+
+ simulateRemoteAnimationStart(type);
+
+ verify(callback).onBackStarted(any(BackMotionEvent.class));
+ verify(animationRunner).startAnimation(any(), any(), any(), any());
+
+ // Check that back invocation is dispatched.
+ mController.setTriggerBack(true); // Fake trigger back
+ doMotionEvent(MotionEvent.ACTION_UP, 0);
+ verify(callback).onBackInvoked();
+ }
+
private void doMotionEvent(int actionDown, int coordinate) {
mController.onMotionEvent(
coordinate, coordinate,
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
index 8b025cd..919bf06 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/bubbles/BubbleDataTest.java
@@ -185,7 +185,8 @@
Intent appBubbleIntent = new Intent(mContext, BubblesTestActivity.class);
appBubbleIntent.setPackage(mContext.getPackageName());
- mAppBubble = new Bubble(appBubbleIntent, new UserHandle(1), mMainExecutor);
+ mAppBubble = new Bubble(appBubbleIntent, new UserHandle(1), mock(Icon.class),
+ mMainExecutor);
mPositioner = new TestableBubblePositioner(mContext,
mock(WindowManager.class));
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
index bc0d93a..a6501f0 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/CompatUIControllerTest.java
@@ -54,7 +54,6 @@
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.ShellExecutor;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.compatui.letterboxedu.LetterboxEduWindowManager;
import com.android.wm.shell.sysui.ShellController;
import com.android.wm.shell.sysui.ShellInit;
import com.android.wm.shell.transition.Transitions;
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java
similarity index 91%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java
index a58620d..172c263 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduDialogLayoutTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduDialogLayoutTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.compatui.letterboxedu;
+package com.android.wm.shell.compatui;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
@@ -58,9 +58,8 @@
public void setUp() {
MockitoAnnotations.initMocks(this);
- mLayout = (LetterboxEduDialogLayout)
- LayoutInflater.from(mContext).inflate(R.layout.letterbox_education_dialog_layout,
- null);
+ mLayout = (LetterboxEduDialogLayout) LayoutInflater.from(mContext)
+ .inflate(R.layout.letterbox_education_dialog_layout, null);
mDismissButton = mLayout.findViewById(R.id.letterbox_education_dialog_dismiss_button);
mDialogContainer = mLayout.findViewById(R.id.letterbox_education_dialog_container);
mLayout.setDismissOnClickListener(mDismissCallback);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
similarity index 97%
rename from libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
rename to libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
index 14190f1..47c9e06 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/letterboxedu/LetterboxEduWindowManagerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/compatui/LetterboxEduWindowManagerTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2022 The Android Open Source Project
+ * Copyright (C) 2023 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -14,7 +14,7 @@
* limitations under the License.
*/
-package com.android.wm.shell.compatui.letterboxedu;
+package com.android.wm.shell.compatui;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
@@ -56,7 +56,6 @@
import com.android.wm.shell.common.DisplayLayout;
import com.android.wm.shell.common.DockStateReader;
import com.android.wm.shell.common.SyncTransactionQueue;
-import com.android.wm.shell.compatui.DialogAnimationController;
import com.android.wm.shell.transition.Transitions;
import org.junit.After;
@@ -400,15 +399,16 @@
false, isDocked);
}
- private LetterboxEduWindowManager createWindowManager(boolean eligible,
- int userId, boolean isTaskbarEduShowing) {
+ private LetterboxEduWindowManager createWindowManager(boolean eligible, int userId,
+ boolean isTaskbarEduShowing) {
return createWindowManager(eligible, userId, isTaskbarEduShowing, /* isDocked */false);
}
- private LetterboxEduWindowManager createWindowManager(boolean eligible,
- int userId, boolean isTaskbarEduShowing, boolean isDocked) {
+ private LetterboxEduWindowManager createWindowManager(boolean eligible, int userId,
+ boolean isTaskbarEduShowing, boolean isDocked) {
doReturn(isDocked).when(mDockStateReader).isDocked();
- LetterboxEduWindowManager windowManager = new LetterboxEduWindowManager(mContext,
+ LetterboxEduWindowManager
+ windowManager = new LetterboxEduWindowManager(mContext,
createTaskInfo(eligible, userId), mSyncTransactionQueue, mTaskListener,
createDisplayLayout(), mTransitions, mOnDismissCallback,
mAnimationController, mDockStateReader);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
index ecfb427..58e91cb 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/kidsmode/KidsModeTaskOrganizerTest.java
@@ -31,6 +31,7 @@
import android.app.ActivityManager;
import android.content.Context;
import android.content.pm.ParceledListSlice;
+import android.content.res.Resources;
import android.os.Handler;
import android.os.IBinder;
import android.os.RemoteException;
@@ -77,6 +78,7 @@
@Mock private ShellInit mShellInit;
@Mock private ShellCommandHandler mShellCommandHandler;
@Mock private DisplayInsetsController mDisplayInsetsController;
+ @Mock private Resources mResources;
KidsModeTaskOrganizer mOrganizer;
@@ -89,10 +91,12 @@
} catch (RemoteException e) {
}
// NOTE: KidsModeTaskOrganizer should have a null CompatUIController.
- mOrganizer = spy(new KidsModeTaskOrganizer(mContext, mShellInit, mShellCommandHandler,
- mTaskOrganizerController, mSyncTransactionQueue, mDisplayController,
- mDisplayInsetsController, Optional.empty(), Optional.empty(), mObserver,
- mTestExecutor, mHandler));
+ doReturn(mResources).when(mContext).getResources();
+ final KidsModeTaskOrganizer kidsModeTaskOrganizer = new KidsModeTaskOrganizer(mContext,
+ mShellInit, mShellCommandHandler, mTaskOrganizerController, mSyncTransactionQueue,
+ mDisplayController, mDisplayInsetsController, Optional.empty(), Optional.empty(),
+ mObserver, mTestExecutor, mHandler);
+ mOrganizer = spy(kidsModeTaskOrganizer);
doReturn(mTransaction).when(mOrganizer).getWindowContainerTransaction();
doReturn(new InsetsState()).when(mDisplayController).getInsetsState(DEFAULT_DISPLAY);
}
@@ -112,6 +116,8 @@
verify(mOrganizer, times(1)).registerOrganizer();
verify(mOrganizer, times(1)).createRootTask(
eq(DEFAULT_DISPLAY), eq(WINDOWING_MODE_FULLSCREEN), eq(mOrganizer.mCookie));
+ verify(mOrganizer, times(1))
+ .setOrientationRequestPolicy(eq(true), any(), any());
final ActivityManager.RunningTaskInfo rootTask = createTaskInfo(12,
WINDOWING_MODE_FULLSCREEN, mOrganizer.mCookie);
@@ -132,10 +138,11 @@
doReturn(false).when(mObserver).isEnabled();
mOrganizer.updateKidsModeState();
-
verify(mOrganizer, times(1)).disable();
verify(mOrganizer, times(1)).unregisterOrganizer();
verify(mOrganizer, times(1)).deleteRootTask(rootTask.token);
+ verify(mOrganizer, times(1))
+ .setOrientationRequestPolicy(eq(false), any(), any());
assertThat(mOrganizer.mLaunchRootLeash).isNull();
assertThat(mOrganizer.mLaunchRootTask).isNull();
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
index 108e273..6995d10 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipControllerTest.java
@@ -318,6 +318,7 @@
@Test
public void onKeepClearAreasChanged_featureDisabled_pipBoundsStateDoesntChange() {
+ mPipController.setEnablePipKeepClearAlgorithm(false);
final int displayId = 1;
final Rect keepClearArea = new Rect(0, 0, 10, 10);
when(mMockPipDisplayLayoutState.getDisplayId()).thenReturn(displayId);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
index d36060f..10b1ddf 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/pip/phone/PipTouchHandlerTest.java
@@ -175,6 +175,7 @@
@Test
public void updateMovementBounds_withImeAdjustment_movesPip() {
+ mPipTouchHandler.setEnablePipKeepClearAlgorithm(false);
mFromImeAdjustment = true;
mPipTouchHandler.onImeVisibilityChanged(true /* imeVisible */, mImeHeight);
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
index 3901dab..df78d92 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/SplitTransitionTests.java
@@ -35,6 +35,7 @@
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -249,7 +250,7 @@
@Test
@UiThreadTest
- public void testEnterRecents() {
+ public void testEnterRecentsAndCommit() {
enterSplit();
ActivityManager.RunningTaskInfo homeTask = new TestRunningTaskInfoBuilder()
@@ -258,27 +259,65 @@
.build();
// Create a request to bring home forward
- TransitionRequestInfo request = new TransitionRequestInfo(TRANSIT_TO_FRONT, homeTask, null);
+ TransitionRequestInfo request = new TransitionRequestInfo(TRANSIT_TO_FRONT, homeTask,
+ mock(RemoteTransition.class));
IBinder transition = mock(IBinder.class);
WindowContainerTransaction result = mStageCoordinator.handleRequest(transition, request);
-
- assertTrue(result.isEmpty());
+ // Don't handle recents opening
+ assertNull(result);
// make sure we haven't made any local changes yet (need to wait until transition is ready)
assertTrue(mStageCoordinator.isSplitScreenVisible());
- // simulate the transition
- TransitionInfo info = new TransitionInfoBuilder(TRANSIT_TO_FRONT, 0)
- .addChange(TRANSIT_TO_FRONT, homeTask)
- .addChange(TRANSIT_TO_BACK, mMainChild)
- .addChange(TRANSIT_TO_BACK, mSideChild)
- .build();
+ // simulate the start of recents transition
mMainStage.onTaskVanished(mMainChild);
mSideStage.onTaskVanished(mSideChild);
- mStageCoordinator.startAnimation(transition, info,
- mock(SurfaceControl.Transaction.class),
- mock(SurfaceControl.Transaction.class),
- mock(Transitions.TransitionFinishCallback.class));
+ mStageCoordinator.onRecentsInSplitAnimationStart(mock(SurfaceControl.Transaction.class));
+ assertTrue(mStageCoordinator.isSplitScreenVisible());
+
+ // Make sure it cleans-up if recents doesn't restore
+ WindowContainerTransaction commitWCT = new WindowContainerTransaction();
+ mStageCoordinator.onRecentsInSplitAnimationFinish(commitWCT,
+ mock(SurfaceControl.Transaction.class));
+ assertFalse(mStageCoordinator.isSplitScreenVisible());
+ }
+
+ @Test
+ @UiThreadTest
+ public void testEnterRecentsAndRestore() {
+ enterSplit();
+
+ ActivityManager.RunningTaskInfo homeTask = new TestRunningTaskInfoBuilder()
+ .setWindowingMode(WINDOWING_MODE_FULLSCREEN)
+ .setActivityType(ACTIVITY_TYPE_HOME)
+ .build();
+
+ // Create a request to bring home forward
+ TransitionRequestInfo request = new TransitionRequestInfo(TRANSIT_TO_FRONT, homeTask,
+ mock(RemoteTransition.class));
+ IBinder transition = mock(IBinder.class);
+ WindowContainerTransaction result = mStageCoordinator.handleRequest(transition, request);
+ // Don't handle recents opening
+ assertNull(result);
+
+ // make sure we haven't made any local changes yet (need to wait until transition is ready)
+ assertTrue(mStageCoordinator.isSplitScreenVisible());
+
+ // simulate the start of recents transition
+ mMainStage.onTaskVanished(mMainChild);
+ mSideStage.onTaskVanished(mSideChild);
+ mStageCoordinator.onRecentsInSplitAnimationStart(mock(SurfaceControl.Transaction.class));
+ assertTrue(mStageCoordinator.isSplitScreenVisible());
+
+ // Make sure we remain in split after recents restores.
+ WindowContainerTransaction restoreWCT = new WindowContainerTransaction();
+ restoreWCT.reorder(mMainChild.token, true /* toTop */);
+ restoreWCT.reorder(mSideChild.token, true /* toTop */);
+ // simulate the restoreWCT being applied:
+ mMainStage.onTaskAppeared(mMainChild, mock(SurfaceControl.class));
+ mSideStage.onTaskAppeared(mSideChild, mock(SurfaceControl.class));
+ mStageCoordinator.onRecentsInSplitAnimationFinish(restoreWCT,
+ mock(SurfaceControl.Transaction.class));
assertTrue(mStageCoordinator.isSplitScreenVisible());
}
diff --git a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
index 2e2e49e..eda6fdc 100644
--- a/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
+++ b/libs/WindowManager/Shell/tests/unittest/src/com/android/wm/shell/splitscreen/StageCoordinatorTests.java
@@ -145,39 +145,48 @@
}
@Test
- public void testMoveToStage() {
+ public void testMoveToStage_splitActiveBackground() {
+ when(mStageCoordinator.isSplitActive()).thenReturn(true);
+
final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
- mStageCoordinator.moveToStage(task, STAGE_TYPE_MAIN, SPLIT_POSITION_BOTTOM_OR_RIGHT,
- new WindowContainerTransaction());
- verify(mMainStage).addTask(eq(task), any(WindowContainerTransaction.class));
- assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
-
- mStageCoordinator.moveToStage(task, STAGE_TYPE_SIDE, SPLIT_POSITION_BOTTOM_OR_RIGHT,
- new WindowContainerTransaction());
- verify(mSideStage).addTask(eq(task), any(WindowContainerTransaction.class));
+ mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
+ verify(mSideStage).addTask(eq(task), eq(wct));
assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
+ assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
}
@Test
- public void testMoveToUndefinedStage() {
- final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
-
- // Verify move to undefined stage while split screen not activated moves task to side stage.
- when(mStageCoordinator.isSplitScreenVisible()).thenReturn(false);
- mStageCoordinator.setSideStagePosition(SPLIT_POSITION_TOP_OR_LEFT, null);
- mStageCoordinator.moveToStage(task, STAGE_TYPE_UNDEFINED, SPLIT_POSITION_BOTTOM_OR_RIGHT,
- new WindowContainerTransaction());
- verify(mSideStage).addTask(eq(task), any(WindowContainerTransaction.class));
- assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
-
- // Verify move to undefined stage after split screen activated moves task based on position.
+ public void testMoveToStage_splitActiveForeground() {
+ when(mStageCoordinator.isSplitActive()).thenReturn(true);
when(mStageCoordinator.isSplitScreenVisible()).thenReturn(true);
- assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
- mStageCoordinator.moveToStage(task, STAGE_TYPE_UNDEFINED, SPLIT_POSITION_TOP_OR_LEFT,
- new WindowContainerTransaction());
- verify(mMainStage).addTask(eq(task), any(WindowContainerTransaction.class));
- assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getMainStagePosition());
+ // Assume current side stage is top or left.
+ mStageCoordinator.setSideStagePosition(SPLIT_POSITION_TOP_OR_LEFT, null);
+
+ final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+
+ mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
+ verify(mMainStage).addTask(eq(task), eq(wct));
+ assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
+ assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getSideStagePosition());
+
+ mStageCoordinator.moveToStage(task, SPLIT_POSITION_TOP_OR_LEFT, wct);
+ verify(mSideStage).addTask(eq(task), eq(wct));
+ assertEquals(SPLIT_POSITION_TOP_OR_LEFT, mStageCoordinator.getSideStagePosition());
+ assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getMainStagePosition());
+ }
+
+ @Test
+ public void testMoveToStage_splitInctive() {
+ final ActivityManager.RunningTaskInfo task = new TestRunningTaskInfoBuilder().build();
+ final WindowContainerTransaction wct = new WindowContainerTransaction();
+
+ mStageCoordinator.moveToStage(task, SPLIT_POSITION_BOTTOM_OR_RIGHT, wct);
+ verify(mStageCoordinator).prepareEnterSplitScreen(eq(wct), eq(task),
+ eq(SPLIT_POSITION_BOTTOM_OR_RIGHT));
+ assertEquals(SPLIT_POSITION_BOTTOM_OR_RIGHT, mStageCoordinator.getSideStagePosition());
}
@Test
diff --git a/libs/hwui/Properties.cpp b/libs/hwui/Properties.cpp
index 33c9eac..f4fd3a4 100644
--- a/libs/hwui/Properties.cpp
+++ b/libs/hwui/Properties.cpp
@@ -91,6 +91,8 @@
bool Properties::isLowRam = false;
bool Properties::isSystemOrPersistent = false;
+float Properties::maxHdrHeadroomOn8bit = 5.f; // TODO: Refine this number
+
StretchEffectBehavior Properties::stretchEffectBehavior = StretchEffectBehavior::ShaderHWUI;
DrawingEnabled Properties::drawingEnabled = DrawingEnabled::NotInitialized;
@@ -150,6 +152,11 @@
enableWebViewOverlays = base::GetBoolProperty(PROPERTY_WEBVIEW_OVERLAYS_ENABLED, true);
+ auto hdrHeadroom = (float)atof(base::GetProperty(PROPERTY_8BIT_HDR_HEADROOM, "").c_str());
+ if (hdrHeadroom >= 1.f) {
+ maxHdrHeadroomOn8bit = std::min(hdrHeadroom, 100.f);
+ }
+
// call isDrawingEnabled to force loading of the property
isDrawingEnabled();
diff --git a/libs/hwui/Properties.h b/libs/hwui/Properties.h
index ed7175e..24e206b 100644
--- a/libs/hwui/Properties.h
+++ b/libs/hwui/Properties.h
@@ -218,6 +218,8 @@
#define PROPERTY_MEMORY_POLICY "debug.hwui.app_memory_policy"
+#define PROPERTY_8BIT_HDR_HEADROOM "debug.hwui.8bit_hdr_headroom"
+
///////////////////////////////////////////////////////////////////////////////
// Misc
///////////////////////////////////////////////////////////////////////////////
@@ -321,6 +323,8 @@
static bool isLowRam;
static bool isSystemOrPersistent;
+ static float maxHdrHeadroomOn8bit;
+
static StretchEffectBehavior getStretchEffectBehavior() {
return stretchEffectBehavior;
}
diff --git a/libs/hwui/pipeline/skia/ShaderCache.h b/libs/hwui/pipeline/skia/ShaderCache.h
index f5506d6..0492d70 100644
--- a/libs/hwui/pipeline/skia/ShaderCache.h
+++ b/libs/hwui/pipeline/skia/ShaderCache.h
@@ -24,6 +24,7 @@
#include <string>
#include <vector>
+class GrDirectContext;
class SkData;
namespace android {
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index f10b2b2..dd781bb 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -311,7 +311,7 @@
}
switch (mColorMode) {
case ColorMode::Hdr:
- return 3.f; // TODO: Refine this number
+ return Properties::maxHdrHeadroomOn8bit;
case ColorMode::Hdr10:
return 10.f;
default:
diff --git a/libs/input/MouseCursorController.cpp b/libs/input/MouseCursorController.cpp
index c398405..c3ad767 100644
--- a/libs/input/MouseCursorController.cpp
+++ b/libs/input/MouseCursorController.cpp
@@ -53,8 +53,6 @@
mLocked.resolvedPointerType = PointerIconStyle::TYPE_NOT_SPECIFIED;
mLocked.resourcesLoaded = false;
-
- mLocked.buttonState = 0;
}
MouseCursorController::~MouseCursorController() {
@@ -95,22 +93,6 @@
setPositionLocked(mLocked.pointerX + deltaX, mLocked.pointerY + deltaY);
}
-void MouseCursorController::setButtonState(int32_t buttonState) {
-#if DEBUG_MOUSE_CURSOR_UPDATES
- ALOGD("Set button state 0x%08x", buttonState);
-#endif
- std::scoped_lock lock(mLock);
-
- if (mLocked.buttonState != buttonState) {
- mLocked.buttonState = buttonState;
- }
-}
-
-int32_t MouseCursorController::getButtonState() const {
- std::scoped_lock lock(mLock);
- return mLocked.buttonState;
-}
-
void MouseCursorController::setPosition(float x, float y) {
#if DEBUG_MOUSE_CURSOR_UPDATES
ALOGD("Set pointer position to x=%0.3f, y=%0.3f", x, y);
diff --git a/libs/input/MouseCursorController.h b/libs/input/MouseCursorController.h
index 26be2a8..00dc085 100644
--- a/libs/input/MouseCursorController.h
+++ b/libs/input/MouseCursorController.h
@@ -45,8 +45,6 @@
std::optional<FloatRect> getBounds() const;
void move(float deltaX, float deltaY);
- void setButtonState(int32_t buttonState);
- int32_t getButtonState() const;
void setPosition(float x, float y);
FloatPoint getPosition() const;
int32_t getDisplayId() const;
@@ -96,8 +94,6 @@
PointerIconStyle requestedPointerType;
PointerIconStyle resolvedPointerType;
- int32_t buttonState;
-
bool animating{false};
} mLocked GUARDED_BY(mLock);
diff --git a/libs/input/PointerController.cpp b/libs/input/PointerController.cpp
index 544edc2..88e3519 100644
--- a/libs/input/PointerController.cpp
+++ b/libs/input/PointerController.cpp
@@ -136,14 +136,6 @@
mCursorController.move(transformed.x, transformed.y);
}
-void PointerController::setButtonState(int32_t buttonState) {
- mCursorController.setButtonState(buttonState);
-}
-
-int32_t PointerController::getButtonState() const {
- return mCursorController.getButtonState();
-}
-
void PointerController::setPosition(float x, float y) {
const int32_t displayId = mCursorController.getDisplayId();
vec2 transformed;
diff --git a/libs/input/PointerController.h b/libs/input/PointerController.h
index 6d3557c..ca14b6e 100644
--- a/libs/input/PointerController.h
+++ b/libs/input/PointerController.h
@@ -50,21 +50,19 @@
~PointerController() override;
- virtual std::optional<FloatRect> getBounds() const;
- virtual void move(float deltaX, float deltaY);
- virtual void setButtonState(int32_t buttonState);
- virtual int32_t getButtonState() const;
- virtual void setPosition(float x, float y);
- virtual FloatPoint getPosition() const;
- virtual int32_t getDisplayId() const;
- virtual void fade(Transition transition);
- virtual void unfade(Transition transition);
- virtual void setDisplayViewport(const DisplayViewport& viewport);
+ std::optional<FloatRect> getBounds() const override;
+ void move(float deltaX, float deltaY) override;
+ void setPosition(float x, float y) override;
+ FloatPoint getPosition() const override;
+ int32_t getDisplayId() const override;
+ void fade(Transition transition) override;
+ void unfade(Transition transition) override;
+ void setDisplayViewport(const DisplayViewport& viewport) override;
- virtual void setPresentation(Presentation presentation);
- virtual void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
- BitSet32 spotIdBits, int32_t displayId);
- virtual void clearSpots();
+ void setPresentation(Presentation presentation) override;
+ void setSpots(const PointerCoords* spotCoords, const uint32_t* spotIdToIndex,
+ BitSet32 spotIdBits, int32_t displayId) override;
+ void clearSpots() override;
void updatePointerIcon(PointerIconStyle iconId);
void setCustomPointerIcon(const SpriteIcon& icon);
diff --git a/location/java/android/location/ILocationManager.aidl b/location/java/android/location/ILocationManager.aidl
index 42b72d4..72761ef 100644
--- a/location/java/android/location/ILocationManager.aidl
+++ b/location/java/android/location/ILocationManager.aidl
@@ -98,12 +98,16 @@
void addGnssAntennaInfoListener(in IGnssAntennaInfoListener listener, String packageName, @nullable String attributionTag, String listenerId);
void removeGnssAntennaInfoListener(in IGnssAntennaInfoListener listener);
+ @EnforcePermission("INTERACT_ACROSS_USERS")
void addProviderRequestListener(in IProviderRequestListener listener);
void removeProviderRequestListener(in IProviderRequestListener listener);
int getGnssBatchSize();
+ @EnforcePermission("LOCATION_HARDWARE")
void startGnssBatch(long periodNanos, in ILocationListener listener, String packageName, @nullable String attributionTag, String listenerId);
+ @EnforcePermission("LOCATION_HARDWARE")
void flushGnssBatch();
+ @EnforcePermission("LOCATION_HARDWARE")
void stopGnssBatch();
boolean hasProvider(String provider);
@@ -111,7 +115,9 @@
List<String> getProviders(in Criteria criteria, boolean enabledOnly);
String getBestProvider(in Criteria criteria, boolean enabledOnly);
ProviderProperties getProviderProperties(String provider);
+ @EnforcePermission("READ_DEVICE_CONFIG")
boolean isProviderPackage(@nullable String provider, String packageName, @nullable String attributionTag);
+ @EnforcePermission("READ_DEVICE_CONFIG")
List<String> getProviderPackages(String provider);
@EnforcePermission("LOCATION_HARDWARE")
diff --git a/media/java/android/media/AudioManager.java b/media/java/android/media/AudioManager.java
index f9b6ce0..8efd180 100644
--- a/media/java/android/media/AudioManager.java
+++ b/media/java/android/media/AudioManager.java
@@ -6752,7 +6752,7 @@
/**
* @hide
- * Lower media volume to RS1
+ * Lower media volume to RS1 interval
*/
public void lowerVolumeToRs1() {
try {
@@ -6764,13 +6764,13 @@
/**
* @hide
- * @return the RS2 value used for momentary exposure warnings
+ * @return the RS2 upper bound used for momentary exposure warnings
*/
@TestApi
@RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public float getRs2Value() {
try {
- return getService().getRs2Value();
+ return getService().getOutputRs2UpperBound();
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
@@ -6778,13 +6778,13 @@
/**
* @hide
- * Sets the RS2 value used for momentary exposure warnings
+ * Sets the RS2 upper bound used for momentary exposure warnings
*/
@TestApi
@RequiresPermission(Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
public void setRs2Value(float rs2Value) {
try {
- getService().setRs2Value(rs2Value);
+ getService().setOutputRs2UpperBound(rs2Value);
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
diff --git a/media/java/android/media/IAudioService.aidl b/media/java/android/media/IAudioService.aidl
index cebdc82..b251468 100644
--- a/media/java/android/media/IAudioService.aidl
+++ b/media/java/android/media/IAudioService.aidl
@@ -221,6 +221,7 @@
boolean isSurroundFormatEnabled(int audioFormat);
+ @EnforcePermission("WRITE_SETTINGS")
boolean setEncodedSurroundMode(int mode);
int getEncodedSurroundMode(int targetSdkVersion);
@@ -254,6 +255,7 @@
void forceVolumeControlStream(int streamType, IBinder cb);
+ @EnforcePermission("REMOTE_AUDIO_PLAYBACK")
void setRingtonePlayer(IRingtonePlayer player);
IRingtonePlayer getRingtonePlayer();
int getUiSoundsStreamType();
@@ -296,10 +298,10 @@
void lowerVolumeToRs1(String callingPackage);
@EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
- float getRs2Value();
+ float getOutputRs2UpperBound();
@EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
- oneway void setRs2Value(float rs2Value);
+ oneway void setOutputRs2UpperBound(float rs2Value);
@EnforcePermission("MODIFY_AUDIO_SETTINGS_PRIVILEGED")
float getCsd();
@@ -358,6 +360,7 @@
oneway void playerHasOpPlayAudio(in int piid, in boolean hasOpPlayAudio);
+ @EnforcePermission("BLUETOOTH_STACK")
void handleBluetoothActiveDeviceChanged(in BluetoothDevice newDevice,
in BluetoothDevice previousDevice, in BluetoothProfileConnectionInfo info);
diff --git a/media/java/android/media/ThumbnailUtils.java b/media/java/android/media/ThumbnailUtils.java
index 9b238e1..6744359 100644
--- a/media/java/android/media/ThumbnailUtils.java
+++ b/media/java/android/media/ThumbnailUtils.java
@@ -49,6 +49,7 @@
import libcore.io.IoUtils;
import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.Comparator;
@@ -255,17 +256,19 @@
// get orientation
if (MediaFile.isExifMimeType(mimeType)) {
- exif = new ExifInterface(file);
- switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)) {
- case ExifInterface.ORIENTATION_ROTATE_90:
- orientation = 90;
- break;
- case ExifInterface.ORIENTATION_ROTATE_180:
- orientation = 180;
- break;
- case ExifInterface.ORIENTATION_ROTATE_270:
- orientation = 270;
- break;
+ try (FileInputStream is = new FileInputStream(file)) {
+ exif = new ExifInterface(is.getFD());
+ switch (exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, 0)) {
+ case ExifInterface.ORIENTATION_ROTATE_90:
+ orientation = 90;
+ break;
+ case ExifInterface.ORIENTATION_ROTATE_180:
+ orientation = 180;
+ break;
+ case ExifInterface.ORIENTATION_ROTATE_270:
+ orientation = 270;
+ break;
+ }
}
}
diff --git a/media/java/android/media/projection/IMediaProjectionManager.aidl b/media/java/android/media/projection/IMediaProjectionManager.aidl
index c259f9a..97e3ec1 100644
--- a/media/java/android/media/projection/IMediaProjectionManager.aidl
+++ b/media/java/android/media/projection/IMediaProjectionManager.aidl
@@ -39,14 +39,17 @@
+ ".permission.MANAGE_MEDIA_PROJECTION)")
MediaProjectionInfo getActiveProjectionInfo();
+ @EnforcePermission("MANAGE_MEDIA_PROJECTION")
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ ".permission.MANAGE_MEDIA_PROJECTION)")
void stopActiveProjection();
+ @EnforcePermission("MANAGE_MEDIA_PROJECTION")
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ ".permission.MANAGE_MEDIA_PROJECTION)")
void notifyActiveProjectionCapturedContentResized(int width, int height);
+ @EnforcePermission("MANAGE_MEDIA_PROJECTION")
@JavaPassthrough(annotation = "@android.annotation.RequiresPermission(android.Manifest"
+ ".permission.MANAGE_MEDIA_PROJECTION)")
void notifyActiveProjectionCapturedContentVisibilityChanged(boolean isVisible);
diff --git a/media/java/android/media/projection/MediaProjection.java b/media/java/android/media/projection/MediaProjection.java
index 9d0662b..6ed8f09 100644
--- a/media/java/android/media/projection/MediaProjection.java
+++ b/media/java/android/media/projection/MediaProjection.java
@@ -180,6 +180,10 @@
* is registered. If the target SDK is less than
* {@link android.os.Build.VERSION_CODES#UPSIDE_DOWN_CAKE U}, no
* exception is thrown.
+ * @throws SecurityException If attempting to create a new virtual display associated with this
+ * MediaProjection instance after it has been stopped by invoking
+ * {@link #stop()}.
+ *
* @see VirtualDisplay
* @see VirtualDisplay.Callback
*/
diff --git a/media/java/android/media/tv/ITvInputManager.aidl b/media/java/android/media/tv/ITvInputManager.aidl
index 14c020e..901ea46 100644
--- a/media/java/android/media/tv/ITvInputManager.aidl
+++ b/media/java/android/media/tv/ITvInputManager.aidl
@@ -120,6 +120,7 @@
// For TV Message
void notifyTvMessage(in IBinder sessionToken, int type, in Bundle data, int userId);
+ void setTvMessageEnabled(in IBinder sessionToken, int type, boolean enabled, int userId);
// For TV input hardware binding
List<TvInputHardwareInfo> getHardwareList();
diff --git a/media/java/android/media/tv/ITvInputSession.aidl b/media/java/android/media/tv/ITvInputSession.aidl
index a7bd8d3..5246f5c4 100644
--- a/media/java/android/media/tv/ITvInputSession.aidl
+++ b/media/java/android/media/tv/ITvInputSession.aidl
@@ -79,4 +79,5 @@
// For TV messages
void notifyTvMessage(int type, in Bundle data);
+ void setTvMessageEnabled(int type, boolean enabled);
}
diff --git a/media/java/android/media/tv/ITvInputSessionWrapper.java b/media/java/android/media/tv/ITvInputSessionWrapper.java
index 7946baee..3a990b3 100644
--- a/media/java/android/media/tv/ITvInputSessionWrapper.java
+++ b/media/java/android/media/tv/ITvInputSessionWrapper.java
@@ -268,6 +268,7 @@
case DO_SET_TV_MESSAGE_ENABLED: {
SomeArgs args = (SomeArgs) msg.obj;
mTvInputSessionImpl.setTvMessageEnabled((Integer) args.arg1, (Boolean) args.arg2);
+ args.recycle();
break;
}
case DO_REQUEST_AD: {
@@ -280,7 +281,7 @@
}
case DO_NOTIFY_TV_MESSAGE: {
SomeArgs args = (SomeArgs) msg.obj;
- mTvInputSessionImpl.onTvMessageReceived((String) args.arg1, (Bundle) args.arg2);
+ mTvInputSessionImpl.onTvMessageReceived((Integer) args.arg1, (Bundle) args.arg2);
break;
}
default: {
@@ -474,6 +475,12 @@
mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_NOTIFY_TV_MESSAGE, type, data));
}
+ @Override
+ public void setTvMessageEnabled(int type, boolean enabled) {
+ mCaller.executeOrSendMessage(mCaller.obtainMessageOO(DO_SET_TV_MESSAGE_ENABLED, type,
+ enabled));
+ }
+
private final class TvInputEventReceiver extends InputEventReceiver {
TvInputEventReceiver(InputChannel inputChannel, Looper looper) {
super(inputChannel, looper);
diff --git a/media/java/android/media/tv/OWNERS b/media/java/android/media/tv/OWNERS
index fa04293..0b022e5 100644
--- a/media/java/android/media/tv/OWNERS
+++ b/media/java/android/media/tv/OWNERS
@@ -1,6 +1,7 @@
quxiangfang@google.com
shubang@google.com
hgchen@google.com
+qingxun@google.com
# For android remote service
per-file ITvRemoteServiceInput.aidl = file:/media/lib/tvremote/OWNERS
diff --git a/media/java/android/media/tv/TvInputManager.java b/media/java/android/media/tv/TvInputManager.java
index ef2b5a5..f344fd3 100644
--- a/media/java/android/media/tv/TvInputManager.java
+++ b/media/java/android/media/tv/TvInputManager.java
@@ -156,20 +156,51 @@
"android.media.tv.TvInputManager.stream_id";
/**
+ * This value for {@link #TV_MESSAGE_KEY_GROUP_ID} denotes that the message doesn't
+ * belong to any group.
+ */
+ public static final long TV_MESSAGE_GROUP_ID_NONE = -1;
+
+ /**
+ * This constant is used as a {@link Bundle} key for TV messages. This is used to
+ * optionally identify messages that belong together, such as headers and bodies
+ * of the same event. For messages that do not have a group, this value
+ * should be {@link #TV_MESSAGE_GROUP_ID_NONE}.
+ *
+ * <p> As -1 is a reserved value, -1 should not be used as a valid groupId.
+ *
+ * <p> Type: long
+ */
+ public static final String TV_MESSAGE_KEY_GROUP_ID =
+ "android.media.tv.TvInputManager.group_id";
+
+ /**
+ * This is a subtype for TV messages that can be potentially found as a value
+ * at {@link #TV_MESSAGE_KEY_SUBTYPE}. It identifies the subtype of the message
+ * as the watermarking format ATSC A/335.
+ */
+ public static final String TV_MESSAGE_SUBTYPE_WATERMARKING_A335 = "ATSC A/335";
+
+ /**
+ * This is a subtype for TV messages that can be potentially found as a value
+ * at {@link #TV_MESSAGE_KEY_SUBTYPE}. It identifies the subtype of the message
+ * as the CC format CTA 608-E.
+ */
+ public static final String TV_MESSAGE_SUBTYPE_CC_608E = "CTA 608-E";
+
+ /**
* This constant is used as a {@link Bundle} key for TV messages. The value of the key
* identifies the subtype of the data, such as the format of the CC data. The format
* found at this key can then be used to identify how to parse the data at
* {@link #TV_MESSAGE_KEY_RAW_DATA}.
*
- * To parse the raw data bsed on the subtype, please refer to the official documentation of the
- * concerning subtype. For example, for the subtype "ATSC A/335" for watermarking, the
- * document for A/335 from the ATSC standard details how this data is formatted.
- *
- * Some other examples of common formats include:
- * <ul>
- * <li>Watermarking - ATSC A/336</li>
- * <li>Closed Captioning - CTA 608-E</li>
- * </ul>
+ * <p> To parse the raw data based on the subtype, please refer to the official
+ * documentation of the concerning subtype. For example, for the subtype
+ * {@link #TV_MESSAGE_SUBTYPE_WATERMARKING_A335}, the document for A/335 from the ATSC
+ * standard details how this data is formatted. Similarly, the subtype
+ * {@link #TV_MESSAGE_SUBTYPE_CC_608E} is documented in the ANSI/CTA standard for
+ * 608-E. These subtypes are examples of common formats for their respective uses
+ * and other subtypes may exist.
*
* <p> Type: String
*/
@@ -178,7 +209,7 @@
/**
* This constant is used as a {@link Bundle} key for TV messages. The value of the key
- * stores the raw data contained in this TV Message. The format of this data is determined
+ * stores the raw data contained in this TV message. The format of this data is determined
* by the format defined by the subtype, found using the key at
* {@link #TV_MESSAGE_KEY_SUBTYPE}. See {@link #TV_MESSAGE_KEY_SUBTYPE} for more
* information on how to parse this data.
@@ -839,6 +870,7 @@
* @param type The type of message received, such as {@link #TV_MESSAGE_TYPE_WATERMARK}
* @param data The raw data of the message. The bundle keys are:
* {@link TvInputManager#TV_MESSAGE_KEY_STREAM_ID},
+ * {@link TvInputManager#TV_MESSAGE_KEY_GROUP_ID},
* {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE},
* {@link TvInputManager#TV_MESSAGE_KEY_RAW_DATA}.
* See {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE} for more information on
@@ -3273,7 +3305,7 @@
/**
* Sends TV messages to the service for testing purposes
*/
- public void notifyTvMessage(@NonNull @TvMessageType int type, @NonNull Bundle data) {
+ public void notifyTvMessage(int type, Bundle data) {
try {
mService.notifyTvMessage(mToken, type, data, mUserId);
} catch (RemoteException e) {
@@ -3282,6 +3314,17 @@
}
/**
+ * Sets whether the TV message of the specific type should be enabled.
+ */
+ public void setTvMessageEnabled(int type, boolean enabled) {
+ try {
+ mService.setTvMessageEnabled(mToken, type, enabled, mUserId);
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+ }
+
+ /**
* Starts TV program recording in the current recording session.
*
* @param programUri The URI for the TV program to record as a hint, built by
diff --git a/media/java/android/media/tv/TvInputService.java b/media/java/android/media/tv/TvInputService.java
index 4e380c4..85b02ad 100644
--- a/media/java/android/media/tv/TvInputService.java
+++ b/media/java/android/media/tv/TvInputService.java
@@ -1032,6 +1032,7 @@
* {@link TvInputManager#TV_MESSAGE_TYPE_WATERMARK}
* @param data The raw data of the message. The bundle keys are:
* {@link TvInputManager#TV_MESSAGE_KEY_STREAM_ID},
+ * {@link TvInputManager#TV_MESSAGE_KEY_GROUP_ID},
* {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE},
* {@link TvInputManager#TV_MESSAGE_KEY_RAW_DATA}.
* See {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE} for more information on
@@ -1507,12 +1508,13 @@
* {@link TvInputManager#TV_MESSAGE_TYPE_WATERMARK}
* @param data The raw data of the message. The bundle keys are:
* {@link TvInputManager#TV_MESSAGE_KEY_STREAM_ID},
+ * {@link TvInputManager#TV_MESSAGE_KEY_GROUP_ID},
* {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE},
* {@link TvInputManager#TV_MESSAGE_KEY_RAW_DATA}.
* See {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE} for more information on
* how to parse this data.
*/
- public void onTvMessage(@NonNull @TvInputManager.TvMessageType String type,
+ public void onTvMessage(@TvInputManager.TvMessageType int type,
@NonNull Bundle data) {
}
@@ -2065,7 +2067,7 @@
onAdBufferReady(buffer);
}
- void onTvMessageReceived(String type, Bundle data) {
+ void onTvMessageReceived(int type, Bundle data) {
onTvMessage(type, data);
}
diff --git a/media/java/android/media/tv/TvView.java b/media/java/android/media/tv/TvView.java
index 8a886832..a4e5fb6 100644
--- a/media/java/android/media/tv/TvView.java
+++ b/media/java/android/media/tv/TvView.java
@@ -745,6 +745,9 @@
*/
public void setTvMessageEnabled(@TvInputManager.TvMessageType int type,
boolean enabled) {
+ if (mSession != null) {
+ mSession.setTvMessageEnabled(type, enabled);
+ }
}
@Override
@@ -1256,6 +1259,7 @@
* {@link TvInputManager#TV_MESSAGE_TYPE_WATERMARK}
* @param data The raw data of the message. The bundle keys are:
* {@link TvInputManager#TV_MESSAGE_KEY_STREAM_ID},
+ * {@link TvInputManager#TV_MESSAGE_KEY_GROUP_ID},
* {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE},
* {@link TvInputManager#TV_MESSAGE_KEY_RAW_DATA}.
* See {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE} for more information on
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppService.java b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
index 69ff9c6..06dfe4f 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppService.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppService.java
@@ -921,6 +921,7 @@
* {@link TvInputManager#TV_MESSAGE_TYPE_WATERMARK}
* @param data The raw data of the message. The bundle keys are:
* {@link TvInputManager#TV_MESSAGE_KEY_STREAM_ID},
+ * {@link TvInputManager#TV_MESSAGE_KEY_GROUP_ID},
* {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE},
* {@link TvInputManager#TV_MESSAGE_KEY_RAW_DATA}.
* See {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE} for more information on
diff --git a/media/java/android/media/tv/interactive/TvInteractiveAppView.java b/media/java/android/media/tv/interactive/TvInteractiveAppView.java
index 80a1435..cbaf5e4 100755
--- a/media/java/android/media/tv/interactive/TvInteractiveAppView.java
+++ b/media/java/android/media/tv/interactive/TvInteractiveAppView.java
@@ -946,6 +946,7 @@
* {@link TvInputManager#TV_MESSAGE_TYPE_WATERMARK}
* @param data The raw data of the message. The bundle keys are:
* {@link TvInputManager#TV_MESSAGE_KEY_STREAM_ID},
+ * {@link TvInputManager#TV_MESSAGE_KEY_GROUP_ID},
* {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE},
* {@link TvInputManager#TV_MESSAGE_KEY_RAW_DATA}.
* See {@link TvInputManager#TV_MESSAGE_KEY_SUBTYPE} for more information on
diff --git a/media/jni/android_media_tv_Tuner.cpp b/media/jni/android_media_tv_Tuner.cpp
index 7f4c03b..6f67d68 100644
--- a/media/jni/android_media_tv_Tuner.cpp
+++ b/media/jni/android_media_tv_Tuner.cpp
@@ -617,8 +617,6 @@
void FilterClientCallbackImpl::getSectionEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/SectionEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIJ)V");
const DemuxFilterSectionEvent §ionEvent = event.get<DemuxFilterEvent::Tag::section>();
jint tableId = sectionEvent.tableId;
@@ -626,23 +624,15 @@
jint sectionNum = sectionEvent.sectionNum;
jlong dataLength = sectionEvent.dataLength;
- jobject obj = env->NewObject(eventClazz, eventInit, tableId, version, sectionNum, dataLength);
+ jobject obj = env->NewObject(mSectionEventClass, mSectionEventInitID, tableId, version,
+ sectionNum, dataLength);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::getMediaEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MediaEvent");
- jmethodID eventInit = env->GetMethodID(
- eventClazz,
- "<init>",
- "(IZJZJJJLandroid/media/MediaCodec$LinearBlock;"
- "ZJIZILandroid/media/tv/tuner/filter/AudioDescriptor;"
- "Ljava/util/List;)V");
- jfieldID eventContext = env->GetFieldID(eventClazz, "mNativeContext", "J");
const DemuxFilterMediaEvent &mediaEvent = event.get<DemuxFilterEvent::Tag::media>();
jobject audioDescriptor = nullptr;
@@ -650,8 +640,6 @@
jobject presentationsJObj = JAudioPresentationInfo::asJobject(env, gAudioPresentationFields);
switch (mediaEvent.extraMetaData.getTag()) {
case DemuxFilterMediaEventExtraMetaData::Tag::audio: {
- jclass adClazz = env->FindClass("android/media/tv/tuner/filter/AudioDescriptor");
- jmethodID adInit = env->GetMethodID(adClazz, "<init>", "(BBCBBB)V");
const AudioExtraMetaData &ad =
mediaEvent.extraMetaData.get<DemuxFilterMediaEventExtraMetaData::Tag::audio>();
@@ -662,9 +650,9 @@
jbyte adGainFront = ad.adGainFront;
jbyte adGainSurround = ad.adGainSurround;
- audioDescriptor = env->NewObject(adClazz, adInit, adFade, adPan, versionTextTag,
- adGainCenter, adGainFront, adGainSurround);
- env->DeleteLocalRef(adClazz);
+ audioDescriptor = env->NewObject(mAudioDescriptorClass, mAudioDescriptorInitID, adFade,
+ adPan, versionTextTag, adGainCenter, adGainFront,
+ adGainSurround);
break;
}
case DemuxFilterMediaEventExtraMetaData::Tag::audioPresentations: {
@@ -705,10 +693,10 @@
sc = mediaEvent.scIndexMask.get<DemuxFilterScIndexMask::Tag::scVvc>();
}
- jobject obj = env->NewObject(eventClazz, eventInit, streamId, isPtsPresent, pts, isDtsPresent,
- dts, dataLength, offset, nullptr, isSecureMemory, avDataId,
- mpuSequenceNumber, isPesPrivateData, sc, audioDescriptor,
- presentationsJObj);
+ jobject obj = env->NewObject(mMediaEventClass, mMediaEventInitID, streamId, isPtsPresent, pts,
+ isDtsPresent, dts, dataLength, offset, nullptr, isSecureMemory,
+ avDataId, mpuSequenceNumber, isPesPrivateData, sc,
+ audioDescriptor, presentationsJObj);
uint64_t avSharedMemSize = mFilterClient->getAvSharedHandleInfo().size;
if (mediaEvent.avMemory.fds.size() > 0 || mediaEvent.avDataId != 0 ||
@@ -717,7 +705,7 @@
new MediaEvent(mFilterClient, dupFromAidl(mediaEvent.avMemory),
mediaEvent.avDataId, dataLength + offset, obj);
mediaEventSp->mAvHandleRefCnt++;
- env->SetLongField(obj, eventContext, (jlong)mediaEventSp.get());
+ env->SetLongField(obj, mMediaEventFieldContextID, (jlong)mediaEventSp.get());
mediaEventSp->incStrong(obj);
}
@@ -726,32 +714,27 @@
env->DeleteLocalRef(audioDescriptor);
}
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
env->DeleteLocalRef(presentationsJObj);
}
void FilterClientCallbackImpl::getPesEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/PesEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(III)V");
const DemuxFilterPesEvent &pesEvent = event.get<DemuxFilterEvent::Tag::pes>();
jint streamId = pesEvent.streamId;
jint dataLength = pesEvent.dataLength;
jint mpuSequenceNumber = pesEvent.mpuSequenceNumber;
- jobject obj = env->NewObject(eventClazz, eventInit, streamId, dataLength, mpuSequenceNumber);
+ jobject obj = env->NewObject(mPesEventClass, mPesEventInitID, streamId, dataLength,
+ mpuSequenceNumber);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::getTsRecordEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TsRecordEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIJJI)V");
const DemuxFilterTsRecordEvent &tsRecordEvent = event.get<DemuxFilterEvent::Tag::tsRecord>();
DemuxPid pid = tsRecordEvent.pid;
@@ -781,18 +764,15 @@
jlong pts = tsRecordEvent.pts;
jint firstMbInSlice = tsRecordEvent.firstMbInSlice;
- jobject obj =
- env->NewObject(eventClazz, eventInit, jpid, ts, sc, byteNumber, pts, firstMbInSlice);
+ jobject obj = env->NewObject(mTsRecordEventClass, mTsRecordEventInitID, jpid, ts, sc,
+ byteNumber, pts, firstMbInSlice);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::getMmtpRecordEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/MmtpRecordEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IJIJII)V");
const DemuxFilterMmtpRecordEvent &mmtpRecordEvent =
event.get<DemuxFilterEvent::Tag::mmtpRecord>();
@@ -803,18 +783,15 @@
jint firstMbInSlice = mmtpRecordEvent.firstMbInSlice;
jlong tsIndexMask = mmtpRecordEvent.tsIndexMask;
- jobject obj = env->NewObject(eventClazz, eventInit, scHevcIndexMask, byteNumber,
- mpuSequenceNumber, pts, firstMbInSlice, tsIndexMask);
+ jobject obj = env->NewObject(mMmtpRecordEventClass, mMmtpRecordEventInitID, scHevcIndexMask,
+ byteNumber, mpuSequenceNumber, pts, firstMbInSlice, tsIndexMask);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::getDownloadEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/DownloadEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(IIIIII)V");
const DemuxFilterDownloadEvent &downloadEvent = event.get<DemuxFilterEvent::Tag::download>();
jint itemId = downloadEvent.itemId;
@@ -824,32 +801,27 @@
jint lastItemFragmentIndex = downloadEvent.lastItemFragmentIndex;
jint dataLength = downloadEvent.dataLength;
- jobject obj = env->NewObject(eventClazz, eventInit, itemId, downloadId, mpuSequenceNumber,
- itemFragmentIndex, lastItemFragmentIndex, dataLength);
+ jobject obj = env->NewObject(mDownloadEventClass, mDownloadEventInitID, itemId, downloadId,
+ mpuSequenceNumber, itemFragmentIndex, lastItemFragmentIndex,
+ dataLength);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::getIpPayloadEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/IpPayloadEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V");
const DemuxFilterIpPayloadEvent &ipPayloadEvent = event.get<DemuxFilterEvent::Tag::ipPayload>();
jint dataLength = ipPayloadEvent.dataLength;
- jobject obj = env->NewObject(eventClazz, eventInit, dataLength);
+ jobject obj = env->NewObject(mIpPayloadEventClass, mIpPayloadEventInitID, dataLength);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::getTemiEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/TemiEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(JB[B)V");
const DemuxFilterTemiEvent &temiEvent = event.get<DemuxFilterEvent::Tag::temi>();
jlong pts = temiEvent.pts;
@@ -859,63 +831,53 @@
jbyteArray array = env->NewByteArray(descrData.size());
env->SetByteArrayRegion(array, 0, descrData.size(), reinterpret_cast<jbyte *>(&descrData[0]));
- jobject obj = env->NewObject(eventClazz, eventInit, pts, descrTag, array);
+ jobject obj = env->NewObject(mTemiEventClass, mTemiEventInitID, pts, descrTag, array);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(array);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::getScramblingStatusEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/ScramblingStatusEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V");
const DemuxFilterMonitorEvent &scramblingStatus =
event.get<DemuxFilterEvent::Tag::monitorEvent>()
.get<DemuxFilterMonitorEvent::Tag::scramblingStatus>();
- jobject obj = env->NewObject(eventClazz, eventInit, scramblingStatus);
+ jobject obj = env->NewObject(mScramblingStatusEventClass, mScramblingStatusEventInitID,
+ scramblingStatus);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::getIpCidChangeEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/IpCidChangeEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V");
const DemuxFilterMonitorEvent &cid = event.get<DemuxFilterEvent::Tag::monitorEvent>()
.get<DemuxFilterMonitorEvent::Tag::cid>();
- jobject obj = env->NewObject(eventClazz, eventInit, cid);
+ jobject obj = env->NewObject(mIpCidChangeEventClass, mIpCidChangeEventInitID, cid);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::getRestartEvent(jobjectArray &arr, const int size,
const DemuxFilterEvent &event) {
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/RestartEvent");
- jmethodID eventInit = env->GetMethodID(eventClazz, "<init>", "(I)V");
const int32_t &startId = event.get<DemuxFilterEvent::Tag::startId>();
- jobject obj = env->NewObject(eventClazz, eventInit, startId);
+ jobject obj = env->NewObject(mRestartEventClass, mRestartEventInitID, startId);
env->SetObjectArrayElement(arr, size, obj);
env->DeleteLocalRef(obj);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::onFilterEvent(const vector<DemuxFilterEvent> &events) {
ALOGV("FilterClientCallbackImpl::onFilterEvent");
JNIEnv *env = AndroidRuntime::getJNIEnv();
- jclass eventClazz = env->FindClass("android/media/tv/tuner/filter/FilterEvent");
jobjectArray array;
if (!events.empty()) {
- array = env->NewObjectArray(events.size(), eventClazz, nullptr);
+ array = env->NewObjectArray(events.size(), mEventClass, nullptr);
}
for (int i = 0, arraySize = 0; i < events.size(); i++) {
@@ -1004,7 +966,6 @@
"Filter object has been freed. Ignoring callback.");
}
env->DeleteLocalRef(array);
- env->DeleteLocalRef(eventClazz);
}
void FilterClientCallbackImpl::onFilterStatus(const DemuxFilterStatus status) {
@@ -1040,6 +1001,67 @@
mSharedFilter = true;
}
+FilterClientCallbackImpl::FilterClientCallbackImpl() {
+ JNIEnv *env = AndroidRuntime::getJNIEnv();
+ ScopedLocalRef eventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/FilterEvent"));
+ ScopedLocalRef sectionEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/SectionEvent"));
+ ScopedLocalRef mediaEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/MediaEvent"));
+ ScopedLocalRef audioDescriptorClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/AudioDescriptor"));
+ ScopedLocalRef pesEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/PesEvent"));
+ ScopedLocalRef tsRecordEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/TsRecordEvent"));
+ ScopedLocalRef mmtpRecordEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/MmtpRecordEvent"));
+ ScopedLocalRef downloadEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/DownloadEvent"));
+ ScopedLocalRef ipPayloadEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/IpPayloadEvent"));
+ ScopedLocalRef temiEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/TemiEvent"));
+ ScopedLocalRef scramblingStatusEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/ScramblingStatusEvent"));
+ ScopedLocalRef ipCidChangeEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/IpCidChangeEvent"));
+ ScopedLocalRef restartEventClass =
+ ScopedLocalRef(env, env->FindClass("android/media/tv/tuner/filter/RestartEvent"));
+ mEventClass = (jclass) env->NewGlobalRef(eventClass.get());
+ mSectionEventClass = (jclass) env->NewGlobalRef(sectionEventClass.get());
+ mMediaEventClass = (jclass) env->NewGlobalRef(mediaEventClass.get());
+ mAudioDescriptorClass = (jclass) env->NewGlobalRef(audioDescriptorClass.get());
+ mPesEventClass = (jclass) env->NewGlobalRef(pesEventClass.get());
+ mTsRecordEventClass = (jclass) env->NewGlobalRef(tsRecordEventClass.get());
+ mMmtpRecordEventClass = (jclass) env->NewGlobalRef(mmtpRecordEventClass.get());
+ mDownloadEventClass = (jclass) env->NewGlobalRef(downloadEventClass.get());
+ mIpPayloadEventClass = (jclass) env->NewGlobalRef(ipPayloadEventClass.get());
+ mTemiEventClass = (jclass) env->NewGlobalRef(temiEventClass.get());
+ mScramblingStatusEventClass = (jclass) env->NewGlobalRef(scramblingStatusEventClass.get());
+ mIpCidChangeEventClass = (jclass) env->NewGlobalRef(ipCidChangeEventClass.get());
+ mRestartEventClass = (jclass) env->NewGlobalRef(restartEventClass.get());
+ mSectionEventInitID = env->GetMethodID(mSectionEventClass, "<init>", "(IIIJ)V");
+ mMediaEventInitID = env->GetMethodID(
+ mMediaEventClass,
+ "<init>",
+ "(IZJZJJJLandroid/media/MediaCodec$LinearBlock;"
+ "ZJIZILandroid/media/tv/tuner/filter/AudioDescriptor;"
+ "Ljava/util/List;)V");
+ mAudioDescriptorInitID = env->GetMethodID(mAudioDescriptorClass, "<init>", "(BBCBBB)V");
+ mPesEventInitID = env->GetMethodID(mPesEventClass, "<init>", "(III)V");
+ mTsRecordEventInitID = env->GetMethodID(mTsRecordEventClass, "<init>", "(IIIJJI)V");
+ mMmtpRecordEventInitID = env->GetMethodID(mMmtpRecordEventClass, "<init>", "(IJIJII)V");
+ mDownloadEventInitID = env->GetMethodID(mDownloadEventClass, "<init>", "(IIIIII)V");
+ mIpPayloadEventInitID = env->GetMethodID(mIpPayloadEventClass, "<init>", "(I)V");
+ mTemiEventInitID = env->GetMethodID(mTemiEventClass, "<init>", "(JB[B)V");
+ mScramblingStatusEventInitID = env->GetMethodID(mScramblingStatusEventClass, "<init>", "(I)V");
+ mIpCidChangeEventInitID = env->GetMethodID(mIpCidChangeEventClass, "<init>", "(I)V");
+ mRestartEventInitID = env->GetMethodID(mRestartEventClass, "<init>", "(I)V");
+ mMediaEventFieldContextID = env->GetFieldID(mMediaEventClass, "mNativeContext", "J");
+}
+
FilterClientCallbackImpl::~FilterClientCallbackImpl() {
JNIEnv *env = AndroidRuntime::getJNIEnv();
if (mFilterObj != nullptr) {
@@ -1047,6 +1069,19 @@
mFilterObj = nullptr;
}
mFilterClient = nullptr;
+ env->DeleteGlobalRef(mEventClass);
+ env->DeleteGlobalRef(mSectionEventClass);
+ env->DeleteGlobalRef(mMediaEventClass);
+ env->DeleteGlobalRef(mAudioDescriptorClass);
+ env->DeleteGlobalRef(mPesEventClass);
+ env->DeleteGlobalRef(mTsRecordEventClass);
+ env->DeleteGlobalRef(mMmtpRecordEventClass);
+ env->DeleteGlobalRef(mDownloadEventClass);
+ env->DeleteGlobalRef(mIpPayloadEventClass);
+ env->DeleteGlobalRef(mTemiEventClass);
+ env->DeleteGlobalRef(mScramblingStatusEventClass);
+ env->DeleteGlobalRef(mIpCidChangeEventClass);
+ env->DeleteGlobalRef(mRestartEventClass);
}
/////////////// FrontendClientCallbackImpl ///////////////////////
diff --git a/media/jni/android_media_tv_Tuner.h b/media/jni/android_media_tv_Tuner.h
index 2bb14f6..6b1b6b1 100644
--- a/media/jni/android_media_tv_Tuner.h
+++ b/media/jni/android_media_tv_Tuner.h
@@ -125,6 +125,7 @@
};
struct FilterClientCallbackImpl : public FilterClientCallback {
+ FilterClientCallbackImpl();
~FilterClientCallbackImpl();
virtual void onFilterEvent(const vector<DemuxFilterEvent>& events);
virtual void onFilterStatus(const DemuxFilterStatus status);
@@ -135,6 +136,32 @@
private:
jweak mFilterObj;
sp<FilterClient> mFilterClient;
+ jclass mEventClass;
+ jclass mSectionEventClass;
+ jclass mMediaEventClass;
+ jclass mAudioDescriptorClass;
+ jclass mPesEventClass;
+ jclass mTsRecordEventClass;
+ jclass mMmtpRecordEventClass;
+ jclass mDownloadEventClass;
+ jclass mIpPayloadEventClass;
+ jclass mTemiEventClass;
+ jclass mScramblingStatusEventClass;
+ jclass mIpCidChangeEventClass;
+ jclass mRestartEventClass;
+ jmethodID mSectionEventInitID;
+ jmethodID mMediaEventInitID;
+ jmethodID mAudioDescriptorInitID;
+ jmethodID mPesEventInitID;
+ jmethodID mTsRecordEventInitID;
+ jmethodID mMmtpRecordEventInitID;
+ jmethodID mDownloadEventInitID;
+ jmethodID mIpPayloadEventInitID;
+ jmethodID mTemiEventInitID;
+ jmethodID mScramblingStatusEventInitID;
+ jmethodID mIpCidChangeEventInitID;
+ jmethodID mRestartEventInitID;
+ jfieldID mMediaEventFieldContextID;
bool mSharedFilter;
void getSectionEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
void getMediaEvent(jobjectArray& arr, const int size, const DemuxFilterEvent& event);
diff --git a/native/android/surface_control.cpp b/native/android/surface_control.cpp
index 904fa74..4b63fbf 100644
--- a/native/android/surface_control.cpp
+++ b/native/android/surface_control.cpp
@@ -628,14 +628,15 @@
CHECK_NOT_NULL(aSurfaceControl);
if (!isfinite(currentBufferRatio) || currentBufferRatio < 1.0f) {
- ALOGE("Ignore setExtendedRangeBrightness, currentBufferRatio %f isn't finite or >= 1.0f",
- currentBufferRatio);
+ LOG_ALWAYS_FATAL("setExtendedRangeBrightness, currentBufferRatio %f isn't finite or >= "
+ "1.0f",
+ currentBufferRatio);
return;
}
if (!isfinite(desiredRatio) || desiredRatio < 1.0f) {
- ALOGE("Ignore setExtendedRangeBrightness, desiredRatio %f isn't finite or >= 1.0f",
- desiredRatio);
+ LOG_ALWAYS_FATAL("setExtendedRangeBrightness, desiredRatio %f isn't finite or >= 1.0f",
+ desiredRatio);
return;
}
diff --git a/packages/CarrierDefaultApp/res/values-af/strings.xml b/packages/CarrierDefaultApp/res/values-af/strings.xml
index d2e47d8..64cc776 100644
--- a/packages/CarrierDefaultApp/res/values-af/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-af/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Selfoondiensverskaffer"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobiele data is op"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Jou mobiele data is gedeaktiveer"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Byvoorbeeld, die aanmeldbladsy behoort dalk nie aan die organisasie wat gewys word nie."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Gaan in elk geval deur blaaier voort"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Prestasiehupstoot"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Verbeter jou appervaring"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tik om %s se webwerf te besoek en meer te wete te kom"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nie nou nie"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Bestuur"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Koop ’n prestasiehupstoot."</string>
diff --git a/packages/CarrierDefaultApp/res/values-am/strings.xml b/packages/CarrierDefaultApp/res/values-am/strings.xml
index c27c942..1bbc190 100644
--- a/packages/CarrierDefaultApp/res/values-am/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-am/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"የተንቀሳቃሽ ስልክ አገልግሎት አቅራቢ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"የተንቀሳቃሽ ስልክ ውሂብ አልቋል"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"የእርስዎ የተንቀሳቃሽ ስልክ ውሂብ ቦዝኗል"</string>
@@ -15,8 +16,9 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ለምሳሌ፣ የመግቢያ ገጹ የሚታየው ድርጅት ላይሆን ይችላል።"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ለማንኛውም በአሳሽ በኩል ይቀጥሉ"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"የአፈጻጸም ጭማሪ"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"የመተግበሪያ ተሞክሮዎን ያሻሽሉ"</string>
- <!-- no translation found for performance_boost_notification_detail (907363829888387028) -->
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
<skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"አሁን አይደለም"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"አስተዳድር"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ar/strings.xml b/packages/CarrierDefaultApp/res/values-ar/strings.xml
index b11de16..e8fa546 100644
--- a/packages/CarrierDefaultApp/res/values-ar/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ar/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"مُشغل شبكة الجوال"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"نفدت بيانات الجوّال"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"تم إيقاف بيانات الجوال"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"على سبيل المثال، قد لا تنتمي صفحة تسجيل الدخول إلى المؤسسة المعروضة."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"المتابعة على أي حال عبر المتصفح"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"تطبيق تعزيز الأداء"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"تحسين تجربة استخدامك للتطبيق"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"انقر لزيارة موقع \"%s\" الإلكتروني ومعرفة المزيد."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"لاحقًا"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"إدارة"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"شراء تطبيق تعزيز الأداء"</string>
diff --git a/packages/CarrierDefaultApp/res/values-as/strings.xml b/packages/CarrierDefaultApp/res/values-as/strings.xml
index 2144c0b..56e2da5 100644
--- a/packages/CarrierDefaultApp/res/values-as/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-as/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"ম’বাইল সেৱা প্ৰদান কৰা কোম্পানী"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ম’বাইল ডেটা শেষ হৈছে"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"আপোনাৰ ম’বাইল ডেটা সেৱা নিষ্ক্ৰিয় কৰা হৈছে"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"উদাহৰণস্বৰূপে, আপোনাক দেখুওৱা লগ ইনৰ পৃষ্ঠাটো প্ৰতিষ্ঠানটোৰ নিজা নহ\'বও পাৰে।"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"তথাপিও ব্ৰাউজাৰৰ জৰিয়তে অব্যাহত ৰাখক"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"কাৰ্যক্ষমতা পৰিৱৰ্ধন"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"আপোনাৰ এপৰ অভিজ্ঞতা উন্নত কৰক"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%sৰ ৱেবছাইটটো চাবলৈ আৰু অধিক জানিবলৈ টিপক"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"এতিয়া নহয়"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"পৰিচালনা কৰক"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"এটা কাৰ্যক্ষমতা পৰিৱৰ্ধন ক্ৰয় কৰক।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-az/strings.xml b/packages/CarrierDefaultApp/res/values-az/strings.xml
index 6267b7e..9677b62 100644
--- a/packages/CarrierDefaultApp/res/values-az/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-az/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobil Operator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobil data bitib"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobil data deaktiv edilib"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Məsələn, giriş səhifəsi göstərilən təşkilata aid olmaya bilər."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Hər bir halda brazuer ilə davam edin"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performans artırması"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Tətbiq təcrübənizi yaxşılaşdırın"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s veb-saytına daxil olmaq üçün toxunun və ətraflı məlumat əldə edin"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"İndi yox"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"İdarə edin"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Performans artırması alın."</string>
diff --git a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
index 38fe610..fc16b14 100644
--- a/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-b+sr+Latn/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobilni podaci su potrošeni"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilni podaci su deaktivirani"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Na primer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko pregledača"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Poboljšanje učinka"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Poboljšajte doživljaj aplikacije"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Dodirnite da biste posetili veb-sajt %s i saznali više"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne sada"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Upravljaj"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kupite poboljšanje učinka."</string>
diff --git a/packages/CarrierDefaultApp/res/values-be/strings.xml b/packages/CarrierDefaultApp/res/values-be/strings.xml
index d92fd1b..cd0974e 100644
--- a/packages/CarrierDefaultApp/res/values-be/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-be/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Аператар мабільнай сувязі"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мабільныя даныя скончыліся"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Перадача мабільных даных была дэактывавана"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Напрыклад, старонка ўваходу можа не належаць указанай арганізацыі."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Усё роўна працягнуць праз браўзер"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Павышэнне прадукцыйнасці"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Пашырце магчымасці вашай праграмы"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Націсніце, каб наведаць сайт %s\'s і даведацца больш"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не цяпер"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Кіраваць"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Аплаціце павышэнне прадукцыйнасці."</string>
diff --git a/packages/CarrierDefaultApp/res/values-bg/strings.xml b/packages/CarrierDefaultApp/res/values-bg/strings.xml
index 1b574a5..966ec33 100644
--- a/packages/CarrierDefaultApp/res/values-bg/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bg/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Мобилен оператор"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобилните данни са изразходвани"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилните ви данни са деактивирани"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Например страницата за вход може да не принадлежи на показаната организация."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Продължаване през браузър въпреки това"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Увеличаване на ефективността"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Подобряване на практическата работа в приложението"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Докоснете, за да посетите уебсайта на %s и да научите повече"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не сега"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Управление"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Купете пакет за увеличаване на ефективността."</string>
diff --git a/packages/CarrierDefaultApp/res/values-bn/strings.xml b/packages/CarrierDefaultApp/res/values-bn/strings.xml
index 890b3c2..46eeb74 100644
--- a/packages/CarrierDefaultApp/res/values-bn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bn/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"পরিষেবা প্রদানকারী"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"মোবাইল ডেটা ফুরিয়ে গেছে"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"আপনার মোবাইল ডেটা নিষ্ক্রিয় করা হয়েছে"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"যেমন, লগ-ইন পৃষ্ঠাটি যে প্রতিষ্ঠানের পৃষ্ঠা বলে দেখানো আছে, আসলে তা নাও হতে পারে৷"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"যাই হোক, ব্রাউজারের মাধ্যমে চালিয়ে যান"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"পারফর্ম্যান্স বুস্ট"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"আপনার অ্যাপ ব্যবহারের অভিজ্ঞতা উন্নত করুন"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s-এর ওয়েবসাইটে যেতে ট্যাপ করুন এবং আরও জানুন"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"এখন নয়"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ম্যানেজ করুন"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"পারফর্ম্যান্স বুস্ট সংক্রান্ত ফিচার কিনুন।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-bs/strings.xml b/packages/CarrierDefaultApp/res/values-bs/strings.xml
index 56ec344..d41ad21 100644
--- a/packages/CarrierDefaultApp/res/values-bs/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-bs/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobilni internet je potrošen"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Prijenos podataka na mobilnoj mreži je deaktiviran"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Naprimjer, stranica za prijavljivanje možda ne pripada prikazanoj organizaciji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi preko preglednika"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Pojačavanje performansi"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Poboljšajte iskustvo u aplikaciji"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Dodirnite da posjetite web lokaciju %s i saznate više"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne sada"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Upravljajte"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kupite pojačavanje performansi."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ca/strings.xml b/packages/CarrierDefaultApp/res/values-ca/strings.xml
index 9a82acd..afde919 100644
--- a/packages/CarrierDefaultApp/res/values-ca/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ca/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operador de telefonia mòbil"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"S\'han esgotat les dades mòbils"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"S\'han desactivat les dades mòbils"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Per exemple, la pàgina d\'inici de sessió podria no pertànyer a l\'organització que es mostra."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continua igualment mitjançant el navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Optimització de rendiment"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Millora l\'experiència a l\'aplicació"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Toca per visitar el lloc web de %s i obtenir més informació"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ara no"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestiona"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Compra una optimització de rendiment."</string>
diff --git a/packages/CarrierDefaultApp/res/values-cs/strings.xml b/packages/CarrierDefaultApp/res/values-cs/strings.xml
index 31c84fe..8ede78a 100644
--- a/packages/CarrierDefaultApp/res/values-cs/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-cs/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobilní operátor"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobilní data byla vyčerpána"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilní data byla deaktivována"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Přihlašovací stránka například nemusí patřit zobrazované organizaci."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Přesto pokračovat prostřednictvím prohlížeče"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Zvýšení výkonu"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Vylepšete si zážitek z aplikace"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Klepnutím přejdete na web %s, kde zjistíte další informace"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Teď ne"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Spravovat"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kupte si zvýšení výkonu."</string>
diff --git a/packages/CarrierDefaultApp/res/values-da/strings.xml b/packages/CarrierDefaultApp/res/values-da/strings.xml
index a214db8..57f8b1a 100644
--- a/packages/CarrierDefaultApp/res/values-da/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-da/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobilselskab"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Der er ikke mere mobildata"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobildata er blevet deaktiveret"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Det er f.eks. ikke sikkert, at loginsiden tilhører den anførte organisation."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Fortsæt alligevel via browseren"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Ydeevneboost"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Få en bedre appoplevelse"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tryk for at gå til websitet for %s og få flere oplysninger"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ikke nu"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Administrer"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Køb et ydeevneboost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-de/strings.xml b/packages/CarrierDefaultApp/res/values-de/strings.xml
index 7e9191f..65e2fd5 100644
--- a/packages/CarrierDefaultApp/res/values-de/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-de/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobilfunkanbieter"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile Daten sind aufgebraucht"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Deine mobilen Daten wurden deaktiviert"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Beispiel: Die Log-in-Seite gehört eventuell nicht zur angezeigten Organisation."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Trotzdem in einem Browser fortfahren"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Leistungs-Boost"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"App-Nutzung verbessern"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tippe, um die Website von %s zu besuchen und mehr zu erfahren"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nicht jetzt"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Verwalten"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Leistungs-Boost erwerben."</string>
diff --git a/packages/CarrierDefaultApp/res/values-el/strings.xml b/packages/CarrierDefaultApp/res/values-el/strings.xml
index 3bc890a..7a55d3a 100644
--- a/packages/CarrierDefaultApp/res/values-el/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-el/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Εταιρεία κινητής τηλεφωνίας"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Τα δεδομένα κινητής τηλεφωνίας εξαντλήθηκαν"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Τα δεδομένα κινητής τηλεφωνίας έχουν απενεργοποιηθεί"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Για παράδειγμα, η σελίδα σύνδεσης ενδέχεται να μην ανήκει στον οργανισμό που εμφανίζεται."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Συνέχεια ούτως ή άλλως μέσω του προγράμματος περιήγησης"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Ενίσχυση απόδοσης"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Βελτιώστε την εμπειρία της εφαρμογής"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Πατήστε για να επισκεφτείτε τον ιστότοπο %s και να μάθετε περισσότερα"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Όχι τώρα"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Διαχείριση"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Αγοράστε μια ενίσχυση απόδοσης."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml b/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
index 346a1d1..9d6b013 100644
--- a/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rAU/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobile Operator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page might not belong to the organisation shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Improve your app experience"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tap to visit %s\'s website and learn more"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rCA/strings.xml b/packages/CarrierDefaultApp/res/values-en-rCA/strings.xml
index 2ae9f16..00c0357 100644
--- a/packages/CarrierDefaultApp/res/values-en-rCA/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rCA/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobile Carrier"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page may not belong to the organization shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Improve your app experience"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tap to visit %s\'s website and learn more"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml b/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
index 346a1d1..9d6b013 100644
--- a/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rGB/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobile Operator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page might not belong to the organisation shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Improve your app experience"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tap to visit %s\'s website and learn more"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml b/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
index 346a1d1..9d6b013 100644
--- a/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rIN/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobile Operator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page might not belong to the organisation shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Improve your app experience"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tap to visit %s\'s website and learn more"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml b/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml
index 95af4d3..7f7456d 100644
--- a/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-en-rXC/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobile Carrier"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobile data has run out"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Your mobile data has been deactivated"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"For example, the login page may not belong to the organization shown."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continue anyway via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performance boost"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Improve your app experience"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tap to visit %s\'s website and learn more"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Not now"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Manage"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Purchase a performance boost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml b/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
index 236a1dc..85598235 100644
--- a/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-es-rUS/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Compañía de telefonía móvil"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Se agotó el servicio de datos móviles"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Se desactivaron los datos móviles"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por ejemplo, es posible que la página de acceso no pertenezca a la organización que aparece."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar de todos modos desde el navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento de rendimiento"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Mejora tu experiencia en la app"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Presiona para visitar el sitio web de %s y obtener más información"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ahora no"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Administrar"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Compra un aumento de rendimiento."</string>
diff --git a/packages/CarrierDefaultApp/res/values-es/strings.xml b/packages/CarrierDefaultApp/res/values-es/strings.xml
index 2550553..b9fa4c0 100644
--- a/packages/CarrierDefaultApp/res/values-es/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-es/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operador de telefonía móvil"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Se han agotado los datos móviles"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Se han desactivado los datos móviles"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por ejemplo, es posible que la página de inicio de sesión no pertenezca a la organización mostrada."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar de todos modos a través del navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Mejora de rendimiento"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Mejora tu experiencia en la aplicación"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Toca para visitar el sitio web de %s y obtener más información."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ahora no"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestionar"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Comprar una mejora de rendimiento."</string>
diff --git a/packages/CarrierDefaultApp/res/values-et/strings.xml b/packages/CarrierDefaultApp/res/values-et/strings.xml
index e1e8cc0..e51b76c 100644
--- a/packages/CarrierDefaultApp/res/values-et/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-et/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobiilioperaator"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobiilse andmeside limiit on täis"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Teie mobiilne andmeside on inaktiveeritud"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Näiteks ei pruugi sisselogimisleht kuuluda kuvatavale organisatsioonile."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Jätka siiski brauseris"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Jõudluse võimendus"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Aidake parandada rakenduse kasutuskogemust"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Puudutage, et külastada rakenduse %s veebisaiti ja hankida lisateavet"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Mitte praegu"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Haldamine"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Ostke jõudluse võimendus."</string>
diff --git a/packages/CarrierDefaultApp/res/values-eu/strings.xml b/packages/CarrierDefaultApp/res/values-eu/strings.xml
index ce6603b..3650635 100644
--- a/packages/CarrierDefaultApp/res/values-eu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-eu/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Telefonia mugikorreko operadorea"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Agortu egin da datu-konexioa"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Desaktibatu da datu-konexioa"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Adibidez, baliteke saioa hasteko orria adierazitako erakundearena ez izatea."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Jarraitu arakatzailearen bidez, halere"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Errendimendu-hobekuntza"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Hobetu aplikazioaren erabilera"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Sakatu hau %s aplikazioaren garatzailearen webgunera joateko eta informazio gehiago lortzeko"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Orain ez"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Kudeatu"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Erosi errendimendu-hobekuntza bat."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fa/strings.xml b/packages/CarrierDefaultApp/res/values-fa/strings.xml
index 8ecc5dc..0738cbf 100644
--- a/packages/CarrierDefaultApp/res/values-fa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fa/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"شرکت مخابراتی دستگاه همراه"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"داده تلفن همراه تمام شده است"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"داده شبکه تلفن همراه شما غیرفعال شده است"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"به عنوان مثال، صفحه ورود به سیستم ممکن است متعلق به سازمان نشان داده شده نباشد."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"درهر صورت ازطریق مرورگر ادامه یابد"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"تقویتکننده عملکرد"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"تجربه برنامهتان را بهبود دهید"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"برای بازدید از وبسایت %s و کسب اطلاعات بیشتر، ضربه بزنید"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"اکنون نه"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"مدیریت"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"تقویتکننده عملکرد خریداری کنید."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fi/strings.xml b/packages/CarrierDefaultApp/res/values-fi/strings.xml
index c283d68..fc51611 100644
--- a/packages/CarrierDefaultApp/res/values-fi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fi/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobiilioperaattori"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobiilidata on loppunut."</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobiilidata poistettu käytöstä"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Kirjautumissivu ei välttämättä kuulu näytetylle organisaatiolle."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Jatka selaimen kautta"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Suorituskykyboosti"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Paranna sovelluskokemustasi"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Avaa sivusto (%s) napauttamalla, niin saat lisätietoja"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ei nyt"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Muuta"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Osta suorituskykyboosti."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
index 8e5bf62..42dca42 100644
--- a/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fr-rCA/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Fournisseur de services"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Vous avez épuisé votre forfait de données cellulaires"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Les données cellulaires ont été désactivées pour votre compte"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Par exemple, la page de connexion pourrait ne pas appartenir à l\'organisation représentée."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuer quand même dans un navigateur"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Optimiseur de performances"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Améliorer votre expérience de l\'application"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Touchez pour consulter le site Web de %s et en savoir plus"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Plus tard"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gérer"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Achetez un optimiseur de performances."</string>
diff --git a/packages/CarrierDefaultApp/res/values-fr/strings.xml b/packages/CarrierDefaultApp/res/values-fr/strings.xml
index ce769e3..1d06a1d 100644
--- a/packages/CarrierDefaultApp/res/values-fr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-fr/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Opérateur mobile"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Les données mobiles sont épuisées"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Les données mobiles ont été désactivées pour votre compte"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Par exemple, la page de connexion peut ne pas appartenir à l\'organisation représentée."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuer quand même dans le navigateur"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Boost de performances"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Améliorer votre expérience dans l\'appli"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Appuyez pour accéder au site Web de %s et en savoir plus"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Pas maintenant"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gérer"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Achetez un boost de performances."</string>
diff --git a/packages/CarrierDefaultApp/res/values-gl/strings.xml b/packages/CarrierDefaultApp/res/values-gl/strings.xml
index 648bca4..ad2fdce 100644
--- a/packages/CarrierDefaultApp/res/values-gl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-gl/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operador móbil"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Esgotáronse os datos móbiles"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Desactiváronse os datos móbiles"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, é posible que a páxina de inicio de sesión non pertenza á organización que se mostra."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar igualmente co navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Mellora de rendemento"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Mellora a túa experiencia ao usar a aplicación"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Toca para consultar máis información no sitio web de %s"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Agora non"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Xestionar"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Comprar unha mellora de rendemento."</string>
diff --git a/packages/CarrierDefaultApp/res/values-gu/strings.xml b/packages/CarrierDefaultApp/res/values-gu/strings.xml
index cc4103f..d003a44 100644
--- a/packages/CarrierDefaultApp/res/values-gu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-gu/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"કૅરિઅર ડિફૉલ્ટ ઍપ્લિકેશન"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"મોબાઇલ કૅરિઅર"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"મોબાઇલ ડેટા પૂરો થઈ ગયો છે"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"તમારો મોબાઇલ ડેટા નિષ્ક્રિય કરવામાં આવ્યો છે"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ઉદાહરણ તરીકે, લોગિન પૃષ્ઠ બતાવવામાં આવેલી સંસ્થાનું ન પણ હોય."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"તો પણ બ્રાઉઝર મારફતે ચાલુ રાખો"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"પર્ફોર્મન્સ બૂસ્ટ"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"ઍપ વિશેનો તમારો અનુભવ બહેતર બનાવો"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%sની વેબસાઇટની મુલાકાત લેવા માટે ટૅપ કરો અને વધુ જાણો"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"હમણાં નહીં"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"મેનેજ કરો"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"પર્ફોર્મન્સ બૂસ્ટ ખરીદો."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hi/strings.xml b/packages/CarrierDefaultApp/res/values-hi/strings.xml
index 2d832b9..6b3c544 100644
--- a/packages/CarrierDefaultApp/res/values-hi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hi/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"मोबाइल सेवा देने वाली कंपनी"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"मोबाइल डेटा खत्म हो गया है"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"आपका मोबाइल डेटा बंद कर दिया गया है"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"उदाहरण के लिए, हो सकता है कि लॉगिन पेज दिखाए गए संगठन का ना हो."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ब्राउज़र के ज़रिए किसी भी तरह जारी रखें"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"परफ़ॉर्मेंस बूस्ट"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"ऐप्लिकेशन इस्तेमाल करने का अनुभव बेहतर बनाएं"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s की वेबसाइट पर जाने और ज़्यादा जानने के लिए टैप करें"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"अभी नहीं"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"मैनेज करें"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"कोई परफ़ॉर्मेंस बूस्ट खरीदें."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hr/strings.xml b/packages/CarrierDefaultApp/res/values-hr/strings.xml
index f137d09..1a58080 100644
--- a/packages/CarrierDefaultApp/res/values-hr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hr/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"Zadana aplikacija mobilnog operatera"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobilni su podaci potrošeni"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilni su podaci deaktivirani"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Na primjer, stranica za prijavu možda ne pripada prikazanoj organizaciji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ipak nastavi putem preglednika"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Poboljšanje izvedbe"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Poboljšajte svoj doživljaj aplikacije"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Dodirnite da biste posjetili web-lokaciju %s i saznali više"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne sad"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Upravljajte"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kupite poboljšanje izvedbe."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hu/strings.xml b/packages/CarrierDefaultApp/res/values-hu/strings.xml
index 45a7e81..6ed1efe 100644
--- a/packages/CarrierDefaultApp/res/values-hu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hu/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobilszolgáltató"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Elérte a rendelkezésre álló mobiladat-mennyiséget"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"A rendszer deaktiválta a mobiladat-forgalmat"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Például lehetséges, hogy a bejelentkezési oldal nem a megjelenített szervezethez tartozik."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Folytatás ennek ellenére böngészőn keresztül"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Teljesítménynövelés"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Az alkalmazással kapcsolatos élmény javítása"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Koppintson a(z) %s webhelyének megnyitásához és a további információk megtekintéséhez."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Most nem"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Kezelés"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Vásároljon teljesítménynövelést."</string>
diff --git a/packages/CarrierDefaultApp/res/values-hy/strings.xml b/packages/CarrierDefaultApp/res/values-hy/strings.xml
index 23cc557..bca95a30 100644
--- a/packages/CarrierDefaultApp/res/values-hy/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-hy/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Բջջային օպերատոր"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Բջջային ինտերնետի սահմանաչափը սպառվել է"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Ձեր բջջային ինտերնետն ապակտիվացված է"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Օրինակ՝ մուտքի էջը կարող է ցուցադրված կազմակերպության էջը չլինել:"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Շարունակել դիտարկիչի միջոցով"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Արտադրողականության բարձրացում"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Բարելավեք հավելվածի օգտագործման ձեր փորձառությունը"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Հպեք՝ %s-ի կայք անցնելու և ավելին իմանալու համար"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ոչ հիմա"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Կառավարել"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Բարձրացրեք ցանցի արտադրողականությունը վճարի դիմաց։"</string>
diff --git a/packages/CarrierDefaultApp/res/values-in/strings.xml b/packages/CarrierDefaultApp/res/values-in/strings.xml
index 1a66584..cb0f35b 100644
--- a/packages/CarrierDefaultApp/res/values-in/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-in/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"AplikasiDefaultOperator"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operator Seluler"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Data seluler telah habis"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Data seluler telah dinonaktifkan"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Misalnya, halaman login mungkin bukan milik organisasi yang ditampilkan."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Tetap lanjutkan melalui browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Penguat sinyal"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Tingkatkan pengalaman aplikasi Anda"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Ketuk untuk membuka situs %s dan mempelajari lebih lanjut"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Lain kali"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Kelola"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Beli penguat sinyal."</string>
diff --git a/packages/CarrierDefaultApp/res/values-is/strings.xml b/packages/CarrierDefaultApp/res/values-is/strings.xml
index 7e7ecde..1e5fa78 100644
--- a/packages/CarrierDefaultApp/res/values-is/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-is/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Símafyrirtæki"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Farsímagögn kláruðust"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Slökkt hefur verið á farsímagögnum"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Til dæmis getur verið að innskráningarsíðan tilheyri ekki fyrirtækinu sem birtist."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Halda samt áfram í vafra"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Afkastaaukning"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Bættu forritsupplifunina"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Ýttu til að opna vefsvæði %s og fá frekari upplýsingar"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ekki núna"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Stjórna"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kaupa afkastaaukningu."</string>
diff --git a/packages/CarrierDefaultApp/res/values-it/strings.xml b/packages/CarrierDefaultApp/res/values-it/strings.xml
index 11ef6ba..f608ae9 100644
--- a/packages/CarrierDefaultApp/res/values-it/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-it/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operatore di telefonia mobile"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Dati mobili esauriti"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"I dati mobili sono stati disattivati"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Ad esempio, la pagina di accesso potrebbe non appartenere all\'organizzazione indicata."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continua comunque dal browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento di prestazioni"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Migliora l\'esperienza con la tua app"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tocca per visitare il sito web di %s e scoprire di più"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Non ora"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestisci"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Acquista un aumento di prestazioni."</string>
diff --git a/packages/CarrierDefaultApp/res/values-iw/strings.xml b/packages/CarrierDefaultApp/res/values-iw/strings.xml
index 4e67a42..3551acf 100644
--- a/packages/CarrierDefaultApp/res/values-iw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-iw/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"ספק שירות לנייד"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ניצלת את מכסת הנתונים הסלולריים"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"חבילת הגלישה שלך הושבתה"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"לדוגמה, ייתכן שדף ההתחברות אינו שייך לארגון המוצג."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"המשך בכל זאת באמצעות דפדפן"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"שיפור ביצועים"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"שיפור חוויית השימוש באפליקציה"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"ניתן להקיש כדי להיכנס אל האתר של %s ולקבל מידע נוסף"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"לא עכשיו"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ניהול"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"רכישת שיפור ביצועים."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ja/strings.xml b/packages/CarrierDefaultApp/res/values-ja/strings.xml
index 3115283..1fcbd7e 100644
--- a/packages/CarrierDefaultApp/res/values-ja/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ja/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"携帯通信会社のデフォルト アプリ"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"携帯通信会社"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"モバイルデータの残量がありません"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"モバイルデータが無効になっています"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"たとえば、ログインページが表示されている組織に属していない可能性があります。"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ブラウザから続行"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"パフォーマンス ブースト"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"アプリ内エクスペリエンスの改善"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"タップして %s のウェブサイトにアクセスし、詳細をご覧ください"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"後で"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"管理"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"パフォーマンス ブーストを購入してください。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ka/strings.xml b/packages/CarrierDefaultApp/res/values-ka/strings.xml
index cae7aad..ee281d7 100644
--- a/packages/CarrierDefaultApp/res/values-ka/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ka/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"მობილური ოპერატორი"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"მობილური ინტერნეტის პაკეტი ამოიწურა"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"მობილური ინტერნეტი დეაქტივირებულია"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"მაგალითად, სისტემაში შესვლის გვერდი შეიძლება არ ეკუთვნოდეს ნაჩვენებ ორგანიზაციას."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"მაინც ბრაუზერში გაგრძელება"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ეფექტურობის გაძლიერება"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"გააუმჯობესეთ თქვენი აპიდან მიღებული გამოცდილება"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"შეეხეთ, რომ ეწვიოთ %s-ის ვებსაიტს და შეიტყოთ მეტი"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ახლა არა"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"მართვა"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ეფექტურობის გაძლიერების შეძენა."</string>
diff --git a/packages/CarrierDefaultApp/res/values-kk/strings.xml b/packages/CarrierDefaultApp/res/values-kk/strings.xml
index 91a0c83..b5f6950 100644
--- a/packages/CarrierDefaultApp/res/values-kk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-kk/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Мобильдік байланыс операторы"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобильдік интернет бітті"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобильдік интернет өшірілді"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Мысалы, кіру беті көрсетілген ұйымға тиесілі болмауы мүмкін."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Бәрібір браузер арқылы жалғастыру"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Өнімділікті арттыру"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Қолданба мүмкіндіктерін жақсартыңыз"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s веб-сайтына кіру және толық ақпарат алу үшін түртіңіз."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Қазір емес"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Басқару"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Өнімділікті арттыру құралын сатып алыңыз."</string>
diff --git a/packages/CarrierDefaultApp/res/values-km/strings.xml b/packages/CarrierDefaultApp/res/values-km/strings.xml
index d15883e..20199a7 100644
--- a/packages/CarrierDefaultApp/res/values-km/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-km/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"ក្រុមហ៊ុនបម្រើសេវាទូរសព្ទចល័ត"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ទិន្នន័យចល័តបានអស់ហើយ"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ទិន្នន័យចល័តរបស់អ្នកត្រូវបានបិទដំណើរការហើយ"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ឧទាហរណ៍៖ ទំព័រចូលនេះអាចនឹងមិនមែនជាកម្មសិទ្ធិរបស់ស្ថាប័នដែលបានបង្ហាញនេះទេ។"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"យ៉ាងណាក៏ដោយនៅតែបន្តតាមរយៈកម្មវិធីរុករកតាមអ៊ីនធឺណិត"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ការបង្កើនប្រតិបត្តិការ"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"កែលម្អបទពិសោធន៍ប្រើប្រាស់កម្មវិធីរបស់អ្នក"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"ចុចដើម្បីចូលទៅកាន់គេហទំព័ររបស់ %s និងស្វែងយល់បន្ថែម"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"កុំទាន់"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"គ្រប់គ្រង"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ទិញការបង្កើនប្រតិបត្តិការ។"</string>
diff --git a/packages/CarrierDefaultApp/res/values-kn/strings.xml b/packages/CarrierDefaultApp/res/values-kn/strings.xml
index 7c7e037..619b92a 100644
--- a/packages/CarrierDefaultApp/res/values-kn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-kn/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"ಮೊಬೈಲ್ ವಾಹಕ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ಮೊಬೈಲ್ ಡೇಟಾ ಮುಗಿದುಹೋಗಿದೆ"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ನಿಮ್ಮ ಮೊಬೈಲ್ ಡೇಟಾ ನಿಷ್ಕ್ರಿಯಗೊಂಡಿದೆ"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ಉದಾಹರಣೆಗೆ, ಲಾಗಿನ್ ಪುಟವು ತೋರಿಸಲಾಗಿರುವ ಸಂಸ್ಥೆಗೆ ಸಂಬಂಧಿಸಿಲ್ಲದಿರಬಹುದು."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ಪರವಾಗಿಲ್ಲ, ಬ್ರೌಸರ್ ಮೂಲಕ ಮುಂದುವರಿಸಿ"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ಕಾರ್ಯಕ್ಷಮತೆ ಬೂಸ್ಟ್"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"ನಿಮ್ಮ ಆ್ಯಪ್ ಅನುಭವವನ್ನು ಸುಧಾರಿಸಿ"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s ನ ವೆಬ್ಸೈಟ್ಗೆ ಭೇಟಿ ನೀಡಲು ಟ್ಯಾಪ್ ಮಾಡಿ ಮತ್ತು ಇನ್ನಷ್ಟು ತಿಳಿದುಕೊಳ್ಳಿ"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ಈಗ ಬೇಡ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ನಿರ್ವಹಿಸಿ"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ಕಾರ್ಯಕ್ಷಮತೆ ಬೂಸ್ಟ್ ಅನ್ನು ಖರೀದಿಸಿ."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ko/strings.xml b/packages/CarrierDefaultApp/res/values-ko/strings.xml
index afc7068..46e172d 100644
--- a/packages/CarrierDefaultApp/res/values-ko/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ko/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"이동통신사 기본 앱"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"이동통신사"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"모바일 데이터가 소진되었습니다."</string>
<string name="no_data_notification_id" msgid="668400731803969521">"모바일 데이터가 비활성화되었습니다."</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"예를 들어 로그인 페이지가 표시된 조직에 속하지 않을 수 있습니다."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"브라우저를 통해 계속하기"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"성능 향상"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"앱 환경 개선"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s의 웹사이트를 방문하여 자세히 알아보려면 탭하세요."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"나중에"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"관리"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"성능 향상 구매"</string>
diff --git a/packages/CarrierDefaultApp/res/values-ky/strings.xml b/packages/CarrierDefaultApp/res/values-ky/strings.xml
index ddb4577..f2a96bc 100644
--- a/packages/CarrierDefaultApp/res/values-ky/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ky/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Мобилдик байланыш оператору"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобилдик Интернетиңиздин трафиги түгөндү"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилдик Интернет өчүрүлгөн"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Мисалы, аккаунтка кирүү баракчасы көрсөтүлгөн уюмга таандык эмес болушу мүмкүн."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Баары бир серепчи аркылуу улантуу"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Иштин майнаптуулугун жогорулатуу"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Колдонмону ыңгайлуу кылыңыз"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s вебсайтына баш багуу жана кеңири маалымат алуу үчүн таптаңыз"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Азыр эмес"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Тескөө"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Иштин майнаптуулугун жогорулатууну сатып алыңыз."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lo/strings.xml b/packages/CarrierDefaultApp/res/values-lo/strings.xml
index 3e45806..28af830 100644
--- a/packages/CarrierDefaultApp/res/values-lo/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lo/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"ຜູ້ໃຫ້ບໍລິການມືຖື"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ອິນເຕີເນັດມືຖືໝົດແລ້ວ"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ປິດການນຳໃຊ້ອິນເຕີເນັດມືຖືຂອງທ່ານແລ້ວ"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ຕົວຢ່າງ, ໜ້າເຂົ້າສູ່ລະບົບອາດຈະບໍ່ແມ່ນຂອງອົງກອນທີ່ປາກົດ."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ດຳເນີນການຕໍ່ຜ່ານໂປຣແກຣມທ່ອງເວັບ"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ເລັ່ງປະສິດທິພາບ"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"ປັບປຸງປະສົບການແອັບຂອງທ່ານ"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"ແຕະເພື່ອເຂົ້າເບິ່ງເວັບໄຊຂອງ %s ແລະ ສຶກສາເພີ່ມເຕີມ"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ບໍ່ຟ້າວເທື່ອ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ຈັດການ"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ຊື້ການເລັ່ງປະສິດທິພາບ."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lt/strings.xml b/packages/CarrierDefaultApp/res/values-lt/strings.xml
index 689d5f7..b9be333 100644
--- a/packages/CarrierDefaultApp/res/values-lt/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lt/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobiliojo ryšio operatorius"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobiliojo ryšio duomenys baigėsi"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobiliojo ryšio duomenys išaktyvinti"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Pavyzdžiui, prisijungimo puslapis gali nepriklausyti rodomai organizacijai."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Vis tiek tęsti naudojant naršyklę"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Našumo pagerinimas"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Pagerinkite savo programos naudojimo patirtį"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Palieskite, jei norite apsilankyti %s svetainėje ir sužinoti daugiau"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne dabar"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Tvarkyti"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Įsigykite našumo pagerinimo paslaugą."</string>
diff --git a/packages/CarrierDefaultApp/res/values-lv/strings.xml b/packages/CarrierDefaultApp/res/values-lv/strings.xml
index 3485fe1..d539947 100644
--- a/packages/CarrierDefaultApp/res/values-lv/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-lv/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobilo sakaru operators"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Sasniegts mobilo datu ierobežojums."</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Jūsu mobilie dati ir deaktivizēti"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Piemēram, pieteikšanās lapa, iespējams, nepieder norādītajai organizācijai."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Tomēr turpināt, izmantojot pārlūkprogrammu"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Veiktspējas uzlabojums"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Uzlabojiet lietotnes darbību"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Pieskarieties, lai apmeklētu %s vietni un uzzinātu vairāk."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Vēlāk"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Pārvaldīt"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Iegādājieties veiktspējas uzlabojumu."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mk/strings.xml b/packages/CarrierDefaultApp/res/values-mk/strings.xml
index d09bdfe..4efecb0 100644
--- a/packages/CarrierDefaultApp/res/values-mk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mk/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Мобилен оператор"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобилниот интернет е искористен"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилниот интернет ви е деактивиран"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"На пример, страницата за најавување може да не припаѓа на прикажаната организација."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Сепак продолжи преку прелистувач"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Засилување на изведбата"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Подобрете го вашето доживување со апликацијата"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Допрете за да го посетите веб-сајтот на %s и да дознаете повеќе"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не сега"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Управувајте"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Купете засилување на изведбата."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ml/strings.xml b/packages/CarrierDefaultApp/res/values-ml/strings.xml
index 77b0f02..f4c19a3 100644
--- a/packages/CarrierDefaultApp/res/values-ml/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ml/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"മൊബൈൽ കാരിയർ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"മൊബൈൽ ഡാറ്റ തീർന്നിരിക്കുന്നു"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"നിങ്ങളുടെ മൊബൈൽ ഡാറ്റ നിർജീവമാക്കി"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ഉദാഹരണത്തിന്, കാണിച്ചിരിക്കുന്ന ഓർഗനൈസേഷന്റേതായിരിക്കില്ല ലോഗിൻ പേജ്."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"എന്തായാലും ബ്രൗസർ വഴി തുടരുക"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"പ്രകടന ബൂസ്റ്റ്"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"നിങ്ങളുടെ ആപ്പ് അനുഭവം മെച്ചപ്പെടുത്തുക"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s എന്നതിന്റെ വെബ്സൈറ്റ് സന്ദർശിക്കാനും കൂടുതലറിയാനും ടാപ്പ് ചെയ്യുക"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ഇപ്പോൾ വേണ്ട"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"മാനേജ് ചെയ്യുക"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"പ്രകടന ബൂസ്റ്റ് വാങ്ങൂ."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mn/strings.xml b/packages/CarrierDefaultApp/res/values-mn/strings.xml
index c101a4e..2f33eb2 100644
--- a/packages/CarrierDefaultApp/res/values-mn/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mn/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Мобайл оператор компани"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобайл дата дууссан"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Таны мобайл датаг идэвхгүй болгосон"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Жишээлбэл нэвтрэх хуудас нь харагдаж буй байгууллагынх биш байж болно."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ямар ч тохиолдолд хөтчөөр үргэлжлүүлэх"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Гүйцэтгэлийн идэвхжүүлэлт"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Аппын хэрэглээгээ сайжруулаарай"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s-н вебсайтад зочлох болон нэмэлт мэдээлэл авахын тулд товшино уу"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Одоо биш"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Удирдах"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Гүйцэтгэлийн идэвхжүүлэлтийг худалдаж аваарай."</string>
diff --git a/packages/CarrierDefaultApp/res/values-mr/strings.xml b/packages/CarrierDefaultApp/res/values-mr/strings.xml
index eba2762..9414545 100644
--- a/packages/CarrierDefaultApp/res/values-mr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-mr/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"मोबाइल वाहक"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"मोबाइल डेटा संपला आहे"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"तुमचा मोबाइल डेटा निष्क्रिय केला गेला"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणार्थ, लॉग इन पृष्ठ दर्शवलेल्या संस्थेच्या मालकीचे नसू शकते."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"तरीही ब्राउझरद्वारे सुरू ठेवा"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"परफॉर्मन्स बूस्ट"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"तुमच्या अॅपशी संबंधित अनुभवामध्ये सुधारणा करा"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s च्या वेबसाइटला भेट देण्यासाठी टॅप करा आणि आणखी जाणून घ्या"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"आता नको"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"व्यवस्थापित करा"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"परफॉर्मन्स बूस्ट खरेदी करा."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ms/strings.xml b/packages/CarrierDefaultApp/res/values-ms/strings.xml
index a6cabe5..4fb377e 100644
--- a/packages/CarrierDefaultApp/res/values-ms/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ms/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"AplLalaiPembawa"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Pembawa Mudah Alih"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Data mudah alih telah habis"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Data mudah alih anda telah dinyahaktifkan"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Contohnya, halaman log masuk mungkin bukan milik organisasi yang ditunjukkan."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Teruskan juga melalui penyemak imbas"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Peningkatan prestasi"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Tingkatkan pengalaman apl anda"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Ketik untuk melawat laman web %s dan ketahui lebih lanjut"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Bukan sekarang"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Urus"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Beli perangsang prestasi."</string>
diff --git a/packages/CarrierDefaultApp/res/values-my/strings.xml b/packages/CarrierDefaultApp/res/values-my/strings.xml
index f858b00..002edd8 100644
--- a/packages/CarrierDefaultApp/res/values-my/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-my/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"မိုဘိုင်း ဝန်ဆောင်မှုပေးသူ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"မိုဘိုင်းဒေတာ ကုန်သွားပါပြီ"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"သင်၏ မိုဘိုင်း ဒေတာကို ပိတ်ထားပါသည်"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ဥပမာ− ဝင်ရောက်ရန် စာမျက်နှာသည် ပြသထားသည့် အဖွဲ့အစည်းနှင့် သက်ဆိုင်မှုမရှိခြင်း ဖြစ်နိုင်ပါသည်။"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"မည်သို့ပင်ဖြစ်စေ ဘရောက်ဇာမှတစ်ဆင့် ရှေ့ဆက်ရန်"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"စွမ်းဆောင်ရည် မြှင့်တင်အက်ပ်"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"အက်ပ်အသုံးပြုမှု ပိုမိုကောင်းမွန်စေခြင်း"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s ၏ ဝဘ်ဆိုက်ကို ဝင်ကြည့်ပြီး ပိုမိုလေ့လာရန် တို့ပါ"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ယခုမလုပ်ပါ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"စီမံရန်"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"စွမ်းဆောင်ရည် မြှင့်တင်အက်ပ် ဝယ်ယူရန်။"</string>
diff --git a/packages/CarrierDefaultApp/res/values-nb/strings.xml b/packages/CarrierDefaultApp/res/values-nb/strings.xml
index 2e9283e..e001e44e 100644
--- a/packages/CarrierDefaultApp/res/values-nb/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-nb/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobiloperatør"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Du er tom for mobildata"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobildata er deaktivert"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Det er for eksempel mulig at påloggingssiden ikke tilhører organisasjonen som vises."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Fortsett likevel via nettleseren"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Bedre ytelse"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Få enda mer ut av appen"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Trykk for å gå til nettstedet til %s og finne ut mer"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ikke nå"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Administrer"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kjøp bedre ytelse."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ne/strings.xml b/packages/CarrierDefaultApp/res/values-ne/strings.xml
index 5750938..169ceff 100644
--- a/packages/CarrierDefaultApp/res/values-ne/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ne/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"मोबाइलको सेवा प्रदायक छनौट गर्नुहोस्"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"मोबाइल डेटा सकियो"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"तपाईंको मोबाइल डेटा निष्क्रिय पारिएको छ"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"उदाहरणका लागि, लग इन पृष्ठ देखाइएको संस्थाको नहुन सक्छ।"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"जे भए पनि ब्राउजर मार्फत जारी राख्नुहोस्"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"पर्फर्मेन्स बुस्ट"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"एप प्रयोग गर्दा अझ राम्रो सुविधा पाउनुहोस्"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s को वेबसाइटमा गई थप जान्न ट्याप गर्नुहोस्"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"अहिले होइन"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"व्यवस्थापन गर्नुहोस्"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"पर्फर्मेन्स बुस्ट किन्नुहोस्।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-nl/strings.xml b/packages/CarrierDefaultApp/res/values-nl/strings.xml
index 061d1b8..35ecb3c 100644
--- a/packages/CarrierDefaultApp/res/values-nl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-nl/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobiele provider"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobiele data verbruikt"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Je mobiele data zijn uitgeschakeld"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Zo hoort de weergegeven inlogpagina misschien niet bij de weergegeven organisatie."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Toch doorgaan via browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Prestatieboost"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Haal meer uit de app"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tik om naar de website van %s te gaan voor meer informatie"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Niet nu"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Beheren"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Koop een prestatieboost."</string>
diff --git a/packages/CarrierDefaultApp/res/values-or/strings.xml b/packages/CarrierDefaultApp/res/values-or/strings.xml
index 5f36024..dc13b65 100644
--- a/packages/CarrierDefaultApp/res/values-or/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-or/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"ମୋବାଇଲ୍ କେରିଅର୍"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ମୋବାଇଲ୍ ଡାଟା ଶେଷ ହୋଇଯାଇଛି"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ଆପଣଙ୍କ ମୋବାଇଲ୍ ଡାଟା ନିଷ୍କ୍ରୀୟ କରାଯାଇଛି"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ଉଦାହରଣସ୍ୱରୂପ, ଲଗଇନ୍ ପୃଷ୍ଠା ଦେଖାଯାଇଥିବା ସଂସ୍ଥାର ହୋଇନଥାଇପାରେ।"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ବ୍ରାଉଜର୍ ଜରିଆରେ ଯେମିତିବି ହେଉ ଜାରି ରଖନ୍ତୁ"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ପରଫରମାନ୍ସ ବୁଷ୍ଟ"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"ଆପଣଙ୍କ ଆପ ଅନୁଭୂତିକୁ ଉନ୍ନତ କରନ୍ତୁ"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%sର ୱେବସାଇଟ ଭିଜିଟ କରି ଅଧିକ ଜାଣିବାକୁ ଟାପ କରନ୍ତୁ"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ବର୍ତ୍ତମାନ ନୁହେଁ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ପରିଚାଳନା କରନ୍ତୁ"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ଏକ ପରଫରମାନ୍ସ ବୁଷ୍ଟ କିଣନ୍ତୁ।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-pa/strings.xml b/packages/CarrierDefaultApp/res/values-pa/strings.xml
index f53758e..c9fd0e8 100644
--- a/packages/CarrierDefaultApp/res/values-pa/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pa/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"ਮੋਬਾਈਲ ਕੈਰੀਅਰ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ਮੋਬਾਈਲ ਡਾਟਾ ਖਤਮ ਹੋ ਗਿਆ ਹੈ"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ਤੁਹਾਡਾ ਮੋਬਾਈਲ ਡਾਟਾ ਅਕਿਰਿਆਸ਼ੀਲ ਕਰ ਦਿੱਤਾ ਗਿਆ ਹੈ"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ਉਦਾਹਰਣ ਵੱਜੋਂ, ਲੌਗ-ਇਨ ਪੰਨਾ ਦਿਖਾਈ ਗਈ ਸੰਸਥਾ ਨਾਲ ਸੰਬੰਧਿਤ ਨਹੀਂ ਹੋ ਸਕਦਾ ਹੈ।"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ਬ੍ਰਾਊਜ਼ਰ ਰਾਹੀਂ ਫਿਰ ਵੀ ਜਾਰੀ ਰੱਖੋ"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"ਕਾਰਗੁਜ਼ਾਰੀ ਬੂਸਟ"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"ਆਪਣੇ ਐਪ ਅਨੁਭਵ ਨੂੰ ਬਿਹਤਰ ਬਣਾਓ"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s ਦੀ ਵੈੱਬਸਾਈਟ \'ਤੇ ਜਾਣ ਲਈ ਟੈਪ ਕਰੋ ਅਤੇ ਹੋਰ ਜਾਣੋ"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ਹੁਣੇ ਨਹੀਂ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"ਪ੍ਰਬੰਧਨ ਕਰੋ"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ਕਾਰਗੁਜ਼ਾਰੀ ਬੂਸਟ ਖਰੀਦੋ।"</string>
diff --git a/packages/CarrierDefaultApp/res/values-pl/strings.xml b/packages/CarrierDefaultApp/res/values-pl/strings.xml
index cd961b4..3ca001b 100644
--- a/packages/CarrierDefaultApp/res/values-pl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pl/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"Domyślna aplikacja operatora"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operator komórkowy"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Osiągnięto limit komórkowej transmisji danych"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobilna transmisja danych została wyłączona"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Na przykład strona logowania może nie należeć do wyświetlanej organizacji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Kontynuuj mimo to w przeglądarce"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Zwiększenie wydajności"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Ulepsz działanie aplikacji"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Kliknij, aby odwiedzić witrynę %s i dowiedzieć się więcej"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nie teraz"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Zarządzaj"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kup wzmocnienie wydajności"</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml b/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
index 1975c6d..cb8329c 100644
--- a/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt-rBR/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operadora de celular"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Os dados móveis se esgotaram"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Os dados móveis foram desativados"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar mesmo assim pelo navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento de performance"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Melhore sua experiência no app"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Toque para acessar o site de %s e saber mais"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Agora não"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gerenciar"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Comprar um aumento de performance."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml b/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
index f32fa89..7e435cf 100644
--- a/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt-rPT/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operador móvel"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Dados móveis esgotados"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Os seus dados móveis foram desativados"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, a página de início de sessão pode não pertencer à entidade apresentada."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar mesmo assim através do navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento do desempenho"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Melhore a sua experiência na app"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Toque para visitar o Website de %s e saiba mais"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Agora não"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gerir"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Compre um aumento do desempenho."</string>
diff --git a/packages/CarrierDefaultApp/res/values-pt/strings.xml b/packages/CarrierDefaultApp/res/values-pt/strings.xml
index 1975c6d..cb8329c 100644
--- a/packages/CarrierDefaultApp/res/values-pt/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-pt/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operadora de celular"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Os dados móveis se esgotaram"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Os dados móveis foram desativados"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Por exemplo, a página de login pode não pertencer à organização mostrada."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuar mesmo assim pelo navegador"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Aumento de performance"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Melhore sua experiência no app"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Toque para acessar o site de %s e saber mais"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Agora não"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gerenciar"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Comprar um aumento de performance."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ro/strings.xml b/packages/CarrierDefaultApp/res/values-ro/strings.xml
index 7f0dd4a..042d9ec 100644
--- a/packages/CarrierDefaultApp/res/values-ro/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ro/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"AplicațiePrestabilităOperator"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operator de telefonie mobilă"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Datele mobile au expirat"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Datele mobile au fost dezactivate"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"De exemplu, este posibil ca pagina de conectare să nu aparțină organizației afișate."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Continuă oricum prin browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Boost de performanță"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Îmbunătățește-ți experiența în aplicație"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Atinge ca să vizitezi site-ul %s și să afli mai multe"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Nu acum"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Gestionează"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Achiziționează un boost de performanță."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ru/strings.xml b/packages/CarrierDefaultApp/res/values-ru/strings.xml
index 5bd7444..0c25796 100644
--- a/packages/CarrierDefaultApp/res/values-ru/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ru/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Оператор мобильной связи"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобильный трафик израсходован"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобильный Интернет отключен"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Например, страница входа в аккаунт может быть фиктивной."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Продолжить в браузере"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Повышение производительности"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Сделайте приложение удобнее"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Нажмите, чтобы перейти на сайт \"%s\" и узнать больше."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не сейчас"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Настроить"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Повысьте производительность сети за плату."</string>
diff --git a/packages/CarrierDefaultApp/res/values-si/strings.xml b/packages/CarrierDefaultApp/res/values-si/strings.xml
index 3694996..6a8ce71 100644
--- a/packages/CarrierDefaultApp/res/values-si/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-si/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"ජංගම වාහකය"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"ජංගම දත්ත අවසන් වී ඇත"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"ඔබගේ ජංගම දත්ත අක්රිය කර ඇත"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"උදාහරණයක් ලෙස, පුරනය වන පිටුව පෙන්වා ඇති සංවිධානයට අයිති නැති විය හැක."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"කෙසේ වුවත් බ්රවුසරය හරහා ඉදිරියට යන්න"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"කාර්ය සාධනය ඉහළ නැංවීම"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"ඔබේ යෙදුම් අත්දැකීම වැඩි දියුණු කරන්න"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%sගේ වෙබ් අඩවියට පිවිසීමට සහ තව දැන ගැනීමට තට්ටු කරන්න"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"දැන් නොවේ"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"කළමනාකරණය කරන්න"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"කාර්ය සාධනය ඉහළ නැංවීමක් මිල දී ගන්න."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sk/strings.xml b/packages/CarrierDefaultApp/res/values-sk/strings.xml
index 4eac2a2..e14e087 100644
--- a/packages/CarrierDefaultApp/res/values-sk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sk/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Poskytovateľ mobilných služieb"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobilné dáta sa minuli"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Vaše mobilné dáta boli deaktivované"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Napríklad prihlasovacia stránka nemusí patriť uvedenej organizácii."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Pokračovať pomocou prehliadača"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Zvýšenie výkonu"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Zlepšite si prostredie v aplikácii"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Ak chcete navštíviť web služby %s a dozvedieť sa viac, klepnite"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Teraz nie"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Spravovať"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kúpte si zvýšenie výkonu."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sl/strings.xml b/packages/CarrierDefaultApp/res/values-sl/strings.xml
index ae95fed..21cb944 100644
--- a/packages/CarrierDefaultApp/res/values-sl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sl/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"Privzeta aplikacija operaterja"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobilni operater"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Porabili ste vse mobilne podatke"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Prenos podatkov v mobilnih omrežjih je deaktiviran"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Stran za prijavo na primer morda ne pripada prikazani organizaciji."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Vseeno nadaljuj v brskalniku"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Ojačevalnik zmogljivosti"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Izboljšajte izkušnjo z aplikacijami"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Dotaknite se za ogled več informacij na spletnem mestu operaterja %s."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Ne zdaj"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Upravljanje"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Kupite ojačevalnik zmogljivosti."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sq/strings.xml b/packages/CarrierDefaultApp/res/values-sq/strings.xml
index d991599..9d501d9 100644
--- a/packages/CarrierDefaultApp/res/values-sq/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sq/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Operatori celular"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Të dhënat celulare kanë përfunduar"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Të dhënat celulare janë çaktivizuar"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"për shembull, faqja e identifikimit mund të mos i përkasë organizatës së shfaqur."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Vazhdo gjithsesi nëpërmjet shfletuesit"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Përforcimi i performancës"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Përmirëso përvojën tënde në aplikacion"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Trokit për të vizituar sajtin e uebit të %s dhe për të mësuar më shumë"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Jo tani"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Menaxho"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Bli një paketë përforcimi të performancës."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sr/strings.xml b/packages/CarrierDefaultApp/res/values-sr/strings.xml
index 4b2322e..257d53b 100644
--- a/packages/CarrierDefaultApp/res/values-sr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sr/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Мобилни оператер"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобилни подаци су потрошени"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобилни подаци су деактивирани"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"На пример, страница за пријављивање можда не припада приказаној организацији."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Ипак настави преко прегледача"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Побољшање учинка"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Побољшајте доживљај апликације"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Додирните да бисте посетили веб-сајт %s и сазнали више"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не сада"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Управљај"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Купите побољшање учинка."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sv/strings.xml b/packages/CarrierDefaultApp/res/values-sv/strings.xml
index b927cda..1886ed9 100644
--- a/packages/CarrierDefaultApp/res/values-sv/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sv/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobiloperatör"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Slut på mobildata"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Din mobildata har inaktiverats"</string>
@@ -15,9 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Det kan t.ex. hända att inloggningssidan inte tillhör den organisation som visas."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Fortsätt ändå via webbläsaren"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Prestandahöjning"</string>
- <!-- no translation found for performance_boost_notification_title (6091638924925876776) -->
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
<skip />
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Tryck för att besöka webbplatsen för %s för att läsa mer"</string>
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Inte nu"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Hantera"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Köp en prestandahöjning."</string>
diff --git a/packages/CarrierDefaultApp/res/values-sw/strings.xml b/packages/CarrierDefaultApp/res/values-sw/strings.xml
index 9db9e27..fc3450f 100644
--- a/packages/CarrierDefaultApp/res/values-sw/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-sw/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mtoa Huduma za Simu"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Data ya mtandao wa simu imekwisha"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Data yako ya mtandao wa simu imezimwa"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Kwa mfano, ukurasa wa kuingia katika akaunti unaweza usiwe unamilikiwa na shirika lililoonyeshwa."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Endelea hata hivyo kupitia kivinjari"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Kuongeza utendaji"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Boresha hali yako ya utumiaji wa programu"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Gusa ili utembelee tovuti ya %s na upate maelezo zaidi"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Si sasa"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Dhibiti"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Nunua programu ya kuongeza utendaji."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ta/strings.xml b/packages/CarrierDefaultApp/res/values-ta/strings.xml
index 0c689bc..4916854 100644
--- a/packages/CarrierDefaultApp/res/values-ta/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ta/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"தொலைத்தொடர்பு நிறுவனம்"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"மொபைல் டேட்டா தீர்ந்துவிட்டது"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"மொபைல் டேட்டா முடக்கப்பட்டது"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"எடுத்துக்காட்டாக, உள்நுழைவுப் பக்கமானது காட்டப்படும் அமைப்பிற்குச் சொந்தமானதாக இல்லாமல் இருக்கலாம்."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"பரவாயில்லை, உலாவி வழியாகத் தொடர்க"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"பெர்ஃபார்மென்ஸ் பூஸ்ட்"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"உங்கள் ஆப்ஸ் அனுபவத்தை மேம்படுத்துங்கள்"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s இணையதளத்திற்குச் சென்று மேலும் அறிய தட்டுங்கள்"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"இப்போது வேண்டாம்"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"நிர்வகியுங்கள்"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ஒரு பெர்ஃபார்மென்ஸ் பூஸ்ட்டைப் பர்ச்சேஸ் செய்யுங்கள்."</string>
diff --git a/packages/CarrierDefaultApp/res/values-te/strings.xml b/packages/CarrierDefaultApp/res/values-te/strings.xml
index a413207..944ee75 100644
--- a/packages/CarrierDefaultApp/res/values-te/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-te/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"మొబైల్ క్యారియర్"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"మొబైల్ డేటాను పూర్తిగా ఉపయోగించారు"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"మీ మొబైల్ డేటా నిష్క్రియం చేయబడింది"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ఉదాహరణకు, లాగిన్ పేజీ చూపిన సంస్థకు చెందినది కాకపోవచ్చు."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ఏదేమైనా బ్రౌజర్ ద్వారా కొనసాగించండి"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"పనితీరు బూస్ట్"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"మీ యాప్ అనుభవాన్ని మెరుగుపరచండి"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s వెబ్సైట్కు వెళ్లడానికి ట్యాప్ చేసి, మరింత తెలుసుకోండి"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ఇప్పుడు కాదు"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"మేనేజ్ చేయండి"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"పనితీరు బూస్ట్ను కొనుగోలు చేయండి."</string>
diff --git a/packages/CarrierDefaultApp/res/values-th/strings.xml b/packages/CarrierDefaultApp/res/values-th/strings.xml
index 5b99194..e13ce44 100644
--- a/packages/CarrierDefaultApp/res/values-th/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-th/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"ผู้ให้บริการเครือข่ายมือถือ"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"เน็ตมือถือหมดแล้ว"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"อินเทอร์เน็ตมือถือของคุณถูกปิดใช้งานแล้ว"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"ตัวอย่างเช่น หน้าเข้าสู่ระบบอาจไม่ใช่ขององค์กรที่แสดงไว้"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"ดำเนินการต่อผ่านเบราว์เซอร์"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"การเพิ่มประสิทธิภาพ"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"ปรับปรุงประสบการณ์การใช้งานแอป"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"แตะเพื่อไปยังเว็บไซต์ของ %s และดูข้อมูลเพิ่มเติม"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ไว้ทีหลัง"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"จัดการ"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"ซื้อการเพิ่มประสิทธิภาพ"</string>
diff --git a/packages/CarrierDefaultApp/res/values-tl/strings.xml b/packages/CarrierDefaultApp/res/values-tl/strings.xml
index 42dfdeb..bdb09ac 100644
--- a/packages/CarrierDefaultApp/res/values-tl/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-tl/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobile Carrier"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Naubos na ang mobile data"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Na-deactivate na ang iyong mobile data"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Halimbawa, maaaring hindi pag-aari ng ipinapakitang organisasyon ang page ng login."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Magpatuloy pa rin sa pamamagitan ng browser"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Pag-boost ng performance"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Pagandahin ang iyong experience sa app"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"I-tap para pumunta sa website ng %s at matuto pa"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Huwag muna"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Pamahalaan"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Bumili ng pang-boost ng performance."</string>
diff --git a/packages/CarrierDefaultApp/res/values-tr/strings.xml b/packages/CarrierDefaultApp/res/values-tr/strings.xml
index 754c92c..e58d679 100644
--- a/packages/CarrierDefaultApp/res/values-tr/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-tr/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"VarsayılanOperatörUygulaması"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobil Operatör"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobil veri kotanız tükendi"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobil veriniz devre dışı bırakıldı"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Örneğin, giriş sayfası, gösterilen kuruluşa ait olmayabilir."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Yine de tarayıcıyla devam et"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Performans artışı"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Uygulama deneyiminizi iyileştirin"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s web sitesini ziyaret edip daha fazla bilgi edinmek için dokunun"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Şimdi değil"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Yönet"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Performans artışı satın alın."</string>
diff --git a/packages/CarrierDefaultApp/res/values-uk/strings.xml b/packages/CarrierDefaultApp/res/values-uk/strings.xml
index bbd6a70..deac7bb 100644
--- a/packages/CarrierDefaultApp/res/values-uk/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-uk/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"Додаток оператора за умовчанням"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Оператор мобільного зв’язку"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Мобільний трафік вичерпано"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Мобільний трафік дезактивовано"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Наприклад, сторінка входу може не належати вказаній організації."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Усе одно продовжити у веб-переглядачі"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Підвищення продуктивності"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Покращте взаємодію з додатком"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Натисніть, щоб перейти на веб-сайт %s і дізнатися більше"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Не зараз"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Керувати"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Придбайте підвищення продуктивності."</string>
diff --git a/packages/CarrierDefaultApp/res/values-ur/strings.xml b/packages/CarrierDefaultApp/res/values-ur/strings.xml
index e52f2c9..ef2677f 100644
--- a/packages/CarrierDefaultApp/res/values-ur/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-ur/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"موبائل کیریئر"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"موبائل ڈیٹا ختم ہو چکا ہے"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"آپ کا موبائل ڈیٹا غیر فعال کر دیا گیا ہے"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"مثال کے طور پر ہو سکتا ہے کہ لاگ ان صفحہ دکھائی گئی تنظیم سے تعلق نہ رکھتا ہو۔"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"براؤزر کے ذریعے بہرحال جاری رکھیں"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"پرفارمینس بوسٹ"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"اپنی ایپ کے تجربے کو بہتر بنائیں"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s کی ویب سائٹ دیکھنے کیلئے تھپتھپائیں اور مزید جانیں"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"ابھی نہیں"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"نظم کریں"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"پرفارمینس بوسٹ خریدیں۔"</string>
diff --git a/packages/CarrierDefaultApp/res/values-uz/strings.xml b/packages/CarrierDefaultApp/res/values-uz/strings.xml
index 04e1409..dd48975 100644
--- a/packages/CarrierDefaultApp/res/values-uz/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-uz/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Mobil aloqa operatori"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Mobil internet tugab qoldi"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Mobil internet o‘chirildi"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Masalan, tizimga kirish sahifasi ko‘rsatilgan tashkilotga tegishli bo‘lmasligi mumkin."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Brauzerda davom ettirish"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Unumdorlikni kuchaytirish"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Ilova ishlashini qulaylashtiring"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"%s saytini ochish va batafsil axborot olish uchun bosing"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Hozir emas"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Boshqarish"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Unumdorlikni kuchaytirish xizmatini xarid qiling."</string>
diff --git a/packages/CarrierDefaultApp/res/values-vi/strings.xml b/packages/CarrierDefaultApp/res/values-vi/strings.xml
index 4a4aab7..b01f951 100644
--- a/packages/CarrierDefaultApp/res/values-vi/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-vi/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Nhà cung cấp dịch vụ di động"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Dữ liệu di động đã hết"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Dữ liệu di động của bạn đã bị hủy kích hoạt"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Ví dụ: trang đăng nhập có thể không thuộc về tổ chức được hiển thị."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Vẫn tiếp tục qua trình duyệt"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"Tăng hiệu suất"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Cải thiện trải nghiệm dùng ứng dụng của bạn"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Nhấn để truy cập trang web của %s và tìm hiểu thêm."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Để sau"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Quản lý"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Mua gói tăng hiệu suất."</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
index f732723..e06cddb 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rCN/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"运营商默认应用"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"移动运营商"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"移动数据流量已用尽"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"您的移动数据网络已停用"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"例如,登录页面可能并不属于页面上显示的单位。"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"仍然通过浏览器继续操作"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"性能提升方案"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"提升您的应用体验"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"点按以访问%s的网站并了解详情"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"以后再说"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"管理"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"购买一份性能提升方案。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
index 1a223d2..ce51495 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rHK/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"流動網絡供應商"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"流動數據量已用盡"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"您的流動數據已停用"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"例如,登入頁面可能並不屬於所顯示的機構。"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"仍要透過瀏覽器繼續操作"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"效能提升服務"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"改善應用程式體驗"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"輕按即可瀏覽「%s」的網站和瞭解詳情"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"暫時不要"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"管理"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"購買效能提升服務。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml b/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml
index a932e20..db3e4db0 100644
--- a/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zh-rTW/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"電信業者預設應用程式"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"電信業者"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"行動數據已用盡"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"你的行動數據已停用"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"例如,登入網頁中顯示的機構可能並非該網頁實際隸屬的機構。"</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"仍要透過瀏覽器繼續操作"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"效能提升方案"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"改善應用程式體驗"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"輕觸即可造訪「%s」的網站及瞭解詳情"</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"暫時不要"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"管理"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"購買效能提升方案。"</string>
diff --git a/packages/CarrierDefaultApp/res/values-zu/strings.xml b/packages/CarrierDefaultApp/res/values-zu/strings.xml
index 20edb0e..dc09c9d 100644
--- a/packages/CarrierDefaultApp/res/values-zu/strings.xml
+++ b/packages/CarrierDefaultApp/res/values-zu/strings.xml
@@ -1,7 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_name" msgid="5247871339820894594">"CarrierDefaultApp"</string>
+ <!-- no translation found for app_name (2809080280462257271) -->
+ <skip />
<string name="android_system_label" msgid="2797790869522345065">"Inkampini yenethiwekhi yeselula"</string>
<string name="portal_notification_id" msgid="5155057562457079297">"Idatha yeselula iphelile"</string>
<string name="no_data_notification_id" msgid="668400731803969521">"Idatha yakho yeselula yenziwe yangasebenzi"</string>
@@ -15,8 +16,10 @@
<string name="ssl_error_example" msgid="6188711843183058764">"Isibonelo, ikhasi lokungena ngemvume kungenzeka lingelenhlangano ebonisiwe."</string>
<string name="ssl_error_continue" msgid="1138548463994095584">"Qhubeka noma kunjalo ngesiphequluli"</string>
<string name="performance_boost_notification_channel" msgid="3475440855635538592">"I-boost yokusebenza"</string>
- <string name="performance_boost_notification_title" msgid="6091638924925876776">"Thuthukisa okwenza nge-app"</string>
- <string name="performance_boost_notification_detail" msgid="907363829888387028">"Thepha ukuze uvakashele iwebhusayithi ye-%s futhi ufunde kabanzi."</string>
+ <!-- no translation found for performance_boost_notification_title (3126203390685781861) -->
+ <skip />
+ <!-- no translation found for performance_boost_notification_detail (216569851036236346) -->
+ <skip />
<string name="performance_boost_notification_button_not_now" msgid="6459755324243683785">"Hhayi manje"</string>
<string name="performance_boost_notification_button_manage" msgid="4976836444046497973">"Phatha"</string>
<string name="slice_purchase_app_label" msgid="7170191659233241166">"Thenga i-boost yokusebenza."</string>
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_device_other.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_device_other.xml
new file mode 100644
index 0000000..aafe466
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_device_other.xml
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_200">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M7,20H4Q3.175,20 2.588,19.413Q2,18.825 2,18V6Q2,5.175 2.588,4.588Q3.175,4 4,4H20V6H4Q4,6 4,6Q4,6 4,6V18Q4,18 4,18Q4,18 4,18H7ZM9,20V18.2Q8.55,17.775 8.275,17.225Q8,16.675 8,16Q8,15.325 8.275,14.775Q8.55,14.225 9,13.8V12H13V13.8Q13.45,14.225 13.725,14.775Q14,15.325 14,16Q14,16.675 13.725,17.225Q13.45,17.775 13,18.2V20ZM11,17.5Q11.65,17.5 12.075,17.075Q12.5,16.65 12.5,16Q12.5,15.35 12.075,14.925Q11.65,14.5 11,14.5Q10.35,14.5 9.925,14.925Q9.5,15.35 9.5,16Q9.5,16.65 9.925,17.075Q10.35,17.5 11,17.5ZM21,20H16Q15.575,20 15.288,19.712Q15,19.425 15,19V10Q15,9.575 15.288,9.287Q15.575,9 16,9H21Q21.425,9 21.712,9.287Q22,9.575 22,10V19Q22,19.425 21.712,19.712Q21.425,20 21,20ZM17,18H20V11H17Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_glasses.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_glasses.xml
index 97d201d..190e0a8 100644
--- a/packages/CompanionDeviceManager/res/drawable-night/ic_glasses.xml
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_glasses.xml
@@ -20,7 +20,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="@android:color/system_neutral1_200">
+ android:tint="@android:color/system_accent1_200">
<path
android:fillColor="@android:color/white"
android:pathData="M6.85,15Q7.625,15 8.238,14.55Q8.85,14.1 9.1,13.375L9.475,12.225Q9.875,11.025 9.275,10.012Q8.675,9 7.55,9H4.025L4.5,12.925Q4.625,13.8 5.287,14.4Q5.95,15 6.85,15ZM17.15,15Q18.05,15 18.712,14.4Q19.375,13.8 19.5,12.925L19.975,9H16.475Q15.35,9 14.75,10.025Q14.15,11.05 14.55,12.25L14.9,13.375Q15.15,14.1 15.762,14.55Q16.375,15 17.15,15ZM6.85,17Q5.2,17 3.963,15.912Q2.725,14.825 2.525,13.175L2,9H1V7H7.55Q8.65,7 9.562,7.537Q10.475,8.075 11,9H13.025Q13.55,8.075 14.463,7.537Q15.375,7 16.475,7H23V9H22L21.475,13.175Q21.275,14.825 20.038,15.912Q18.8,17 17.15,17Q15.725,17 14.588,16.188Q13.45,15.375 13,14.025L12.625,12.9Q12.575,12.725 12.525,12.537Q12.475,12.35 12.425,12H11.575Q11.525,12.3 11.475,12.487Q11.425,12.675 11.375,12.85L11,14Q10.55,15.35 9.413,16.175Q8.275,17 6.85,17Z"/>
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml
index 1611861..78120a3d 100644
--- a/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_permission_nearby_devices.xml
@@ -19,7 +19,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
+ android:tint="@android:color/system_accent1_200">
<path android:fillColor="@android:color/system_accent1_200"
android:pathData="M12,16.4 L7.6,12 12,7.6 16.4,12ZM13.4,21.375Q13.125,21.65 12.75,21.8Q12.375,21.95 12,21.95Q11.625,21.95 11.25,21.8Q10.875,21.65 10.6,21.375L2.625,13.4Q2.35,13.125 2.2,12.75Q2.05,12.375 2.05,12Q2.05,11.625 2.2,11.25Q2.35,10.875 2.625,10.6L10.575,2.65Q10.875,2.35 11.238,2.2Q11.6,2.05 12,2.05Q12.4,2.05 12.762,2.2Q13.125,2.35 13.425,2.65L21.375,10.6Q21.65,10.875 21.8,11.25Q21.95,11.625 21.95,12Q21.95,12.375 21.8,12.75Q21.65,13.125 21.375,13.4ZM12,19.2 L19.2,12Q19.2,12 19.2,12Q19.2,12 19.2,12L12,4.8Q12,4.8 12,4.8Q12,4.8 12,4.8L4.8,12Q4.8,12 4.8,12Q4.8,12 4.8,12L12,19.2Q12,19.2 12,19.2Q12,19.2 12,19.2Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable-night/ic_watch.xml b/packages/CompanionDeviceManager/res/drawable-night/ic_watch.xml
new file mode 100644
index 0000000..f1fda17
--- /dev/null
+++ b/packages/CompanionDeviceManager/res/drawable-night/ic_watch.xml
@@ -0,0 +1,25 @@
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ -->
+
+<vector xmlns:android="http://schemas.android.com/apk/res/android"
+ android:width="24dp"
+ android:height="24dp"
+ android:viewportWidth="24"
+ android:viewportHeight="24"
+ android:tint="@android:color/system_accent1_200">
+ <path android:fillColor="@android:color/white"
+ android:pathData="M9,22 L7.65,17.45Q6.45,16.5 5.725,15.075Q5,13.65 5,12Q5,10.35 5.725,8.925Q6.45,7.5 7.65,6.55L9,2H15L16.35,6.55Q17.55,7.5 18.275,8.925Q19,10.35 19,12Q19,13.65 18.275,15.075Q17.55,16.5 16.35,17.45L15,22ZM12,17Q14.075,17 15.538,15.537Q17,14.075 17,12Q17,9.925 15.538,8.462Q14.075,7 12,7Q9.925,7 8.463,8.462Q7,9.925 7,12Q7,14.075 8.463,15.537Q9.925,17 12,17ZM10.1,5.25Q11.075,4.975 12,4.975Q12.925,4.975 13.9,5.25L13.5,4H10.5ZM10.5,20H13.5L13.9,18.75Q12.925,19.025 12,19.025Q11.075,19.025 10.1,18.75ZM10.1,4H10.5H13.5H13.9Q12.925,4 12,4Q11.075,4 10.1,4ZM10.5,20H10.1Q11.075,20 12,20Q12.925,20 13.9,20H13.5Z"/>
+</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/btn_negative_multiple_devices.xml b/packages/CompanionDeviceManager/res/drawable/btn_negative_multiple_devices.xml
index ebe16a7..e6ac209 100644
--- a/packages/CompanionDeviceManager/res/drawable/btn_negative_multiple_devices.xml
+++ b/packages/CompanionDeviceManager/res/drawable/btn_negative_multiple_devices.xml
@@ -18,8 +18,7 @@
<shape xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<solid android:color="@android:color/transparent" />
- <corners android:topLeftRadius="16dp" android:topRightRadius="16dp"
- android:bottomLeftRadius="16dp" android:bottomRightRadius="16dp"/>
+ <corners android:radius="24dp" />
<stroke
android:width="1dp"
android:color="@android:color/system_accent1_600" />
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
index 15f6987..dc12d12 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_device_other.xml
@@ -19,7 +19,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
+ android:tint="@android:color/system_accent1_600">
<path android:fillColor="@android:color/white"
android:pathData="M7,20H4Q3.175,20 2.588,19.413Q2,18.825 2,18V6Q2,5.175 2.588,4.588Q3.175,4 4,4H20V6H4Q4,6 4,6Q4,6 4,6V18Q4,18 4,18Q4,18 4,18H7ZM9,20V18.2Q8.55,17.775 8.275,17.225Q8,16.675 8,16Q8,15.325 8.275,14.775Q8.55,14.225 9,13.8V12H13V13.8Q13.45,14.225 13.725,14.775Q14,15.325 14,16Q14,16.675 13.725,17.225Q13.45,17.775 13,18.2V20ZM11,17.5Q11.65,17.5 12.075,17.075Q12.5,16.65 12.5,16Q12.5,15.35 12.075,14.925Q11.65,14.5 11,14.5Q10.35,14.5 9.925,14.925Q9.5,15.35 9.5,16Q9.5,16.65 9.925,17.075Q10.35,17.5 11,17.5ZM21,20H16Q15.575,20 15.288,19.712Q15,19.425 15,19V10Q15,9.575 15.288,9.287Q15.575,9 16,9H21Q21.425,9 21.712,9.287Q22,9.575 22,10V19Q22,19.425 21.712,19.712Q21.425,20 21,20ZM17,18H20V11H17Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_glasses.xml b/packages/CompanionDeviceManager/res/drawable/ic_glasses.xml
index 9065520..0baf7ef 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_glasses.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_glasses.xml
@@ -20,7 +20,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
+ android:tint="@android:color/system_accent1_600">
<path
android:fillColor="@android:color/white"
android:pathData="M6.85,15Q7.625,15 8.238,14.55Q8.85,14.1 9.1,13.375L9.475,12.225Q9.875,11.025 9.275,10.012Q8.675,9 7.55,9H4.025L4.5,12.925Q4.625,13.8 5.287,14.4Q5.95,15 6.85,15ZM17.15,15Q18.05,15 18.712,14.4Q19.375,13.8 19.5,12.925L19.975,9H16.475Q15.35,9 14.75,10.025Q14.15,11.05 14.55,12.25L14.9,13.375Q15.15,14.1 15.762,14.55Q16.375,15 17.15,15ZM6.85,17Q5.2,17 3.963,15.912Q2.725,14.825 2.525,13.175L2,9H1V7H7.55Q8.65,7 9.562,7.537Q10.475,8.075 11,9H13.025Q13.55,8.075 14.463,7.537Q15.375,7 16.475,7H23V9H22L21.475,13.175Q21.275,14.825 20.038,15.912Q18.8,17 17.15,17Q15.725,17 14.588,16.188Q13.45,15.375 13,14.025L12.625,12.9Q12.575,12.725 12.525,12.537Q12.475,12.35 12.425,12H11.575Q11.525,12.3 11.475,12.487Q11.425,12.675 11.375,12.85L11,14Q10.55,15.35 9.413,16.175Q8.275,17 6.85,17Z"/>
diff --git a/packages/CompanionDeviceManager/res/drawable/ic_watch.xml b/packages/CompanionDeviceManager/res/drawable/ic_watch.xml
index d7a28d9..0f6b21f 100644
--- a/packages/CompanionDeviceManager/res/drawable/ic_watch.xml
+++ b/packages/CompanionDeviceManager/res/drawable/ic_watch.xml
@@ -20,7 +20,7 @@
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
- android:tint="?attr/colorControlNormal">
+ android:tint="@android:color/system_accent1_600">
<path android:fillColor="@android:color/white"
android:pathData="M9,22 L7.65,17.45Q6.45,16.5 5.725,15.075Q5,13.65 5,12Q5,10.35 5.725,8.925Q6.45,7.5 7.65,6.55L9,2H15L16.35,6.55Q17.55,7.5 18.275,8.925Q19,10.35 19,12Q19,13.65 18.275,15.075Q17.55,16.5 16.35,17.45L15,22ZM12,17Q14.075,17 15.538,15.537Q17,14.075 17,12Q17,9.925 15.538,8.462Q14.075,7 12,7Q9.925,7 8.463,8.462Q7,9.925 7,12Q7,14.075 8.463,15.537Q9.925,17 12,17ZM10.1,5.25Q11.075,4.975 12,4.975Q12.925,4.975 13.9,5.25L13.5,4H10.5ZM10.5,20H13.5L13.9,18.75Q12.925,19.025 12,19.025Q11.075,19.025 10.1,18.75ZM10.1,4H10.5H13.5H13.9Q12.925,4 12,4Q11.075,4 10.1,4ZM10.5,20H10.1Q11.075,20 12,20Q12.925,20 13.9,20H13.5Z"/>
</vector>
\ No newline at end of file
diff --git a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
index 22805f6..d470d4c 100644
--- a/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
+++ b/packages/CompanionDeviceManager/res/layout/activity_confirmation.xml
@@ -38,8 +38,7 @@
android:layout_width="match_parent"
android:layout_height="32dp"
android:gravity="center"
- android:layout_marginTop="18dp"
- android:tint="@android:color/system_accent1_600"/>
+ android:layout_marginTop="18dp" />
<LinearLayout style="@style/Description">
<TextView
@@ -123,21 +122,30 @@
<LinearLayout
android:layout_width="match_parent"
android:layout_height="wrap_content"
+ android:orientation="horizontal"
android:gravity="bottom|end"
- android:orientation="vertical"
android:layout_marginEnd="16dp"
android:layout_marginBottom="16dp">
<!-- Do NOT change the IDs of the buttons: they are referenced in CTS tests. -->
+ <LinearLayout
+ android:id="@+id/negative_multiple_devices_layout"
+ android:layout_width="wrap_content"
+ android:layout_height="48dp"
+ android:gravity="center"
+ android:visibility="gone">
- <Button
- android:id="@+id/btn_negative_multiple_devices"
- style="@style/NegativeButtonMultipleDevices"
- android:textColor="?android:textColorPrimary"
- android:visibility="gone"
- android:layout_marginTop="12dp"
- android:layout_marginBottom="12dp"
- android:text="@string/consent_no" />
+ <Button
+ android:id="@+id/btn_negative_multiple_devices"
+ style="@style/NegativeButtonMultipleDevices"
+ android:textColor="?android:textColorPrimary"
+ android:visibility="gone"
+ android:duplicateParentState="true"
+ android:clickable="false"
+ android:text="@string/consent_no" />
+
+ </LinearLayout>
+
</LinearLayout>
</LinearLayout>
diff --git a/packages/CompanionDeviceManager/res/layout/list_item_device.xml b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
index ac5294a..79f04b9 100644
--- a/packages/CompanionDeviceManager/res/layout/list_item_device.xml
+++ b/packages/CompanionDeviceManager/res/layout/list_item_device.xml
@@ -29,7 +29,6 @@
android:layout_width="24dp"
android:layout_height="24dp"
android:layout_marginStart="24dp"
- android:tint="@android:color/system_accent1_600"
android:importantForAccessibility="no"
android:contentDescription="@null"/>
diff --git a/packages/CompanionDeviceManager/res/values-af/strings.xml b/packages/CompanionDeviceManager/res/values-af/strings.xml
index 29caf5f..bbc6005 100644
--- a/packages/CompanionDeviceManager/res/values-af/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-af/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Kies \'n <xliff:g id="PROFILE_NAME">%1$s</xliff:g> om deur <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> bestuur te word"</string>
<string name="summary_watch" msgid="6566922405914995759">"Hierdie app is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om inligting te sinkroniseer, soos die naam van iemand wat bel, interaksie met jou kennisgewings te hê, en sal toegang tot jou Foon-, SMS-, Kontakte-, Mikrofoon-, en Toestelle in die Omtrek-toestemmings hê."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Hierdie app is nodig om jou <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om inligting te sinkroniseer, soos die naam van iemand wat bel, en toegang tot hierdie toestemmings:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Laat <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toe om <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> te bestuur?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"bril"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Hierdie app is nodig om <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te bestuur. <xliff:g id="APP_NAME">%2$s</xliff:g> sal toegelaat word om interaksie met jou kennisgewings te hê en sal toegang tot jou Foon-, SMS-, Kontakte-, Mikrofoon-, en Toestelle in die Omtrek-toestemmings hê."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Hierdie app sal toegang tot hierdie toestemmings op jou foon hê:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gee <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang tot hierdie inligting op jou foon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Oorkruistoestel-dienste"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om programme tussen jou toestelle te stroom"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Dienste"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot jou foon se foto\'s, media en kennisgewings"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Laat <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> toe om hierdie handeling uit te voer?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> versoek tans namens jou <xliff:g id="DEVICE_NAME">%2$s</xliff:g> toestemming om apps en ander stelselkenmerke na toestelle in die omtrek te stroom"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"toestel"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Hierdie app sal inligting kan sinkroniseer, soos die naam van iemand wat bel, tussen jou foon en <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Hierdie app sal inligting kan sinkroniseer, soos die naam van iemand wat bel, tussen jou foon en die gekose toestel."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
<string name="permission_notification" msgid="693762568127741203">"Kennisgewings"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Stroming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Kan foonoproepe maak en bestuur"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Kan foonoproeprekord lees en skryf"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Kan SMS-boodskappe stuur en ontvang"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Kan by jou kontakte ingaan"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Kan by jou kalender ingaan"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Kan oudio opneem"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Kan toestelle in die omtrek opspoor, aan hulle koppel en hul relatiewe posisie bepaal"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Kan alle kennisgewings lees, insluitend inligting soos kontakte, boodskappe en foto\'s"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Stroom jou foon se apps"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Stroom apps en ander stelselkenmerke van jou foon af"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-am/strings.xml b/packages/CompanionDeviceManager/res/values-am/strings.xml
index 97c1b96..2880fd5 100644
--- a/packages/CompanionDeviceManager/res/values-am/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-am/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"በ<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> የሚተዳደር <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ይምረጡ"</string>
<string name="summary_watch" msgid="6566922405914995759">"የእርስዎን <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ለማስተዳደር መተግበሪያው ያስፈልጋል። <xliff:g id="APP_NAME">%2$s</xliff:g> እንደ የሚደውል ሰው ስም፣ ከማሳወቂያዎችዎ ጋር መስተጋብር እንዲፈጥር እና የእርስዎን ስልክ፣ ኤስኤምኤስ፣ ዕውቅያዎች፣ የቀን መቁጠሪያ፣ የጥሪ ምዝግብ ማስታወሻዎች እና በአቅራቢያ ያሉ መሣሪያዎችን መድረስ ያሉ መረጃዎችን እንዲያሰምር ይፈቀድለታል።"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"የእርስዎን <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ለማስተዳደር መተግበሪያው ያስፈልጋል። <xliff:g id="APP_NAME">%2$s</xliff:g> እንደ የሚደውል ሰው ስም እና እነዚህን ፈቃዶች መድረስ ያሉ መረጃዎችን እንዲያሰምር ይፈቀድለታል፦"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ን እንዲያስተዳድር ይፈቅዳሉ?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"መነጽሮች"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"ይህ መተግበሪያ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ን ለማስተዳደር ያስፈልጋል። <xliff:g id="APP_NAME">%2$s</xliff:g> ከማሳወቂያዎችዎ ጋር መስተጋብር እንዲፈጥር እና የእርስዎን ስልክ፣ ኤስኤምኤስ፣ ዕውቂያዎች፣ ማይክሮፎን እና በአቅራቢያ ያሉ መሣሪያዎች ፈቃዶችን እንዲደርስ ይፈቀድለታል።"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"ይህ መተግበሪያ በስልክዎ ላይ እነዚህን ፈቃዶች ለመድረስ ፈቃድ ይሰጠዋል፦"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ይህን መረጃ ከስልክዎ እንዲደርስበት ይፍቀዱለት"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"መሣሪያ ተሻጋሪ አገልግሎቶች"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> በእርስዎ መሣሪያዎች መካከል መተግበሪያዎችን በዥረት ለመልቀቅ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"የGoogle Play አገልግሎቶች"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> የስልክዎን ፎቶዎች፣ ሚዲያ እና ማሳወቂያዎች ለመድረስ የእርስዎን <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ወክሎ ፈቃድ እየጠየቀ ነው"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ይህን እርምጃ እንዲወስድ ፈቃድ ይሰጠው?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> የእርስዎን <xliff:g id="DEVICE_NAME">%2$s</xliff:g> በመወከል በአቅራቢያ ላሉ መሣሪያዎች መተግበሪያዎች እና ሌሎች የስርዓት ባህሪያትን በዥረት ለመልቀቅ ፈቃድ እየጠየቀ ነው"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"መሣሪያ"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"ይህ መተግበሪያ እንደ የሚደውል ሰው ስም ያለ መረጃን በስልክዎ እና <xliff:g id="DEVICE_NAME">%1$s</xliff:g> መካከል ማስመር ይችላል።"</string>
<string name="summary_generic" msgid="4988130802522924650">"ይህ መተግበሪያ እንደ የሚደውል ሰው ስም ያለ መረጃን በስልክዎ እና በተመረጠው መሣሪያ መካከል ማስመር ይችላል።"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ፎቶዎች እና ሚዲያ"</string>
<string name="permission_notification" msgid="693762568127741203">"ማሳወቂያዎች"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"መተግበሪያዎች"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"በዥረት መልቀቅ"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"የስልክ ጥሪዎችን ማድረግ እና ማስተዳደር ይችላል"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"የስልክ ጥሪ ምዝገባ ማስታወሻን ማንበብ እና መጻፍ ይችላል"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"የኤስኤምኤስ መልዕክቶችን መላክ እና ማየት ይችላል"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"ዕውቂያዎችዎን መድረስ ይችላል"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"የቀን መቁጠሪያዎን መድረስ ይችላል"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ኦዲዮ መቅዳት ይችላል"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"በአቅራቢያ ያሉ መሣሪያዎችን ማግኘት፣ ከእነሱ ጋር መገናኘት እና አንጻራዊ ቦታቸውን መወሰን ይችላል"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"እንደ እውቂያዎች፣ መልዕክቶች እና ፎቶዎች ያሉ መረጃዎችን ጨምሮ ሁሉንም ማሳወቂያዎች ማንበብ ይችላል"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"የስልክዎን መተግበሪያዎች በዥረት ይልቀቁ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"ከስልክዎ ሆነው መተግበሪያዎች እና ሌሎች የስርዓት ባህሪያትን በዥረት ይልቀቁ"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ar/strings.xml b/packages/CompanionDeviceManager/res/values-ar/strings.xml
index bfb4225..e015940 100644
--- a/packages/CompanionDeviceManager/res/values-ar/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ar/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"اختَر <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ليديرها تطبيق <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"يجب توفّر التطبيق لإدارة \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". سيتم السماح لتطبيق \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" بمزامنة المعلومات، مثلاً اسم المتصل، والتفاعل مع الإشعارات والوصول إلى هاتفك، والرسائل القصيرة، وجهات الاتصال، والتقويم، وسجلات المكالمات وأذونات الأجهزة المجاورة."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"يجب توفّر التطبيق لإدارة \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". سيتم السماح لتطبيق \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" بمزامنة المعلومات، مثلاً اسم المتصل، والوصول إلى الأذونات التالية:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بإدارة <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"النظارة"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"يجب توفّر هذا التطبيق لإدارة \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". سيتم السماح لتطبيق \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" بالتفاعل مع الإشعارات والوصول إلى أذونات الهاتف والرسائل القصيرة وجهات الاتصال والميكروفون والأجهزة المجاورة."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"سيتم السماح لهذا التطبيق بالوصول إلى الأذونات التالية على هاتفك:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"السماح لتطبيق <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> بالوصول إلى هذه المعلومات من هاتفك"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"الخدمات التي تعمل بين الأجهزة"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"يطلب تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> لمشاركة التطبيقات بين أجهزتك."</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"خدمات Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"يطلب تطبيق <xliff:g id="APP_NAME">%1$s</xliff:g> الحصول على إذن نيابةً عن <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> للوصول إلى الصور والوسائط والإشعارات في هاتفك."</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"هل تريد السماح للتطبيق <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> باتّخاذ هذا الإجراء؟"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"يطلب \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" الحصول على إذن نيابةً عن \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\" لبثّ التطبيقات وميزات النظام الأخرى إلى أجهزتك المجاورة."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"جهاز"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"سيتمكن هذا التطبيق من مزامنة المعلومات، مثلاً اسم المتصل، بين هاتفك و\"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="summary_generic" msgid="4988130802522924650">"سيتمكن هذا التطبيق من مزامنة المعلومات، مثلاً اسم المتصل، بين هاتفك والجهاز المحدد."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"الصور والوسائط"</string>
<string name="permission_notification" msgid="693762568127741203">"الإشعارات"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"التطبيقات"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"البثّ"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"يمكن إجراء المكالمات الهاتفية وإدارتها."</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"يمكن قراءة سجلّ المكالمات الهاتفية والكتابة فيه."</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"يمكن إرسال الرسائل القصيرة وعرضها."</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"يمكن الوصول إلى جهات الاتصال."</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"يمكن الوصول إلى التقويم."</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"يمكنه تسجيل الصوت."</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"يمكن العثور على الموضع النسبي للأجهزة المجاورة والربط بها وتحديدها."</string>
<string name="permission_notification_summary" msgid="884075314530071011">"يمكن لهذا الملف الشخصي قراءة جميع الإشعارات، بما في ذلك المعلومات، مثل جهات الاتصال والرسائل والصور."</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"بث تطبيقات هاتفك"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"بثّ التطبيقات وميزات النظام الأخرى من هاتفك"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-as/strings.xml b/packages/CompanionDeviceManager/res/values-as/strings.xml
index b69c1c2..81f384f 100644
--- a/packages/CompanionDeviceManager/res/values-as/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-as/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>এ পৰিচালনা কৰিব লগা এটা <xliff:g id="PROFILE_NAME">%1$s</xliff:g> বাছনি কৰক"</string>
<string name="summary_watch" msgid="6566922405914995759">"আপোনাৰ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> পৰিচালনা কৰিবলৈ এপ্টোৰ আৱশ্যক। <xliff:g id="APP_NAME">%2$s</xliff:g>ক কল কৰোঁতাৰ নামৰ দৰে তথ্য ছিংক কৰিবলৈ, আপোনাৰ জাননীৰ সৈতে ভাব-বিনিময় কৰিবলৈ আৰু আপোনাৰ ফ’ন, এছএমএছ, সম্পৰ্ক, কেলেণ্ডাৰ, কল লগ আৰু নিকটৱৰ্তী ডিভাইচৰ অনুমতিসমূহ এক্সেছ কৰিবলৈ দিয়া হ’ব।"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"আপোনাৰ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> পৰিচালনা কৰিবলৈ এপ্টোৰ আৱশ্যক। <xliff:g id="APP_NAME">%2$s</xliff:g>ক কল কৰোঁতাৰ নামৰ দৰে তথ্য ছিংক কৰিবলৈ আৰু এই অনুমতিসমূহ এক্সেছ কৰিবলৈ অনুমতি দিয়া হ’ব:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> পৰিচালনা কৰিবলৈ দিবনে?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"চছ্মা"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> পৰিচালনা কৰিবলৈ এই এপ্টোৰ আৱশ্যক। <xliff:g id="APP_NAME">%2$s</xliff:g>ক আপোনাৰ অনুমতিসমূহৰ সৈতে ভাব-বিনিময় কৰিবলৈ আৰু আপোনাৰ ফ’ন, এছএমএছ, সম্পৰ্ক, মাইক্ৰ’ফ’ন আৰু নিকটৱৰ্তী ডিভাইচৰ অনুমতিসমূহ এক্সেছ কৰিবলৈ দিয়া হ’ব।"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"এই এপ্টোক আপোনাৰ ফ’নত এই অনুমতিসমূহ এক্সেছ কৰিবলৈ অনুমতি দিয়া হ’ব:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ক আপোনাৰ ফ’নৰ পৰা এই তথ্যখিনি এক্সেছ কৰাৰ অনুমতি দিয়ক"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্ৰছ-ডিভাইচ সেৱাসমূহ"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ডিভাইচসমূহৰ মাজত এপ্ ষ্ট্ৰীম কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play সেৱা"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>ৰ হৈ আপোনাৰ ফ’নৰ ফট’, মিডিয়া আৰু জাননী এক্সেছ কৰাৰ বাবে অনুৰোধ জনাইছে"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>ক এই কাৰ্যটো সম্পাদন কৰিবলৈ দিবনে?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g>এ আপোনাৰ <xliff:g id="DEVICE_NAME">%2$s</xliff:g>ৰ হৈ নিকটৱৰ্তী ডিভাইচত এপ্ আৰু ছিষ্টেমৰ অন্য সুবিধাসমূহ ষ্ট্ৰীম কৰাৰ অনুমতি দিবলৈ অনুৰোধ জনাইছে"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইচ"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"এই এপ্টোৱে আপোনাৰ ফ’ন আৰু <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ৰ মাজত তথ্য ছিংক কৰিব পাৰিব, যেনে, কল কৰোঁতাৰ নাম।"</string>
<string name="summary_generic" msgid="4988130802522924650">"এই এপ্টোৱে আপোনাৰ ফ’ন আৰু বাছনি কৰা ডিভাইচটোৰ মাজত তথ্য ছিংক কৰিব পাৰিব, যেনে, কল কৰোঁতাৰ নাম।"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ফট’ আৰু মিডিয়া"</string>
<string name="permission_notification" msgid="693762568127741203">"জাননী"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"এপ্"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"ষ্ট্ৰীম কৰি থকা হৈছে"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ফ’ন কল কৰিব আৰু পৰিচালনা কৰিব পাৰে"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ফ’নৰ কল লগ পঢ়িব আৰু লিখিব পাৰে"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"এছএমএছ বাৰ্তা পঠিয়াব আৰু চাব পাৰে"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"আপোনাৰ সম্পৰ্কসূচী এক্সেছ কৰিব পাৰে"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"আপোনাৰ কেলেণ্ডাৰ এক্সেছ কৰিব পাৰে"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"অডিঅ’ ৰেকৰ্ড কৰিব পাৰে"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"নিকটৱৰ্তী ডিভাইচসমূহ বিচাৰিব, সেইসমূহৰ সৈতে সংযুক্ত হ’ব আৰু সেইসমূহৰ আপেক্ষিক স্থান নিৰ্ধাৰণ কৰিব পাৰে"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"সম্পৰ্কসূচী, বাৰ্তা আৰু ফট’ৰ দৰে তথ্যকে ধৰি আটাইবোৰ জাননী পঢ়িব পাৰে"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"আপোনাৰ ফ’নৰ এপ্ ষ্ট্ৰীম কৰক"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"আপোনাৰ ফ’নৰ পৰা এপ্ আৰু ছিষ্টেমৰ অন্য সুবিধাসমূহ ষ্ট্ৰীম কৰক"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-az/strings.xml b/packages/CompanionDeviceManager/res/values-az/strings.xml
index 68acb6b..007bbc5 100644
--- a/packages/CompanionDeviceManager/res/values-az/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-az/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> tərəfindən idarə ediləcək <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
<string name="summary_watch" msgid="6566922405914995759">"Tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazını idarə etmək üçün lazımdır. <xliff:g id="APP_NAME">%2$s</xliff:g> tətbiqinə zəng edənin adı kimi məlumatları sinxronlaşdırmaq, bildirişlərlə qarşılıqlı əlaqəyə girmək, habelə Telefon, SMS, Kontaktlar, Təqvim, Zəng qeydləri və Yaxınlıqdakı cihazlar üzrə icazələrə daxil olmaq imkanı veriləcək."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazını idarə etmək üçün lazımdır. <xliff:g id="APP_NAME">%2$s</xliff:g> tətbiqinə zəng edənin adı kimi məlumatları sinxronlaşdırmaq və bu icazələrə daxil olmaq imkanı veriləcək:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazını idarə etmək icazəsi verilsin?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"eynək"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Bu tətbiq <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazını idarə etmək üçün lazımdır. <xliff:g id="APP_NAME">%2$s</xliff:g> bildirişlərə, Telefon, SMS, Kontaktlar, Mikrofon və Yaxınlıqdakı cihazlar icazələrinə giriş əldə edəcək."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Tətbiq telefonda bu icazələrə daxil ola biləcək:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tətbiqinə telefonunuzdan bu məlumata giriş icazəsi verin"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlararası xidmətlər"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından cihazlarınız arasında tətbiqləri yayımlamaq üçün icazə istəyir"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play xidmətləri"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> tətbiqi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> adından telefonunuzun fotoları, mediası və bildirişlərinə giriş üçün icazə istəyir"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> cihazına bu əməliyyatı yerinə yetirmək icazəsi verilsin?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> adından tətbiq və digər sistem funksiyalarını yaxınlıqdakı cihazlara yayımlamaq icazəsi sitəyir"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Bu tətbiq telefon və <xliff:g id="DEVICE_NAME">%1$s</xliff:g> arasında zəng edənin adı kimi məlumatları sinxronlaşdıra biləcək."</string>
<string name="summary_generic" msgid="4988130802522924650">"Bu tətbiq telefon və seçilmiş cihaz arasında zəng edənin adı kimi məlumatları sinxronlaşdıra biləcək."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto və media"</string>
<string name="permission_notification" msgid="693762568127741203">"Bildirişlər"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Tətbiqlər"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Yayım"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Telefon zəngi edə və onları idarə edə bilər"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Telefonun zəng qeydini oxuya və yaza bilər"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS mesajları göndərə və baxa bilər"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Kontaktlarınıza giriş edə bilər"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Təqviminizə giriş edə bilər"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Audio qeydə ala bilər"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Yaxınlıqdakı cihazları tapa, qoşula və nisbi mövqeyi təyin edə bilər"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Bütün bildirişləri, o cümlədən kontaktlar, mesajlar və fotolar kimi məlumatları oxuya bilər"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Telefonunuzun tətbiqlərini yayımlayın"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Telefondan tətbiq və digər sistem funksiyalarını yayımlayın"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
index 4812889..fea0d07 100644
--- a/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-b+sr+Latn/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Odaberite <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za sinhronizovanje informacija, poput osobe koja upućuje poziv, za interakciju sa obaveštenjima i pristup dozvolama za telefon, SMS, kontakte, kalendar, evidencije poziva i uređaje u blizini."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za sinhronizaciju informacija, poput osobe koja upućuje poziv, kao za pristup sledećim dozvolama:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Želite li da dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> upravlja uređajem <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"naočare"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Ova aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> će dobiti dozvolu za interakciju sa obaveštenjima i pristup dozvolama za telefon, SMS, kontakte, mikrofon i uređaje u blizini."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Ovoj aplikaciji će biti dozvoljeno da pristupa ovim dozvolama na telefonu:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama sa telefona"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na više uređaja"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za strimovanje aplikacija između uređaja"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup slikama, medijskom sadržaju i obaveštenjima sa telefona"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Želite li da dozvolite da <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> obavi ovu radnju?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahteva dozvolu u ime uređaja <xliff:g id="DEVICE_NAME">%2$s</xliff:g> da strimuje aplikacije i druge sistemske funkcije na uređaje u blizini"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ova aplikacija će moći da sinhronizuje podatke, poput imena osobe koja upućuje poziv, između telefona i uređaja <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ova aplikacija će moći da sinhronizuje podatke, poput imena osobe koja upućuje poziv, između telefona i odabranog uređaja."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Slike i mediji"</string>
<string name="permission_notification" msgid="693762568127741203">"Obaveštenja"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikacije"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Striming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Može da upućuje telefonske pozive i upravlja njima"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Može da čita i piše evidenciju poziva na telefonu"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Može da šalje i pregleda SMS poruke"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Može da pristupa kontaktima"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Može da pristupa kalendaru"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Može da snima zvuk"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Može da pronalazi i utvrđuje relativnu poziciju uređaja u blizini, kao i da se povezuje sa njima"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Može da čita sva obaveštenja, uključujući informacije poput kontakata, poruka i slika"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Strimujte aplikacije na telefonu"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Strimujte aplikacije i druge sistemske funkcije sa telefona"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-be/strings.xml b/packages/CompanionDeviceManager/res/values-be/strings.xml
index 76de34a..9bf51d5 100644
--- a/packages/CompanionDeviceManager/res/values-be/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-be/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Выберыце прыладу (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), якой будзе кіраваць праграма <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Гэта праграма неабходная для кіравання прыладай \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". <xliff:g id="APP_NAME">%2$s</xliff:g> зможа сінхранізаваць інфармацыю (напрыклад, імя таго, хто звоніць), узаемадзейнічаць з вашымі апавяшчэннямі, а таксама атрымае доступ да тэлефона, SMS, кантактаў, календара, журналаў выклікаў і прылад паблізу."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Гэта праграма неабходная для кіравання прыладай \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". <xliff:g id="APP_NAME">%2$s</xliff:g> зможа сінхранізаваць інфармацыю (напрыклад, імя таго, хто звоніць) і атрымае наступныя дазволы:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Дазволіць праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> кіраваць прыладай <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"акуляры"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Гэта праграма неабходная для кіравання прыладай \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". <xliff:g id="APP_NAME">%2$s</xliff:g> зможа ўзаемадзейнічаць з вашымі апавяшчэннямі і атрымае доступ да тэлефона, SMS, кантактаў, мікрафона і прылад паблізу."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Гэта праграма будзе мець на вашым тэлефоне наступныя дазволы:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дазвольце праграме <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> мець доступ да гэтай інфармацыі з вашага тэлефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сэрвісы для некалькіх прылад"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на трансляцыю праграм паміж вашымі прыладамі"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сэрвісы Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>\" на доступ да фота, медыяфайлаў і апавяшчэнняў на вашым тэлефоне"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Дазволіць прыладзе <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> выканаць гэта дзеянне?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Праграма \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запытвае дазвол ад імя вашай прылады \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\" на перадачу плынню змесціва праграм і іншых функцый сістэмы на прылады паблізу"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"прылада"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Гэта праграма зможа сінхранізаваць інфармацыю (напрыклад, імя таго, хто звоніць) паміж тэлефонам і прыладай \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="summary_generic" msgid="4988130802522924650">"Гэта праграма зможа сінхранізаваць інфармацыю (напрыклад, імя таго, хто звоніць) паміж тэлефонам і выбранай прыладай."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Фота і медыяфайлы"</string>
<string name="permission_notification" msgid="693762568127741203">"Апавяшчэнні"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Праграмы"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Перадача плынню"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Можа рабіць тэлефонныя выклікі і кіраваць імі"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Можа счытваць і запісваць даныя ў журнале тэлефонных выклікаў"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Можа адпраўляць і праглядаць SMS-паведамленні"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Можа атрымліваць доступ да вашых кантактаў"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Можа атрымліваць доступ да вашага календара"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Можа запісваць аўдыя"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Можа знаходзіць прылады паблізу, падключацца да іх і вызначаць іх прыблізнае месцазнаходжанне"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Можа счытваць усе апавяшчэнні, уключаючы паведамленні, фота і інфармацыю пра кантакты"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Трансляцыя змесціва праграм з вашага тэлефона"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Перадача плынню змесціва праграм і іншых функцый сістэмы з вашага тэлефона"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bg/strings.xml b/packages/CompanionDeviceManager/res/values-bg/strings.xml
index 36da32d..bd2e63b 100644
--- a/packages/CompanionDeviceManager/res/values-bg/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bg/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Изберете устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), което да се управлява от <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Това приложение е необходимо за управление на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ще получи право да синхронизира различна информация, като например името на обаждащия се, да взаимодейства с известията ви и достъп до разрешенията за телефона, SMS съобщенията, контактите, календара, списъците с обажданията и устройствата в близост."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Това приложение е необходимо за управление на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ще получи право да синхронизира различна информация, като например името на обаждащия се, и достъп до следните разрешения:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Разрешавате ли на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да управлява устройството <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"очилата"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Това приложение е необходимо за управление на <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Приложението <xliff:g id="APP_NAME">%2$s</xliff:g> ще получи право да взаимодейства с известията ви, както и достъп до разрешенията за телефона, SMS съобщенията, контактите, микрофона и устройствата в близост."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Това приложение ще има достъп до следните разрешения за телефона ви:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешете на <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да осъществява достъп до тази информация от телефона ви"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуги за различни устройства"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> да предава поточно приложения между устройствата ви"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги за Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за достъп до снимките, мултимедията и известията на телефона ви"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Разрешавате ли на <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> да предприема това действие?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> иска разрешение от името на <xliff:g id="DEVICE_NAME">%2$s</xliff:g> да предава поточно приложения и други системни функции към устройства в близост"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Това приложение ще може да синхронизира различна информация, като например името на обаждащия се, между телефона ви и <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Това приложение ще може да синхронизира различна информация, като например името на обаждащия се, между телефона ви и избраното устройство."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Снимки и мултимедия"</string>
<string name="permission_notification" msgid="693762568127741203">"Известия"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Приложения"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Поточно предаване"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Може да извършва и управлява телефонни обаждания"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Може да чете списъка с телефонните обаждания и да записва в него"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Може да изпраща и преглежда SMS съобщения"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Може да осъществява достъп до контактите ви"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Може да осъществява достъп до календара ви"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Може да записва звук"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Може да намира и да се свързва с устройства в близост, както и да определя относителната им позиция"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Може да чете всички известия, включително различна информация, като например контакти, съобщения и снимки"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Поточно предаване на приложенията на телефона ви"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Поточно предаване на приложения и други системни функции от телефона ви"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bn/strings.xml b/packages/CompanionDeviceManager/res/values-bn/strings.xml
index 20a6e27..c6d364f 100644
--- a/packages/CompanionDeviceManager/res/values-bn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bn/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> বেছে নিন যেটি <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ম্যানেজ করবে"</string>
<string name="summary_watch" msgid="6566922405914995759">"আপনার <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ম্যানেজ করার জন্য অ্যাপটি প্রয়োজন। <xliff:g id="APP_NAME">%2$s</xliff:g>-কে কলারের নামের মতো তথ্য সিঙ্ক করার অনুমতি দেওয়া হবে, এছাড়াও আপনার বিজ্ঞপ্তির সাথে ইন্টার্যাক্ট করা এবং আপনার ফোন, এসএমএস, পরিচিতি তালিকা, ক্যালেন্ডার, কল লগ এবং আশেপাশের ডিভাইস ব্যবহার করার অনুমতি অ্যাক্সেস করতে দেওয়া হবে।"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"আপনার <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ম্যানেজ করার জন্য অ্যাপটি প্রয়োজন। <xliff:g id="APP_NAME">%2$s</xliff:g>-কে কলারের নামের মতো তথ্য় সিঙ্ক করতে এবং এইসব অনুমতি অ্যাক্সেস করতে দেওয়া হবে:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"আপনি কি <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ম্যানেজ করার জন্য <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-কে অনুমতি দেবেন?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"চশমা"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ম্যানেজ করতে এই অ্যাপ দরকার। <xliff:g id="APP_NAME">%2$s</xliff:g>-কে আপনার বিজ্ঞপ্তির সাথে ইন্টার্যাক্ট করার এবং ফোন, এসএমএস, পরিচিতি, মাইক্রোফোন ও আশেপাশের ডিভাইসের অনুমতি অ্যাক্সেস করতে দেওয়া হবে।"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"আপনার ফোনের এইসব অনুমতি এই অ্যাপ অ্যাক্সেস করতে পারবে:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"আপনার ফোন থেকে <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> অ্যাপকে এই তথ্য অ্যাক্সেস করার অনুমতি দিন"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ক্রস-ডিভাইস পরিষেবা"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"আপনার ডিভাইসগুলির মধ্যে অ্যাপ স্ট্রিম করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play পরিষেবা"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"আপনার ফোনের ফটো, মিডিয়া এবং তথ্য অ্যাক্সেস করার জন্য <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-এর হয়ে অনুমতি চাইছে"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>কে এই অ্যাকশন করতে দেবেন?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"আশেপাশের ডিভাইসে অ্যাপ ও অন্যান্য সিস্টেম ফিচার স্ট্রিম করার জন্য আপনার <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-এর হয়ে <xliff:g id="APP_NAME">%1$s</xliff:g> অনুমতি চেয়ে অনুরোধ করছে"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ডিভাইস"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"এই অ্যাপ আপনার ফোন এবং <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ডিভাইসের মধ্যে তথ্য সিঙ্ক করতে পারবে, যেমন কলারের নাম।"</string>
<string name="summary_generic" msgid="4988130802522924650">"এই অ্যাপ আপনার ফোন এবং বেছে নেওয়া ডিভাইসের মধ্যে তথ্য সিঙ্ক করতে পারবে, যেমন কলারের নাম।"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ফটো ও মিডিয়া"</string>
<string name="permission_notification" msgid="693762568127741203">"বিজ্ঞপ্তি"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"অ্যাপ"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"স্ট্রিমিং"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ফোন কল করতে ও ম্যানেজ করতে পারবে"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ফোনের কল লগ পড়তে ও লিখতে পারবে"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"এসএমএস মেসেজ পাঠাতে ও দেখতে পারবে"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"আপনার পরিচিতি অ্যাক্সেস করতে পারবে"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"আপনার ক্যালেন্ডার অ্যাক্সেস করতে পারবে"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"অডিও রেকর্ড করতে পারে"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"আশেপাশের ডিভাইস খুঁজে দেখতে, তার সাথে কানেক্ট করতে এবং তার আপেক্ষিক অবস্থান নির্ধারণ করতে পারবে"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"সব বিজ্ঞপ্তি পড়তে পারবে, যার মধ্যে পরিচিতি, মেসেজ ও ফটোর মতো তথ্য অন্তর্ভুক্ত"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"আপনার ফোনের অ্যাপ স্ট্রিম করুন"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"আপনার ফোন থেকে অ্যাপ ও অন্যান্য সিস্টেম ফিচার স্ট্রিম করে"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-bs/strings.xml b/packages/CompanionDeviceManager/res/values-bs/strings.xml
index 1df3da5..ec3be16 100644
--- a/packages/CompanionDeviceManager/res/values-bs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-bs/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Odaberite uređaj \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> će biti dozvoljeni sinhroniziranje informacija, kao što je ime osobe koja upućuje poziv, interakcija s obavještenjima i pristup odobrenjima za Telefon, SMS-ove, Kontakte, Kalendar, Zapisnike poziva i Uređaje u blizini."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> će biti dozvoljeni sinhroniziranje informacija, kao što je ime osobe koja upućuje poziv, i pristup ovim odobrenjima:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Dozvoliti aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da upravlja uređajem <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"naočale"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Ova aplikacija je potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> će biti dozvoljena interakcija s obavještenjima i pristup odobrenjima za Telefon, SMS, Kontakte, Mikrofon i Uređaje u blizini."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Aplikaciji će biti dozvoljen pristup ovim odobrenjima na telefonu:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dozvolite da aplikacija <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pristupa ovim informacijama s telefona"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluga na više uređaja"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da prenosi aplikacije između vaših uređaja"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play usluge"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> zahtijeva odobrenje da pristupi fotografijama, medijima i odobrenjima na vašem telefonu"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Dozvoliti uređaju <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> da poduzme ovu radnju?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> u ime uređaja <xliff:g id="DEVICE_NAME">%2$s</xliff:g> traži odobrenje da prenosi aplikacije i druge funkcije sistema na uređajima u blizini"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ova aplikacija će moći sinhronizirati informacije, kao što je ime osobe koja upućuje poziv, između vašeg telefona i uređaja <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ova aplikacija će moći sinhronizirati informacije, kao što je ime osobe koja upućuje poziv, između vašeg telefona i odabranog uređaja."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string>
<string name="permission_notification" msgid="693762568127741203">"Obavještenja"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikacije"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Prijenos"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Može uspostavljati telefonske pozive i upravljati njima"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Može čitati i zapisivati zapisnik telefonskih poziva"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Može slati i prikazivati SMS poruke"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Može pristupiti kontaktima"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Može pristupiti kalendaru"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Može snimati zvuk"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Može pronaći uređaje u blizini, povezati se s njima i odrediti im relativan položaj"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sva obavještenja, uključujući informacije kao što su kontakti, poruke i fotografije"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Prenosite aplikacije s telefona"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Prijenos aplikacija i drugih funkcija sistema s vašeg telefona"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ca/strings.xml b/packages/CompanionDeviceManager/res/values-ca/strings.xml
index 56dd313..01c5869 100644
--- a/packages/CompanionDeviceManager/res/values-ca/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ca/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Tria un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> perquè el gestioni <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"L\'aplicació és necessària per gestionar el dispositiu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> tindrà permís per sincronitzar informació, com ara el nom d\'algú que truca, per interaccionar amb les teves notificacions i accedir al telèfon, als SMS, als contactes, al calendari, als registres de trucades i als dispositius propers."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"L\'aplicació és necessària per gestionar el dispositiu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> tindrà permís per sincronitzar informació, com ara el nom d\'algú que truca, i accedir a aquests permisos:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gestioni <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"ulleres"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Aquesta aplicació es necessita per gestionar el dispositiu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> tindrà permís per interaccionar amb les teves notificacions i accedir al telèfon, als SMS, als contactes, al micròfon i als dispositius propers."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Aquesta aplicació podrà accedir a aquests permisos del telèfon:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permet que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> accedeixi a aquesta informació del telèfon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serveis multidispositiu"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> per reproduir en continu aplicacions entre els dispositius"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Serveis de Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> demana permís en nom del teu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> per accedir a les fotos, el contingut multimèdia i les notificacions del telèfon"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vols permetre que <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> dugui a terme aquesta acció?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> sol·licita permís en nom del teu dispositiu (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) per reproduir en continu aplicacions i altres funcions del sistema en dispositius propers"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositiu"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Aquesta aplicació podrà sincronitzar informació, com ara el nom d\'algú que truca, entre el teu telèfon i el teu dispositiu (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)."</string>
<string name="summary_generic" msgid="4988130802522924650">"Aquesta aplicació podrà sincronitzar informació, com ara el nom d\'algú que truca, entre el teu telèfon i el dispositiu triat."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos i contingut multimèdia"</string>
<string name="permission_notification" msgid="693762568127741203">"Notificacions"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplicacions"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Reproducció en continu"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Pot fer i gestionar trucades"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Pot llegir i escriure el registre de trucades del telèfon"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Pot enviar i consultar missatges SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Pot accedir als contactes"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Pot accedir al calendari"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Pot gravar àudio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Pot determinar la posició relativa dels dispositius propers, cercar-los i connectar-s\'hi"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Pot llegir totes les notificacions, inclosa informació com ara els contactes, els missatges i les fotos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Reprodueix en continu aplicacions del telèfon"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Reprodueix en continu aplicacions i altres funcions del sistema des del telèfon"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-cs/strings.xml b/packages/CompanionDeviceManager/res/values-cs/strings.xml
index edb21d8..09c96a7 100644
--- a/packages/CompanionDeviceManager/res/values-cs/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-cs/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Vyberte zařízení <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, které chcete spravovat pomocí aplikace <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci synchronizovat údaje, jako je jméno volajícího, interagovat s vašimi oznámeními a získat přístup k vašim oprávněním k telefonu, SMS, kontaktům, kalendáři, seznamům hovorů a zařízením v okolí."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci synchronizovat údaje, jako je jméno volajícího, a získat přístup k těmto oprávněním:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Povolit aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> spravovat zařízení <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"brýle"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Tato aplikace je nutná ke správě zařízení <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude moci interagovat s vašimi oznámeními a získat přístup k vašim oprávněním k telefonu, SMS, kontaktům, mikrofonu a zařízením v okolí."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Tato aplikace bude mít ve vašem telefonu povolený přístup k těmto oprávněním:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povolte aplikaci <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> přístup k těmto informacím z vašeho telefonu"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pro více zařízení"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění ke streamování aplikací mezi zařízeními"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> požaduje za vaše zařízení <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> oprávnění k přístupu k fotkám, médiím a oznámením v telefonu"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Povolit zařízení <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> podniknout tuto akci?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikace <xliff:g id="APP_NAME">%1$s</xliff:g> žádá jménem vašeho zařízení <xliff:g id="DEVICE_NAME">%2$s</xliff:g> o oprávnění streamovat aplikace a další systémové funkce do zařízení v okolí"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zařízení"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, mezi vaším telefonem a zařízením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Tato aplikace bude moci synchronizovat údaje, jako je jméno volajícího, mezi vaším telefonem a vybraným zařízením."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotky a média"</string>
<string name="permission_notification" msgid="693762568127741203">"Oznámení"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikace"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streamování"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Může uskutečňovat a spravovat telefonní hovory"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Může číst seznam telefonních hovorů a zapisovat do něj"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Může odesílat a číst zprávy SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Má přístup k vašim kontaktům"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Má přístup k vašemu kalendáři"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Může nahrávat zvuk"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Může nacházet zařízení v okolí, připojovat se k nim a zjišťovat jejich relativní polohu"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Může číst veškerá oznámení včetně informací, jako jsou kontakty, zprávy a fotky"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Streamujte aplikace v telefonu"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Streamování aplikací a dalších systémových funkcí z telefonu"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-da/strings.xml b/packages/CompanionDeviceManager/res/values-da/strings.xml
index 181c4aa..17ed586 100644
--- a/packages/CompanionDeviceManager/res/values-da/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-da/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Vælg det <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, som skal administreres af <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Du skal bruge denne app for at administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tilladelse til at interagere med dine notifikationer og synkronisere oplysninger som f.eks. navnet på en person, der ringer, og appen får adgang til dine tilladelser for Opkald, Sms, Kalender, Opkaldshistorik og Enheder i nærheden."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Du skal bruge denne app for at administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tilladelse til at synkronisere oplysninger som f.eks. navnet på en person, der ringer, og appen får adgang til følgende tilladelser:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vil du tillade, at <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> administrerer <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"briller"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Du skal bruge denne app for at administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tilladelse til at interagere med dine notifikationer og tilgå tilladelserne Telefon, Sms, Kontakter, Mikrofon og Enheder i nærheden."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Denne app får tilladelse til at tilgå disse tilladelser på din telefon:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Giv <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> adgang til disse oplysninger fra din telefon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester, som kan tilsluttes en anden enhed"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at streame apps mellem dine enheder"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> til at få adgang til din telefons billeder, medier og notifikationer"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vil du tillade, at <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> foretager denne handling?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> anmoder om tilladelse på vegne af din <xliff:g id="DEVICE_NAME">%2$s</xliff:g> til at streame apps og andre systemfunktioner til enheder i nærheden"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhed"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Denne app vil kunne synkronisere oplysninger som f.eks. navnet på en person, der ringer, mellem din telefon og <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Denne app vil kunne synkronisere oplysninger som f.eks. navnet på en person, der ringer, mellem din telefon og den valgte enhed."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Billeder og medier"</string>
<string name="permission_notification" msgid="693762568127741203">"Notifikationer"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Kan foretage og administrere telefonopkald"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Kan læse og redigere opkaldshistorik"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Kan sende og se sms-beskeder"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Kan tilgå dine kontakter"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Kan tilgå din kalender"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Kan optage lyd"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Kan finde, oprette forbindelse til og fastslå den omtrentlige lokation af enheder i nærheden"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Kan læse alle notifikationer, herunder oplysninger som f.eks. kontakter, beskeder og billeder"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Stream din telefons apps"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Stream apps og andre systemfunktioner fra din telefon"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-de/strings.xml b/packages/CompanionDeviceManager/res/values-de/strings.xml
index 5063e7e..bfb750e 100644
--- a/packages/CompanionDeviceManager/res/values-de/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-de/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Gerät „<xliff:g id="PROFILE_NAME">%1$s</xliff:g>“ auswählen, das von <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> verwaltet werden soll"</string>
<string name="summary_watch" msgid="6566922405914995759">"Die App wird zur Verwaltung deines Geräts (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) benötigt. <xliff:g id="APP_NAME">%2$s</xliff:g> darf dann Daten wie den Namen eines Anrufers synchronisieren, mit deinen Benachrichtigungen interagieren und auf die Berechtigungen „Telefon“, „SMS“, „Kontakte“, „Kalender“, „Anruflisten“ und „Geräte in der Nähe“ zugreifen."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Die App wird zur Verwaltung deines Geräts (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) benötigt. <xliff:g id="APP_NAME">%2$s</xliff:g> darf dann Daten wie den Namen eines Anrufers synchronisieren und auf folgende Berechtigungen zugreifen:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Zulassen, dass <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> das Gerät <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> verwalten darf"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"Glass-Geräte"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Diese App wird zur Verwaltung deines Geräts (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) benötigt. <xliff:g id="APP_NAME">%2$s</xliff:g> darf mit deinen Benachrichtigungen interagieren und auf die Berechtigungen „Telefon“, „SMS“, „Kontakte“, „Mikrofon“ und „Geräte in der Nähe“ zugreifen."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Diese App darf auf die folgenden Berechtigungen auf deinem Smartphone zugreifen:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> Zugriff auf diese Informationen von deinem Smartphone gewähren"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Geräteübergreifende Dienste"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Streamen von Apps zwischen deinen Geräten"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-Dienste"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet im Namen deines <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> um die Berechtigung zum Zugriff auf die Fotos, Medien und Benachrichtigungen deines Smartphones"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Darf das Gerät <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> diese Aktion ausführen?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> bittet für dein Gerät (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) um die Berechtigung, Apps und andere Systemfunktionen auf Geräte in der Nähe zu streamen"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"Gerät"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Diese App kann dann Daten wie den Namen eines Anrufers zwischen deinem Smartphone und deinem Gerät (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) synchronisieren."</string>
<string name="summary_generic" msgid="4988130802522924650">"Diese App kann dann Daten wie den Namen eines Anrufers zwischen deinem Smartphone und dem ausgewählten Gerät synchronisieren."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos und Medien"</string>
<string name="permission_notification" msgid="693762568127741203">"Benachrichtigungen"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Kann Anrufe tätigen und verwalten"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Kann auf die Anrufliste zugreifen und sie bearbeiten"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Kann SMS senden und abrufen"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Kann auf deine Kontakte zugreifen"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Kann auf deinen Kalender zugreifen"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Darf Audio aufnehmen"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Kann Geräte in der Nähe finden, eine Verbindung zu ihnen herstellen und ihren relativen Standort ermitteln"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Kann alle Benachrichtigungen lesen, einschließlich Informationen wie Kontakten, Nachrichten und Fotos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Smartphone-Apps streamen"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Apps und andere Systemfunktionen von deinem Smartphone streamen"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-el/strings.xml b/packages/CompanionDeviceManager/res/values-el/strings.xml
index 992d7cf..d0b4609 100644
--- a/packages/CompanionDeviceManager/res/values-el/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-el/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Επιλέξτε ένα προφίλ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> για διαχείριση από την εφαρμογή <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Η εφαρμογή <xliff:g id="APP_NAME">%2$s</xliff:g> θα μπορεί να συγχρονίζει πληροφορίες, όπως το όνομα ενός ατόμου που σας καλεί, να αλληλεπιδρά με τις ειδοποιήσεις σας και να αποκτά πρόσβαση στις άδειες Τηλέφωνο, SMS, Επαφές, Ημερολόγιο, Αρχεία καταγρ. κλήσ. και Συσκευές σε κοντινή απόσταση."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Η εφαρμογή <xliff:g id="APP_NAME">%2$s</xliff:g> θα μπορεί να συγχρονίζει πληροφορίες, όπως το όνομα ενός ατόμου που σας καλεί, και να αποκτά πρόσβαση σε αυτές τις άδειες:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Να επιτρέπεται στην εφαρμογή <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> να διαχειρίζεται τη συσκευή <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ;"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"γυαλιά"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Αυτή η εφαρμογή είναι απαραίτητη για τη διαχείριση της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Θα επιτρέπεται στην εφαρμογή <xliff:g id="APP_NAME">%2$s</xliff:g> να αλληλεπιδρά με τις ειδοποιήσεις σας και να αποκτά πρόσβαση στις άδειες για το Τηλέφωνο, τα SMS, τις Επαφές, το Μικρόφωνο και τις Συσκευές σε κοντινή απόσταση."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Αυτή η εφαρμογή θα μπορεί να έχει πρόσβαση σε αυτές τις άδειες στο τηλέφωνό σας:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Να επιτρέπεται στο <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> η πρόσβαση σε αυτές τις πληροφορίες από το τηλέφωνό σας."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Υπηρεσίες πολλών συσκευών"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για ροή εφαρμογών μεταξύ των συσκευών σας"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Υπηρεσίες Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά εκ μέρους της συσκευής σας <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> άδεια για πρόσβαση στις φωτογραφίες, τα αρχεία μέσων και τις ειδοποιήσεις του τηλεφώνου σας"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Να επιτρέπεται στη συσκευή <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> να εκτελεί αυτήν την ενέργεια;"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Η εφαρμογή <xliff:g id="APP_NAME">%1$s</xliff:g> ζητά άδεια εκ μέρους της συσκευής σας <xliff:g id="DEVICE_NAME">%2$s</xliff:g> για ροή εφαρμογών και άλλων λειτουργιών του συστήματος σε συσκευές σε κοντινή απόσταση"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"συσκευή"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Αυτή η εφαρμογή θα μπορεί να συγχρονίζει πληροφορίες μεταξύ του τηλεφώνου και της συσκευής <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, όπως το όνομα ενός ατόμου που σας καλεί."</string>
<string name="summary_generic" msgid="4988130802522924650">"Αυτή η εφαρμογή θα μπορεί να συγχρονίζει πληροφορίες μεταξύ του τηλεφώνου και της επιλεγμένης συσκευής σας, όπως το όνομα ενός ατόμου που σας καλεί."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Φωτογραφίες και μέσα"</string>
<string name="permission_notification" msgid="693762568127741203">"Ειδοποιήσεις"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Εφαρμογές"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Ροή"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Μπορεί να πραγματοποιήσει και να διαχειριστεί τηλεφωνικές κλήσεις"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Έχει άδεια ανάγνωσης και εγγραφής στο αρχείο καταγραφής κλήσεων του τηλεφώνου"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Μπορεί να στείλει και να προβάλλει μηνύματα SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Έχει πρόσβαση στις επαφές σας"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Έχει πρόσβαση στο ημερολόγιό σας"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Μπορεί να κάνει εγγραφή ήχου"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Δεν μπορεί να βρει, να συνδεθεί και να προσδιορίσει τη σχετική τοποθεσία των κοντινών συσκευών"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Μπορεί να διαβάσει όλες τις ειδοποιήσεις, συμπεριλαμβανομένων πληροφοριών όπως επαφές, μηνύματα και φωτογραφίες"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Μεταδώστε σε ροή τις εφαρμογές του τηλεφώνου σας"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Ροή εφαρμογών και άλλων λειτουργιών του συστήματος από το τηλέφωνό σας"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
index 21b8434..e4215c6 100644
--- a/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rAU/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, and access these permissions:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"This app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, microphone and Nearby devices permissions."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"This app will be allowed to access these permissions on your phone:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Allow <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> to take this action?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_NAME">%2$s</xliff:g> to stream apps and other system features to nearby devices"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Can make and manage phone calls"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Can read and write phone call log"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Can send and view SMS messages"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Can access your contacts"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Can access your calendar"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Can record audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Can find, connect to and determine the relative position of nearby devices"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Stream your phone’s apps"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Stream apps and other system features from your phone"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
index 21b8434..e4215c6 100644
--- a/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rGB/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, and access these permissions:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"This app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, microphone and Nearby devices permissions."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"This app will be allowed to access these permissions on your phone:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Allow <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> to take this action?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_NAME">%2$s</xliff:g> to stream apps and other system features to nearby devices"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Can make and manage phone calls"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Can read and write phone call log"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Can send and view SMS messages"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Can access your contacts"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Can access your calendar"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Can record audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Can find, connect to and determine the relative position of nearby devices"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Stream your phone’s apps"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Stream apps and other system features from your phone"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
index 21b8434..e4215c6 100644
--- a/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-en-rIN/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Choose a <xliff:g id="PROFILE_NAME">%1$s</xliff:g> to be managed by <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, interact with your notifications and access your Phone, SMS, Contacts, Calendar, Call logs and Nearby devices permissions."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"The app is needed to manage your <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to sync info, like the name of someone calling, and access these permissions:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to manage <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"This app is needed to manage <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> will be allowed to interact with your notifications and access your phone, SMS, contacts, microphone and Nearby devices permissions."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"This app will be allowed to access these permissions on your phone:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Allow <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> to access this information from your phone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to stream apps between your devices"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> to access your phone’s photos, media and notifications"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Allow <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> to take this action?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> is requesting permission on behalf of your <xliff:g id="DEVICE_NAME">%2$s</xliff:g> to stream apps and other system features to nearby devices"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"This app will be able to sync info, like the name of someone calling, between your phone and <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"This app will be able to sync info, like the name of someone calling, between your phone and the chosen device."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos and media"</string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Can make and manage phone calls"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Can read and write phone call log"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Can send and view SMS messages"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Can access your contacts"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Can access your calendar"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Can record audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Can find, connect to and determine the relative position of nearby devices"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Can read all notifications, including information like contacts, messages and photos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Stream your phone’s apps"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Stream apps and other system features from your phone"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
index df5562e..97b68ed 100644
--- a/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es-rUS/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para que la app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> lo administre"</string>
<string name="summary_watch" msgid="6566922405914995759">"Esta app es necesaria para administrar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá sincronizar información, como el nombre de la persona que llama, interactuar con tus notificaciones y acceder a los permisos de Teléfono, SMS, Contactos, Calendario, Llamadas y Dispositivos cercanos."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Esta app es necesaria para administrar tu <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá sincronizar información, como el nombre de la persona que llama, y acceder a los siguientes permisos:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> administre <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"Gafas"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Esta app es necesaria para administrar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con tus notificaciones y acceder a los permisos de Teléfono, SMS, Contactos, Micrófono y Dispositivos cercanos."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Esta app podrá acceder a los siguientes permisos en tu teléfono:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permite que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para transmitir apps entre dispositivos"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicita tu permiso en nombre de <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, el contenido multimedia y las notificaciones de tu teléfono"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"¿Permites que <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> realice esta acción?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nombre de tu <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para transmitir apps y otras funciones del sistema a dispositivos cercanos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Esta app podrá sincronizar información, como el nombre de la persona que llama, entre el teléfono y <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Esta app podrá sincronizar información, como el nombre de la persona que llama, entre el teléfono y el dispositivo elegido."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos y contenido multimedia"</string>
<string name="permission_notification" msgid="693762568127741203">"Notificaciones"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Transmisión"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Puede hacer y administrar llamadas telefónicas"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Puede leer y escribir el registro de llamadas telefónicas"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Puede enviar y ver mensajes SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Puede acceder a los contactos"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Puede acceder al calendario"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Puede grabar audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Puede encontrar, conectarse con y determinar la ubicación relativa de los dispositivos cercanos"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Puede leer todas las notificaciones, incluso con información como contactos, mensajes y fotos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Transmitir las apps de tu teléfono"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Transmite apps y otras funciones del sistema desde tu teléfono"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-es/strings.xml b/packages/CompanionDeviceManager/res/values-es/strings.xml
index ba8fd5d..5ecf79e 100644
--- a/packages/CompanionDeviceManager/res/values-es/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-es/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Elige un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para gestionarlo con <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Se necesita la aplicación para gestionar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá sincronizar información (por ejemplo, el nombre de la persona que te llama), interactuar con tus notificaciones y acceder a tus permisos de teléfono, SMS, contactos, calendario, registros de llamadas y dispositivos cercanos."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Se necesita la aplicación para gestionar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá sincronizar información (por ejemplo, el nombre de la persona que te llama) y acceder a los permisos siguientes:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"¿Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gestione <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"gafas"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Se necesita esta aplicación para gestionar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> podrá interactuar con tus notificaciones y acceder a tus permisos de teléfono, SMS, contactos, micrófono y dispositivos cercanos."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Esta aplicación podrá acceder a los siguientes permisos de tu teléfono:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información de tu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicios multidispositivo"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para emitir aplicaciones en otros dispositivos tuyos"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicios de Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acceder a las fotos, los archivos multimedia y las notificaciones de tu teléfono"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"¿Permitir que <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> realice esta acción?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pidiendo permiso en nombre de tu <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para emitir aplicaciones y otras funciones del sistema en dispositivos cercanos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Esta aplicación podrá sincronizar información (por ejemplo, el nombre de la persona que te llama) entre tu teléfono y <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Esta aplicación podrá sincronizar información (por ejemplo, el nombre de la persona que te llama) entre tu teléfono y el dispositivo que elijas."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos y elementos multimedia"</string>
<string name="permission_notification" msgid="693762568127741203">"Notificaciones"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplicaciones"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Emitir"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Puede hacer y gestionar llamadas"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Puede leer y escribir en el registro de llamadas del teléfono"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Puede enviar y ver mensajes SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Puede acceder a tus contactos"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Puede acceder a tu calendario"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Puede grabar audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Puede buscar, conectarse y determinar la posición relativa de dispositivos cercanos"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Puede leer todas las notificaciones, incluida información como contactos, mensajes y fotos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Muestra en streaming las aplicaciones de tu teléfono"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Emite aplicaciones y otras funciones del sistema desde tu teléfono"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-et/strings.xml b/packages/CompanionDeviceManager/res/values-et/strings.xml
index fadb56a..f0e565f2 100644
--- a/packages/CompanionDeviceManager/res/values-et/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-et/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Valige <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, mida haldab rakendus <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Seda rakendust on vaja teie seadme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> haldamiseks. Rakendusel <xliff:g id="APP_NAME">%2$s</xliff:g> lubatakse sünkroonida teavet, näiteks helistaja nime, kasutada teie märguandeid ning pääseda juurde teie telefoni, SMS-ide, kontaktide, kalendri, kõnelogide ja läheduses olevate seadmete lubadele."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Seda rakendust on vaja teie seadme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> haldamiseks. <xliff:g id="APP_NAME">%2$s</xliff:g> lubatakse sünkroonida teavet, näiteks helistaja nime, ja pääseda juurde järgmistele lubadele."</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> hallata seadet <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"prillid"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Seda rakendust on vaja seadme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> haldamiseks. Rakendusel <xliff:g id="APP_NAME">%2$s</xliff:g> lubatakse kasutada teie märguandeid ning pääseda juurde teie telefoni, SMS-ide, kontaktide, mikrofoni ja läheduses olevate seadmete lubadele."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Sellele rakendusele antakse luba neile juurdepääsudele teie telefonis:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lubage rakendusel <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pääseda teie telefonis juurde sellele teabele"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Seadmeülesed teenused"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba teie seadmete vahel rakendusi voogesitada"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play teenused"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nimel luba pääseda juurde telefoni fotodele, meediale ja märguannetele"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Kas lubada seadmel <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> teha seda toimingut?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> taotleb teie seadme <xliff:g id="DEVICE_NAME">%2$s</xliff:g> nimel luba voogesitada rakendusi ja muid süsteemi funktsioone läheduses olevatesse seadmetesse"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"seade"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"See rakendus saab sünkroonida teavet, näiteks helistaja nime, teie telefoni ja seadme <xliff:g id="DEVICE_NAME">%1$s</xliff:g> vahel."</string>
<string name="summary_generic" msgid="4988130802522924650">"See rakendus saab sünkroonida teavet, näiteks helistaja nime, teie telefoni ja valitud seadme vahel."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotod ja meedia"</string>
<string name="permission_notification" msgid="693762568127741203">"Märguanded"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Rakendused"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Voogesitus"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Saab teha ja hallata telefonikõnesid"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Saab telefoni kõnelogi lugeda ja sinna kirjutada"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Saab saata ja vaadata SMS-sõnumeid"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Pääseb juurde teie kontaktidele"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Pääseb juurde teie kalendrile"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Saab salvestada heli"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Leiab läheduses olevaid seadmeid, saab nendega ühenduse luua ja määrata nende suhtelise asendi"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Kõikide märguannete, sealhulgas teabe, nagu kontaktid, sõnumid ja fotod, lugemine"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Telefoni rakenduste voogesitamine"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Rakenduste ja muude süsteemi funktsioonide voogesitamine teie telefonist"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-eu/strings.xml b/packages/CompanionDeviceManager/res/values-eu/strings.xml
index 4d2b67c..caebdda 100644
--- a/packages/CompanionDeviceManager/res/values-eu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-eu/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Aukeratu <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> aplikazioak kudeatu beharreko <xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="summary_watch" msgid="6566922405914995759">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> kudeatzeko behar da aplikazioa. Informazioa sinkronizatzeko (esate baterako, deitzaileen izenak), jakinarazpenekin interakzioan aritzeko, eta telefonoa, SMSak, kontaktuak, egutegia, deien erregistroa eta inguruko gailuak erabiltzeko baimena izango du <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> kudeatzeko behar da aplikazioa. Informazioa sinkronizatzeko (esate baterako, deitzaileen izenak) eta ekintza hauek gauzatzeko baimena izango du <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> kudeatzeko baimena eman nahi diozu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"betaurrekoak"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailua kudeatzeko behar da aplikazioa. Jakinarazpenekin interakzioan aritzeko, eta telefonoa, SMSak, kontaktuak, mikrofonoa eta inguruko gailuak erabiltzeko baimena izango du <xliff:g id="APP_NAME">%2$s</xliff:g> aplikazioak."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Telefonoko baimen hauek erabiltzeko baimena izango du aplikazioak:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Eman informazioa telefonotik hartzeko baimena <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aplikazioari"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Gailu baterako baino gehiagotarako zerbitzuak"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Gailu batetik bestera aplikazioak igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Telefonoko argazkiak, multimedia-edukia eta jakinarazpenak erabiltzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> gailuaren izenean"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ekintza hau gauzatzeko baimena eman nahi diozu <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> aplikazioari?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikazioak eta sistemaren beste eginbide batzuk inguruko gailuetara igortzeko baimena eskatzen ari da <xliff:g id="APP_NAME">%1$s</xliff:g>, <xliff:g id="DEVICE_NAME">%2$s</xliff:g> gailuaren izenean"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"gailua"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Telefonoaren eta <xliff:g id="DEVICE_NAME">%1$s</xliff:g> gailuaren artean informazioa sinkronizatzeko gai izango da aplikazioa (esate baterako, deitzaileen izenak)."</string>
<string name="summary_generic" msgid="4988130802522924650">"Telefonoaren eta hautatutako gailuaren artean informazioa sinkronizatzeko gai izango da aplikazioa (esate baterako, deitzaileen izenak)."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Argazkiak eta multimedia-edukia"</string>
<string name="permission_notification" msgid="693762568127741203">"Jakinarazpenak"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikazioak"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Igortzea"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Telefono-deiak egin eta kudea ditzake"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Telefonoko deien erregistroa irakurri, eta bertan idatz dezake"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS mezuak bidali eta ikus ditzake"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Kontaktuak atzi ditzake"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Egutegia atzi dezake"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Audioa graba dezake"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Inguruko gailuak aurki ditzake, haietara konekta daiteke eta haien posizio erlatiboa zehatz dezake"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Jakinarazpen guztiak irakur ditzake; besteak beste, kontaktuak, mezuak, argazkiak eta antzeko informazioa"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Igorri zuzenean telefonoko aplikazioak"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Igorri aplikazioak eta sistemaren beste eginbide batzuk telefonotik"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fa/strings.xml b/packages/CompanionDeviceManager/res/values-fa/strings.xml
index 5d638e0..031b9d9 100644
--- a/packages/CompanionDeviceManager/res/values-fa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fa/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"انتخاب <xliff:g id="PROFILE_NAME">%1$s</xliff:g> برای مدیریت کردن با <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"این برنامه برای مدیریت <xliff:g id="DEVICE_NAME">%1$s</xliff:g> شما لازم است. به <xliff:g id="APP_NAME">%2$s</xliff:g> اجازه داده میشود اطلاعاتی مثل نام شخصی که تماس میگیرد را همگامسازی کند، با اعلانهای شما تعامل داشته باشد، و به اجازههای «تلفن»، «پیامک»، «مخاطبین»، «تقویم»، «گزارشهای تماس»، و «دستگاههای اطراف» دسترسی داشته باشد."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"این برنامه برای مدیریت <xliff:g id="DEVICE_NAME">%1$s</xliff:g> شما لازم است. به <xliff:g id="APP_NAME">%2$s</xliff:g> اجازه داده میشود اطلاعاتی مثل نام شخصی که تماس میگیرد را همگامسازی کند و به این اجازهها دسترسی داشته باشد:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> اجازه داده شود <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> را مدیریت کند؟"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"عینک"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"این برنامه برای مدیریت <xliff:g id="DEVICE_NAME">%1$s</xliff:g> لازم است. به <xliff:g id="APP_NAME">%2$s</xliff:g> اجازه داده میشود با اعلانهای شما تعامل داشته باشد و به اجازههای «تلفن»، «پیامک»، «مخاطبین»، «میکروفون»، و «دستگاههای اطراف» دسترسی داشته باشد."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"این برنامه مجاز میشود به اجازههای زیر در تلفن شما دسترسی داشته باشد:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"اجازه دادن به <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> برای دسترسی به اطلاعات تلفن"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"سرویسهای بیندستگاهی"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه میخواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> برنامهها را بین دستگاههای شما جاریسازی کند"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"خدمات Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> اجازه میخواهد ازطرف <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> به عکسها، رسانهها، و اعلانهای تلفن شما دسترسی پیدا کند"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"به <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> اجازه داده شود این اقدام را انجام دهد؟"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ازطرف <xliff:g id="DEVICE_NAME">%2$s</xliff:g> اجازه میخواهد تا برنامهها و دیگر ویژگیهای سیستم را در دستگاههای اطراف جاریسازی کند."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"دستگاه"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"این برنامه مجاز میشود اطلاعتی مثل نام شخصی که تماس میگیرد را بین تلفن شما و <xliff:g id="DEVICE_NAME">%1$s</xliff:g> همگامسازی کند."</string>
<string name="summary_generic" msgid="4988130802522924650">"این برنامه مجاز میشود اطلاعتی مثل نام شخصی که تماس میگیرد را بین تلفن شما و دستگاه انتخابشده همگامسازی کند."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"عکسها و رسانهها"</string>
<string name="permission_notification" msgid="693762568127741203">"اعلانها"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"برنامهها"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"جاریسازی"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"میتواند تماس تلفنی برقرار کند و این تماسها را مدیریت کند"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"میتواند گزارش تماسهای تلفنی را بنویسد و بخواند"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"میتواند پیامک ارسال کند و متن پیامک را مشاهده کند"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"میتواند به مخاطبین شما دسترسی داشته باشد"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"میتواند به تقویم شما دسترسی داشته باشد"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"میتواند صدا ضبط کند"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"میتواند دستگاههای اطراف را پیدا کند، به آنها متصل شود، و موقعیت نسبی آنها را تعیین کند"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"میتواند همه اعلانها، ازجمله اطلاعاتی مثل مخاطبین، پیامها، و عکسها را بخواند"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"جاریسازی برنامههای تلفن"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"برنامهها و دیگر ویژگیهای سیستم را از تلفن شما جاریسازی میکند"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fi/strings.xml b/packages/CompanionDeviceManager/res/values-fi/strings.xml
index 2f0e266..990b818 100644
--- a/packages/CompanionDeviceManager/res/values-fi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fi/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Valitse <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, jota <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> hallinnoi"</string>
<string name="summary_watch" msgid="6566922405914995759">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> edellyttää ylläpitoon tätä sovellusta. <xliff:g id="APP_NAME">%2$s</xliff:g> saa luvan synkronoida tietoja (esimerkiksi soittajan nimen), hallinnoida ilmoituksiasi sekä pääsyn puhelimeen, tekstiviesteihin, yhteystietoihin, kalenteriin, puhelulokeihin ja lähellä olevat laitteet ‑lupiin."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> edellyttää ylläpitoon tätä sovellusta. <xliff:g id="APP_NAME">%2$s</xliff:g> saa luvan synkronoida tietoja (esimerkiksi soittajan nimen) ja pääsyn näihin lupiin:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Salli, että <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> saa ylläpitää laitetta: <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"lasit"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> edellyttää ylläpitoon tätä sovellusta. <xliff:g id="APP_NAME">%2$s</xliff:g> saa luvan hallinnoida ilmoituksiasi sekä pääsyn puhelimeen, tekstiviesteihin, yhteystietoihin, mikrofoniin ja lähellä olevat laitteet ‑lupiin."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Tämä sovellus saa käyttää näitä lupia puhelimella:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Salli, että <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> saa pääsyn näihin puhelimesi tietoihin"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Laitteidenväliset palvelut"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa striimata sovelluksia laitteidesi välillä"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Palvelut"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) puolesta lupaa päästä puhelimesi kuviin, mediaan ja ilmoituksiin"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Sallitko, että <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> voi suorittaa tämän toiminnon?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> pyytää laitteesi (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) puolesta lupaa striimata sovelluksia ja muita järjestelmän ominaisuuksia lähellä oleviin laitteisiin."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"laite"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Sovellus voi synkronoida tietoja (esimerkiksi soittajan nimen) puhelimesi ja laitteen (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) välillä."</string>
<string name="summary_generic" msgid="4988130802522924650">"Sovellus voi synkronoida tietoja (esimerkiksi soittajan nimen) puhelimesi ja valitun laitteen välillä."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Kuvat ja media"</string>
<string name="permission_notification" msgid="693762568127741203">"Ilmoitukset"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Sovellukset"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Striimaus"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Voi soittaa ja hallinnoida puheluita"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Voi lukea puhelulokia ja kirjoittaa siihen"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Voi lähettää ja nähdä tekstiviestejä"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Voi nähdä yhteystietosi"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Voi nähdä kalenterisi"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Voi tallentaa audiota"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Voi löytää lähellä olevia laitteita, muodostaa niihin yhteyden ja määrittää niiden suhteellisen sijainnin"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Voi lukea kaikkia ilmoituksia, esim. kontakteihin, viesteihin ja kuviin liittyviä tietoja"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Striimaa puhelimen sovelluksia"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Striimaa sovelluksia ja muita järjestelmän ominaisuuksia puhelimesta"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
index 97aaa76..38f01cd 100644
--- a/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr-rCA/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Choisissez un(e) <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré(e) par <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"L\'application est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation de synchroniser des informations, comme le nom de l\'appelant, d\'interagir avec vos notifications et d\'accéder à vos autorisations pour le téléphone, les messages texte, les contacts, l\'agenda, les journaux d\'appels et les appareils à proximité."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"L\'application est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation de synchroniser des informations, comme le nom de l\'appelant, et d\'accéder à ces autorisations :"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à gérer <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"lunettes"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Cette application est nécessaire pour gérer <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> sera autorisée à interagir avec vos notifications et à accéder à vos autorisations pour le téléphone, les messages texte, les contacts, le microphone et les appareils à proximité."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Cette application pourra accéder aux autorisations suivantes sur votre téléphone :"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autorisez <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations à partir de votre téléphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services multiappareils"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour diffuser des applications entre vos appareils"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, aux fichiers multimédias et aux notifications de votre téléphone"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Autoriser <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> à effectuer cette action?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation, au nom de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g>, de diffuser des applications et d\'autres fonctionnalités du système sur des appareils à proximité"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Cette application pourra synchroniser des informations, comme le nom de l\'appelant, entre votre téléphone et <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Cette application pourra synchroniser des informations, comme le nom de l\'appelant, entre votre téléphone et l\'appareil sélectionné."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos et fichiers multimédias"</string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Applications"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Diffusion en continu"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Peut passer et gérer des appels téléphoniques"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Peut lire et écrire les journaux d\'appels téléphoniques"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Peut envoyer et voir les messages texte"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Peut accéder à vos contacts"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Peut accéder à votre agenda"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Peut enregistrer des données audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Peut trouver et déterminer la position relative des appareils à proximité, et s\'y connecter"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Peut lire toutes les notifications, y compris les renseignements tels que les contacts, les messages et les photos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Diffusez les applications de votre téléphone"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Diffusez des applications et d\'autres fonctionnalités du système à partir de votre téléphone"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-fr/strings.xml b/packages/CompanionDeviceManager/res/values-fr/strings.xml
index 65e4a36..dbae1ab 100644
--- a/packages/CompanionDeviceManager/res/values-fr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-fr/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Sélectionnez le/la <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qui sera géré(e) par <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Cette appli est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation de synchroniser des informations (comme le nom de la personne à l\'origine d\'un appel entrant), d\'interagir avec vos notifications et d\'accéder aux autorisations du téléphone, des SMS, des contacts, de l\'agenda, des journaux d\'appels et des appareils à proximité."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Cette appli est nécessaire pour gérer votre <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation de synchroniser vos informations, comme le nom de la personne à l\'origine d\'un appel entrant, et d\'accéder à ces autorisations :"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à gérer <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"lunettes"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Cette appli est nécessaire pour gérer <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> aura l\'autorisation d\'interagir avec vos notifications et d\'accéder aux autorisations du téléphone, des SMS, des contacts, du micro et des appareils à proximité."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Cette appli sera autorisée à accéder à ces autorisations sur votre téléphone :"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Autoriser <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> à accéder à ces informations depuis votre téléphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Services inter-appareils"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour caster des applis d\'un appareil à l\'autre"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Services Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> pour accéder aux photos, contenus multimédias et notifications de votre téléphone"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Autoriser <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> à effectuer cette action ?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> demande l\'autorisation au nom de votre <xliff:g id="DEVICE_NAME">%2$s</xliff:g> de diffuser des applis et d\'autres fonctionnalités système en streaming sur des appareils à proximité"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"appareil"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Cette appli pourra synchroniser des informations entre votre téléphone et <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, comme le nom de la personne à l\'origine d\'un appel entrant."</string>
<string name="summary_generic" msgid="4988130802522924650">"Cette appli pourra synchroniser des informations entre votre téléphone et l\'appareil choisi, comme le nom de la personne à l\'origine d\'un appel entrant."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Photos et contenus multimédias"</string>
<string name="permission_notification" msgid="693762568127741203">"Notifications"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Applis"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Peut passer des appels téléphoniques et les gérer"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Peut consulter et modifier les journaux d\'appels du téléphone"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Peut envoyer et afficher des SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Peut accéder à vos contacts"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Peut accéder à votre agenda"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Impossible d\'enregistrer l\'audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Peut trouver les appareils à proximité, s\'y connecter et déterminer leur position relative"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Peut lire toutes les notifications, y compris des informations comme les contacts, messages et photos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Diffuser en streaming les applis de votre téléphone"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Diffusez des applis et d\'autres fonctionnalités système en streaming depuis votre téléphone"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-gl/strings.xml b/packages/CompanionDeviceManager/res/values-gl/strings.xml
index 59d6226..4f78073 100644
--- a/packages/CompanionDeviceManager/res/values-gl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gl/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolle un dispositivo (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) para que o xestione a aplicación <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"A aplicación é necesaria para xestionar o teu dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá sincronizar información (por exemplo, o nome de quen chama), interactuar coas túas notificacións e acceder aos permisos do teu teléfono, das SMS, dos contactos, do calendario, dos rexistros de chamadas e dos dispositivos próximos."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"A aplicación é necesaria para xestionar o teu dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá sincronizar información (por exemplo, o nome de quen chama) e acceder a estes permisos:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Queres permitir que <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> xestione o dispositivo (<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>)?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"lentes"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Esta aplicación é necesaria para xestionar o dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>). <xliff:g id="APP_NAME">%2$s</xliff:g> poderá interactuar coas túas notificacións e acceder aos permisos do teu teléfono, das SMS, dos contactos, do micrófono e dos dispositivos próximos."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Esta aplicación poderá acceder aos seguintes permisos do teléfono:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que a aplicación <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acceda a esta información desde o teu teléfono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizos multidispositivo"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para emitir contido de aplicacións entre os teus aparellos"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servizos de Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>) para acceder ás fotos, ao contido multimedia e ás notificacións do teléfono"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Queres permitir que <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> leve a cabo esta acción?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está solicitando permiso en nome do teu dispositivo (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) para emitir o contido das aplicacións e doutras funcións do sistema en dispositivos próximos"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Esta aplicación poderá sincronizar información (por exemplo, o nome de quen chama) entre o teléfono e o dispositivo (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>)."</string>
<string name="summary_generic" msgid="4988130802522924650">"Esta aplicación poderá sincronizar información (por exemplo, o nome de quen chama) entre o teléfono e o dispositivo escollido."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e contido multimedia"</string>
<string name="permission_notification" msgid="693762568127741203">"Notificacións"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplicacións"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Reprodución en tempo real"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Pode facer e xestionar chamadas"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Pode ler e editar o rexistro de chamadas do teléfono"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Pode enviar e ver mensaxes SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Pode acceder aos contactos"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Pode acceder ao calendario"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Pode gravar audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Pode atopar dispositivos próximos, conectarse a eles e determinar a súa posición relativa"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificacións (que poden incluír información como contactos, mensaxes e fotos)"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Emite as aplicacións do teu teléfono"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Emite o contido das aplicacións e doutras funcións do sistema desde o teléfono"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-gu/strings.xml b/packages/CompanionDeviceManager/res/values-gu/strings.xml
index 85be70a..f4f496f 100644
--- a/packages/CompanionDeviceManager/res/values-gu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-gu/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> દ્વારા મેનેજ કરવા માટે કોઈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> પસંદ કરો"</string>
<string name="summary_watch" msgid="6566922405914995759">"તમારા <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ને મેનેજ કરવા માટે ઍપ જરૂરી છે. <xliff:g id="APP_NAME">%2$s</xliff:g>ને કૉલ કરનાર વ્યક્તિનું નામ જેવી માહિતી સિંક કરવાની, તમારા નોટિફિકેશન સાથે ક્રિયાપ્રતિક્રિયા કરવાની અને તમારો ફોન, SMS, સંપર્કો, Calendar, કૉલ લૉગ તથા નજીકના ડિવાઇસની પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી આપવામાં આવશે."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"તમારા <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ને મેનેજ કરવા માટે ઍપ જરૂરી છે. <xliff:g id="APP_NAME">%2$s</xliff:g>ને કૉલ કરનાર વ્યક્તિનું નામ જેવી માહિતી સિંક કરવાની અને આ પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી આપવામાં આવશે:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> મેનેજ કરવા માટે મંજૂરી આપીએ?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"ચશ્માં"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ને મેનેજ કરવા માટે આ ઍપ જરૂરી છે. <xliff:g id="APP_NAME">%2$s</xliff:g>ને તમારા નોટિફિકેશન સાથે ક્રિયાપ્રતિક્રિયા કરવાની અને તમારો ફોન, SMS, સંપર્કો, માઇક્રોફોન તથા નજીકના ડિવાઇસની પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી આપવામાં આવશે."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"આ ઍપને તમારા ફોન પર આ પરવાનગીઓ ઍક્સેસ કરવાની મંજૂરી મળશે:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"તમારા ફોનમાંથી આ માહિતી ઍક્સેસ કરવા માટે, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ને મંજૂરી આપો"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ક્રોસ-ડિવાઇસ સેવાઓ"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ડિવાઇસ વચ્ચે ઍપ સ્ટ્રીમ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play સેવાઓ"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> તમારા <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> વતી તમારા ફોનના ફોટા, મીડિયા અને નોટિફિકેશન ઍક્સેસ કરવાની પરવાનગીની વિનંતી કરી રહી છે"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>ને આ પગલું ભરવાની મંજૂરી આપીએ?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> નજીકના ડિવાઇસ પર ઍપ અને સિસ્ટમની અન્ય સુવિધાઓ સ્ટ્રીમ કરવા તમારા <xliff:g id="DEVICE_NAME">%2$s</xliff:g> વતી પરવાનગીની વિનંતી કરી રહી છે"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ડિવાઇસ"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"આ ઍપ તમારા ફોન અને <xliff:g id="DEVICE_NAME">%1$s</xliff:g> વચ્ચે, કૉલ કરનાર કોઈ વ્યક્તિનું નામ જેવી માહિતી સિંક કરી શકશે."</string>
<string name="summary_generic" msgid="4988130802522924650">"આ ઍપ તમારા ફોન અને પસંદ કરેલા ડિવાઇસ વચ્ચે, કૉલ કરનાર કોઈ વ્યક્તિનું નામ જેવી માહિતી સિંક કરી શકશે."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ફોટા અને મીડિયા"</string>
<string name="permission_notification" msgid="693762568127741203">"નોટિફિકેશન"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ઍપ"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"સ્ટ્રીમિંગ"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ફોન કૉલ કરી શકે છે અને તેને મેનેજ કરી શકે છે"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ફોન કૉલ લૉગ વાંચી અને લખી શકે છે"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS મેસેજ મોકલી શકે છે અને જોઈ શકે છે"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"તમારા સંપર્કો ઍક્સેસ કરી શકે છે"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"તમારા કૅલેન્ડરનો ઍક્સેસ કરી શકે છે"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ઑડિયો રેકોર્ડ કરી શકે છે"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"નજીકના ડિવાઇસ શોધી શકે છે, તેમની સાથે કનેક્ટ કરી શકે છે અને તેમની સંબંધિત સ્થિતિ નિર્ધારિત કરી શકે છે"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"સંપર્કો, મેસેજ અને ફોટા જેવી માહિતી સહિતના બધા નોટિફિકેશન વાંચી શકે છે"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"તમારા ફોનની ઍપ સ્ટ્રીમ કરો"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"તમારા ફોન પરથી ઍપ અને સિસ્ટમની અન્ય સુવિધાઓ સ્ટ્રીમ કરો"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hi/strings.xml b/packages/CompanionDeviceManager/res/values-hi/strings.xml
index a3e8bce..2b1def0 100644
--- a/packages/CompanionDeviceManager/res/values-hi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hi/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"कोई <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चुनें, ताकि उसे <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> की मदद से मैनेज किया जा सके"</string>
<string name="summary_watch" msgid="6566922405914995759">"यह ऐप्लिकेशन, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> को मैनेज करने के लिए ज़रूरी है. <xliff:g id="APP_NAME">%2$s</xliff:g> को डिवाइस की जानकारी सिंक करने की अनुमति होगी. जैसे, कॉल करने वाले व्यक्ति का नाम. इसे आपकी सूचनाओं पर कार्रवाई करने के साथ-साथ आपके फ़ोन, एसएमएस, संपर्कों, कैलेंडर, कॉल लॉग, और आस-पास मौजूद डिवाइसों को ऐक्सेस करने की अनुमति भी होगी."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"यह ऐप्लिकेशन, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> को मैनेज करने के लिए ज़रूरी है. <xliff:g id="APP_NAME">%2$s</xliff:g> को डिवाइस की जानकारी सिंक करने की अनुमति होगी. जैसे, कॉल करने वाले व्यक्ति का नाम. ऐप्लिकेशन इन अनुमतियों का भी इस्तेमाल कर पाएगा:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"क्या <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> मैनेज करने की अनुमति देनी है?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"चश्मा"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"यह ऐप्लिकेशन, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> को मैनेज करने के लिए ज़रूरी है. <xliff:g id="APP_NAME">%2$s</xliff:g> को डिवाइस की सूचनाओं पर कार्रवाई करने की अनुमति होगी. इसे आपके फ़ोन, मैसेज, संपर्कों, माइक्रोफ़ोन, और आस-पास मौजूद डिवाइसों को ऐक्सेस करने की अनुमति भी होगी."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"इस ऐप्लिकेशन को आपके फ़ोन पर ये अनुमतियां ऐक्सेस करने की अनुमति होगी:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> को अपने फ़ोन से यह जानकारी ऐक्सेस करने की अनुमति दें"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिवाइस से जुड़ी सेवाएं"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, आपके डिवाइसों के बीच ऐप्लिकेशन को स्ट्रीम करने की अनुमति मांग रहा है"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> की ओर से, फ़ोन में मौजूद फ़ोटो, मीडिया, और सूचनाओं को ऐक्सेस करने की अनुमति मांग रहा है"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"क्या <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> को यह कार्रवाई करने की अनुमति देनी है?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> आपके <xliff:g id="DEVICE_NAME">%2$s</xliff:g> की ओर से, ऐप्लिकेशन और दूसरे सिस्टम की सुविधाओं को आस-पास मौजूद डिवाइसों पर स्ट्रीम करने की अनुमति मांग रहा है"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"डिवाइस"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"यह ऐप्लिकेशन, आपके फ़ोन और <xliff:g id="DEVICE_NAME">%1$s</xliff:g> के बीच जानकारी सिंक कर सकता है. जैसे, कॉल करने वाले व्यक्ति का नाम."</string>
<string name="summary_generic" msgid="4988130802522924650">"यह ऐप्लिकेशन, आपके फ़ोन और चुने हुए डिवाइस के बीच जानकारी सिंक कर सकता है. जैसे, कॉल करने वाले व्यक्ति का नाम."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"फ़ोटो और मीडिया"</string>
<string name="permission_notification" msgid="693762568127741203">"सूचनाएं"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ऐप्लिकेशन"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"स्ट्रीमिंग"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"फ़ोन कॉल करने और उन्हें मैनेज करने की अनुमति है"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"कॉल लॉग देखने और उसमें बदलाव करने की अनुमति है"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"एसएमएस भेजने और उन्हें देखने की अनुमति है"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"आपकी संपर्क सूची को ऐक्सेस करने की अनुमति है"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"कैलेंडर को ऐक्सेस करने की अनुमति है"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ऑडियो को रिकॉर्ड किया जा सकता है"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"आपको आस-पास मौजूद डिवाइसों को खोजने, उनसे कनेक्ट करने, और उनकी जगह की जानकारी का पता लगाने की अनुमति है"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"इससे सभी सूचनाएं देखी जा सकती हैं. इनमें संपर्क, मैसेज, और फ़ोटो जैसी जानकारी शामिल होती है"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"अपने फ़ोन पर मौजूद ऐप्लिकेशन स्ट्रीम करें"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"अपने फ़ोन से ऐप्लिकेशन और दूसरे सिस्टम की सुविधाओं को स्ट्रीम करें"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hr/strings.xml b/packages/CompanionDeviceManager/res/values-hr/strings.xml
index f1672b9..77c7f94 100644
--- a/packages/CompanionDeviceManager/res/values-hr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hr/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Odaberite <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kojim će upravljati aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Aplikacija je potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će sinkronizirati podatke, primjerice ime pozivatelja, stupati u interakciju s vašim obavijestima i pristupati vašim dopuštenjima za telefon, SMS-ove, kontakte, kalendar, zapisnike poziva i uređaje u blizini."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Aplikacija je potrebna za upravljanje vašim uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će sinkronizirati podatke, primjerice ime pozivatelja i pristupati sljedećim dopuštenjima:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Dopustiti aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da upravlja uređajem <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"naočale"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Ta je aplikacija potrebna za upravljanje uređajem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacija <xliff:g id="APP_NAME">%2$s</xliff:g> moći će stupati u interakciju s vašim obavijestima i pristupati vašim dopuštenjima za telefon, SMS-ove, kontakte, mikrofon i uređaje u blizini."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Aplikacija će moći pristupati ovim dopuštenjima na telefonu:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Omogućite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> da pristupa informacijama s vašeg telefona"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usluge na različitim uređajima"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za emitiranje aplikacija između vaših uređaja"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Usluge za Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> za pristup fotografijama, medijskim sadržajima i obavijestima na telefonu"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Dopustiti <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> da izvede tu radnju?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> zahtijeva dopuštenje u ime vašeg uređaja <xliff:g id="DEVICE_NAME">%2$s</xliff:g> za emitiranje aplikacija i drugih značajki sustava na uređajima u blizini"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"uređaj"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ta će aplikacija moći sinkronizirati podatke između vašeg telefona i uređaja <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, primjerice ime pozivatelja."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ta će aplikacija moći sinkronizirati podatke između vašeg telefona i odabranog uređaja, primjerice ime pozivatelja."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografije i mediji"</string>
<string name="permission_notification" msgid="693762568127741203">"Obavijesti"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikacije"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Može uspostavljati telefonske pozive i upravljati njima"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Može čitati i pisati zapisnik poziva telefona"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Može slati i pregledavati SMS poruke"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Može pristupiti vašim kontaktima"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Može pristupiti vašem kalendaru"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Može snimati zvuk"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Može pronaći i odrediti relativni položaj uređaja u blizini i povezati se s njima"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Može čitati sve obavijesti, uključujući informacije kao što su kontakti, poruke i fotografije"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Streaming aplikacija vašeg telefona"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Emitiranje aplikacija i drugih značajki sustava s vašeg telefona"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hu/strings.xml b/packages/CompanionDeviceManager/res/values-hu/strings.xml
index 74757f9..f1b5520 100644
--- a/packages/CompanionDeviceManager/res/values-hu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hu/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"A(z) <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> alkalmazással kezelni kívánt <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiválasztása"</string>
<string name="summary_watch" msgid="6566922405914995759">"Az alkalmazásra szükség van a következő eszköz kezeléséhez: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A(z) <xliff:g id="APP_NAME">%2$s</xliff:g> képes lesz szinkronizálni információkat (például a hívó fél nevét), műveleteket végezhet majd az értesítésekkel, és hozzáférhet majd a Telefon, az SMS, a Névjegyek, a Naptár, a Hívásnaplók és a Közeli eszközök engedélyekhez."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Az alkalmazásra szükség van a következő eszköz kezeléséhez: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A(z) <xliff:g id="APP_NAME">%2$s</xliff:g> képes lesz szinkronizálni információkat (például a hívó fél nevét), és hozzáférhet majd ezekhez az engedélyekhez:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Engedélyezi, hogy a(z) <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> kezelje a következő eszközt: <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"szemüveg"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Erre az alkalmazásra szükség van a következő eszköz kezeléséhez: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. A(z) <xliff:g id="APP_NAME">%2$s</xliff:g> műveleteket végezhet majd az értesítésekkel, és hozzáférhet majd a Telefon, az SMS, a Névjegyek, a Mikrofon és a Közeli eszközök engedélyekhez."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Az alkalmazás hozzáférhet majd a következő engedélyekhez a telefonon:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Engedélyezi a(z) „<xliff:g id="APP_NAME">%1$s</xliff:g>” alkalmazás számára az információhoz való hozzáférést a telefonról"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Többeszközös szolgáltatások"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében az alkalmazások eszközök közötti streameléséhez"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-szolgáltatások"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nevében a telefonon tárolt fotókhoz, médiatartalmakhoz és értesítésekhez való hozzáféréshez"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Engedélyezi a(z) <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> számára ennek a műveletnek a végrehajtását?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"A(z) <xliff:g id="APP_NAME">%1$s</xliff:g> engedélyt kér a(z) <xliff:g id="DEVICE_NAME">%2$s</xliff:g> nevében az alkalmazások és más rendszerfunkciók közeli eszközökre történő streamelésére"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"eszköz"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ez az alkalmazás képes lesz szinkronizálni az olyan információkat a telefon és a(z) <xliff:g id="DEVICE_NAME">%1$s</xliff:g> eszköz között, mint például a hívó fél neve."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ez az alkalmazás képes lesz szinkronizálni az olyan információkat a telefon és a kiválasztott eszköz között, mint például a hívó fél neve."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotók és médiatartalmak"</string>
<string name="permission_notification" msgid="693762568127741203">"Értesítések"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Alkalmazások"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streamelés"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Hívásokat indíthat és kezelhet"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Olvashatja és írhatja a telefon hívásnaplóját"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS-üzeneteket küldhet és tekinthet meg"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Hozzáférhet a névjegyekhez"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Hozzáférhet a naptárhoz"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Rögzíthet hangot"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Megkeresheti a közeli eszközöket, meghatározhatja viszonylagos helyzetüket és csatlakozhat hozzájuk"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Elolvashat minden értesítést, ideértve az olyan információkat, mint a névjegyek, az üzenetek és a fotók"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"A telefon alkalmazásainak streamelése"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Alkalmazások és más rendszerfunkciók streamelése a telefonról"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-hy/strings.xml b/packages/CompanionDeviceManager/res/values-hy/strings.xml
index cedc6fc..e45ccaf 100644
--- a/packages/CompanionDeviceManager/res/values-hy/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-hy/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Ընտրեք <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ը, որը պետք է կառավարվի <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> հավելվածի կողմից"</string>
<string name="summary_watch" msgid="6566922405914995759">"Հավելվածն անհրաժեշտ է ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքը կառավարելու համար։ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածը կկարողանա համաժամացնել տվյալները, օր․՝ զանգողի անունը, փոխազդել ձեր ծանուցումների հետ և կստանա «Հեռախոս», «SMS», «Կոնտակտներ», «Օրացույց», «Կանչերի ցուցակ» և «Մոտակա սարքեր» թույլտվությունները։"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Հավելվածն անհրաժեշտ է ձեր <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքը կառավարելու համար։ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածը կկարողանա համաժամացնել տվյալները, օր․՝ զանգողի անունը, և կստանա հետևյալ թույլտվությունները․"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Թույլատրե՞լ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին կառավարել <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> սարքը"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"ակնոց"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Այս հավելվածն անհրաժեշտ է <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքը կառավարելու համար։ <xliff:g id="APP_NAME">%2$s</xliff:g> հավելվածը կկարողանա փոխազդել ձեր ծանուցումների հետ և կստանա «Հեռախոս», «SMS», «Կոնտակտներ», «Խոսափող» և «Մոտակա սարքեր» թույլտվությունները։"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Այս հեռախոսին հասանելի կլինեն հետևյալ թույլտվությունները ձեր հեռախոսում․"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Թույլատրեք <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> հավելվածին օգտագործել այս տեղեկությունները ձեր հեռախոսից"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Միջսարքային ծառայություններ"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր սարքերի միջև հավելվածներ հեռարձակելու համար"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ծառայություններ"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ ձեր հեռախոսի լուսանկարները, մեդիաֆայլերն ու ծանուցումները տեսնելու համար"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Թույլատրե՞լ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> հավելվածին կատարել այս գործողությունը"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> հավելվածը ձեր <xliff:g id="DEVICE_NAME">%2$s</xliff:g> սարքի անունից թույլտվություն է խնդրում՝ մոտակա սարքերին հավելվածներ և համակարգի այլ գործառույթներ հեռարձակելու համար"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"սարք"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Այս հավելվածը կկարողանա համաժամացնել ձեր հեռախոսի և <xliff:g id="DEVICE_NAME">%1$s</xliff:g> սարքի տվյալները, օր․՝ զանգողի անունը։"</string>
<string name="summary_generic" msgid="4988130802522924650">"Այս հավելվածը կկարողանա համաժամացնել ձեր հեռախոսի և ընտրված սարքի տվյալները, օր․՝ զանգողի անունը։"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Լուսանկարներ և մուլտիմեդիա"</string>
<string name="permission_notification" msgid="693762568127741203">"Ծանուցումներ"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Հավելվածներ"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Հեռարձակում"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Կարող է կատարել հեռախոսազանգեր և կառավարել դրանք"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Կարող է դիտել և գրանցել կանչերը"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Կարող է ուղարկել SMS հաղորդագրություններ և դիտել դրանք"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Կարող է օգտագործել ձեր կոնտակտները"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Կարող է օգտագործել ձեր օրացույցը"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Կարող է ձայնագրել"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Կարող է գտնել և որոշել մոտակա սարքերի մոտավոր դիրքը և միանալ դրանց"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Կարող է կարդալ բոլոր ծանուցումները, ներառյալ տեղեկությունները, օրինակ՝ կոնտակտները, հաղորդագրությունները և լուսանկարները"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Հեռարձակել հեռախոսի հավելվածները"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Հեռարձակել հավելվածներ և համակարգի այլ գործառույթներ հեռախոսում"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-in/strings.xml b/packages/CompanionDeviceManager/res/values-in/strings.xml
index 5f07125..db2f1ef 100644
--- a/packages/CompanionDeviceManager/res/values-in/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-in/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk dikelola oleh <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Aplikasi diperlukan untuk mengelola <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> akan diizinkan menyinkronkan informasi, seperti nama pemanggil, berinteraksi dengan notifikasi, dan mengakses izin Telepon, SMS, Kontak, Kalender, Log panggilan, dan Perangkat di sekitar."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Aplikasi diperlukan untuk mengelola <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> akan diizinkan menyinkronkan informasi, seperti nama pemanggil, dan mengakses izin berikut:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengelola <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Aplikasi ini diperlukan untuk mengelola <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> akan diizinkan berinteraksi dengan notifikasi dan mengakses izin Ponsel, SMS, Kontak, Mikrofon, dan Perangkat di sekitar."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Aplikasi ini akan diizinkan untuk mengakses izin ini di ponsel Anda:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Izinkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> untuk mengakses informasi ini dari ponsel Anda"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Layanan lintas perangkat"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk menstreaming aplikasi di antara perangkat Anda"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Layanan Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> untuk mengakses foto, media, dan notifikasi ponsel Anda"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Izinkan <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> melakukan tindakan ini?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> meminta izin atas nama <xliff:g id="DEVICE_NAME">%2$s</xliff:g> untuk menstreaming aplikasi dan fitur sistem lainnya ke perangkat di sekitar"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"perangkat"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Aplikasi ini akan dapat menyinkronkan info, seperti nama penelepon, antara ponsel dan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Aplikasi ini akan dapat menyinkronkan info, seperti nama penelepon, antara ponsel dan perangkat yang dipilih."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string>
<string name="permission_notification" msgid="693762568127741203">"Notifikasi"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikasi"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Dapat melakukan dan mengelola panggilan telepon"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Dapat membaca dan menulis log panggilan telepon"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Dapat mengirim dan melihat pesan SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Dapat mengakses kontak Anda"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Dapat mengakses kalender Anda"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Dapat merekam audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Dapat menemukan, menghubungkan, dan menentukan posisi relatif dari perangkat di sekitar"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Dapat membaca semua notifikasi, termasuk informasi seperti kontak, pesan, dan foto"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Streaming aplikasi ponsel"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Menstreaming aplikasi dan fitur sistem lainnya dari ponsel Anda"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-is/strings.xml b/packages/CompanionDeviceManager/res/values-is/strings.xml
index 507abc6..a906cbc 100644
--- a/packages/CompanionDeviceManager/res/values-is/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-is/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Velja <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sem <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> á að stjórna"</string>
<string name="summary_watch" msgid="6566922405914995759">"Forritið er nauðsynlegt til að stjórna <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> fær heimild til að samstilla upplýsingar, t.d. nafn þess sem hringir, og bregðast við tilkynningum og fær aðgang að heimildum fyrir síma, SMS, tengiliði, dagatal, símtalaskrár og nálæg tæki."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Forritið er nauðsynlegt til að stjórna <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> fær heimild til að samstilla upplýsingar, t.d. nafn þess sem hringir, og fær aðgang að eftirfarandi heimildum:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Leyfa <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> að stjórna <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"gleraugu"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Þetta forrit er nauðsynlegt til að stjórna <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> fær heimild til að bregðast við tilkynningum og fær aðgang að heimildum fyrir síma, SMS, tengiliði, hljóðnema og nálæg tæki."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Þetta forrit fær aðgang að eftirfarandi heimildum í símanum þínum:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Veita <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> aðgang að þessum upplýsingum úr símanum þínum"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Þjónustur á milli tækja"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um heimild til straumspilunar forrita á milli tækjanna þinna fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Þjónusta Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> sendir beiðni um aðgang að myndum, margmiðlunarefni og tilkynningum símans þíns fyrir hönd <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Leyfa <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> að framkvæma þessa aðgerð?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> biður um heimild fyrir <xliff:g id="DEVICE_NAME">%2$s</xliff:g> til að streyma forritum og öðrum kerfiseiginleikum í nálægum tækjum"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"tæki"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Þetta forrit mun geta samstillt upplýsingar, t.d. nafn þess sem hringir, á milli símans og <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Þetta forrit mun geta samstillt upplýsingar, t.d. nafn þess sem hringir, á milli símans og valins tækis."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Myndir og efni"</string>
<string name="permission_notification" msgid="693762568127741203">"Tilkynningar"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Forrit"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streymi"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Getur hringt og stjórnað símtölum"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Getur lesið og skrifað símtalaskrá símans"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Getur sent og skoðað SMS-skilaboð"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Hefur aðgang að tengiliðum"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Hefur aðgang að dagatalinu"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Getur tekið upp hljóð"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Getur fundið, tengst og áætlað staðsetningu nálægra tækja"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Getur lesið allar tilkynningar, þar á meðal upplýsingar á borð við tengiliði, skilaboð og myndir"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Streymdu forritum símans"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Streymdu forritum og öðrum kerfiseiginleikum úr símanum"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-it/strings.xml b/packages/CompanionDeviceManager/res/values-it/strings.xml
index 4612893..7c90775 100644
--- a/packages/CompanionDeviceManager/res/values-it/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-it/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Scegli un <xliff:g id="PROFILE_NAME">%1$s</xliff:g> da gestire con <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà sincronizzare informazioni, ad esempio il nome di un chiamante, interagire con le tue notifiche e accedere alle autorizzazioni Telefono, SMS, Contatti, Calendario, Registri chiamate e Dispositivi nelle vicinanze."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà sincronizzare informazioni, ad esempio il nome di un chiamante, e accedere alle seguenti autorizzazioni:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vuoi consentire all\'app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di gestire <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"occhiali"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Questa app è necessaria per gestire <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> potrà interagire con le tue notifiche e accedere alle autorizzazioni Telefono, SMS, Contatti, Microfono e Dispositivi nelle vicinanze."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"L\'app potrà accedere alle seguenti autorizzazioni sul telefono:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Consenti a <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> di accedere a queste informazioni dal tuo telefono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servizi cross-device"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione a trasmettere app in streaming tra i dispositivi"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto del tuo <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> l\'autorizzazione ad accedere a foto, contenuti multimediali e notifiche del telefono"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vuoi consentire a <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> di compiere questa azione?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> richiede per conto di <xliff:g id="DEVICE_NAME">%2$s</xliff:g> l\'autorizzazione a trasmettere in streaming app e altre funzionalità di sistema ai dispositivi nelle vicinanze"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Questa app potrà sincronizzare informazioni, ad esempio il nome di un chiamante, tra il telefono e <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Questa app potrà sincronizzare informazioni, ad esempio il nome di un chiamante, tra il telefono e il dispositivo scelto."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto e contenuti multimediali"</string>
<string name="permission_notification" msgid="693762568127741203">"Notifiche"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"App"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Consente di effettuare e gestire telefonate"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Consente di leggere e modificare il registro chiamate del telefono"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Consente di inviare e visualizzare SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Consente di accedere ai tuoi contatti"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Consente di accedere al tuo calendario"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Consente di registrare audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Consente di trovare e connettersi a dispositivi nelle vicinanze, nonché di stabilirne la posizione relativa"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Puoi leggere tutte le notifiche, incluse le informazioni come contatti, messaggi e foto"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Trasmetti in streaming le app del tuo telefono"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Consente di trasmettere in streaming app e altre funzionalità di sistema dal telefono"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-iw/strings.xml b/packages/CompanionDeviceManager/res/values-iw/strings.xml
index f080652..28a8877 100644
--- a/packages/CompanionDeviceManager/res/values-iw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-iw/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"בחירת <xliff:g id="PROFILE_NAME">%1$s</xliff:g> לניהול באמצעות <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. האפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g> תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, לבצע פעולות בהתראות ולקבל הרשאות גישה לטלפון, ל-SMS לאנשי הקשר, למיקרופון ולמכשירים בקרבת מקום."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. האפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g> תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, ולקיים אינטראקציה עם ההרשאות הבאות:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"מתן הרשאה לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong&g; לנהל את <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"משקפיים"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"האפליקציה הזו נחוצה כדי לנהל את <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. האפליקציה <xliff:g id="APP_NAME">%2$s</xliff:g> תוכל לבצע פעולות בהתראות ותקבל הרשאות גישה לטלפון, ל-SMS לאנשי הקשר, למיקרופון ולמכשירים בקרבת מקום."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"האפליקציה הזו תוכל לגשת להרשאות הבאות בטלפון שלך:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"מתן אישור לאפליקציה <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> לגשת למידע הזה מהטלפון שלך"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"שירותים למספר מכשירים"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לשדר אפליקציות בין המכשירים שלך"</string>
@@ -38,17 +35,15 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור מכשיר <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> כדי לגשת לתמונות, למדיה ולהתראות בטלפון שלך"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"לתת הרשאה למכשיר <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> לבצע את הפעולה הזו?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"האפליקציה <xliff:g id="APP_NAME">%1$s</xliff:g> מבקשת הרשאה עבור <xliff:g id="DEVICE_NAME">%2$s</xliff:g> כדי להעביר אפליקציות ותכונות מערכת אחרות בסטרימינג למכשירים בקרבת מקום"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"מכשיר"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, מהטלפון שלך ל-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"האפליקציה הזו תוכל לסנכרן מידע, כמו השם של מישהו שמתקשר, מהטלפון שלך למכשיר שבחרת."</string>
<string name="consent_yes" msgid="8344487259618762872">"יש אישור"</string>
<string name="consent_no" msgid="2640796915611404382">"אין אישור"</string>
<string name="consent_back" msgid="2560683030046918882">"חזרה"</string>
- <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"האם לתת לאפליקציות ב-<strong><xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g></strong>את אותן הרשאות כמו ב-<strong><xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
+ <string name="permission_sync_confirmation_title" msgid="4409622174437248702">"האם לתת לאפליקציות ב-<strong><xliff:g id="COMPANION_DEVICE_NAME">%1$s</xliff:g></strong> את אותן הרשאות כמו ב-<strong><xliff:g id="PRIMARY_DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="permission_sync_summary" msgid="765497944331294275">"ההרשאות עשויות לכלול גישה ל<strong>מיקרופון</strong>, ל<strong>מצלמה</strong>, ול<strong>מיקום</strong>, וכן גישה למידע רגיש אחר ב-<strong><xliff:g id="COMPANION_DEVICE_NAME_0">%1$s</xliff:g></strong>. <br/><br/>אפשר לשנות את ההרשאות האלה בכל שלב בהגדרות של <strong><xliff:g id="COMPANION_DEVICE_NAME_1">%1$s</xliff:g></strong>."</string>
<string name="vendor_icon_description" msgid="4445875290032225965">"סמל האפליקציה"</string>
<string name="vendor_header_button_description" msgid="6566660389500630608">"לחצן מידע נוסף"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"תמונות ומדיה"</string>
<string name="permission_notification" msgid="693762568127741203">"התראות"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"אפליקציות"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"סטרימינג"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"אפשרות לבצע ולנהל שיחות טלפון"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"אפשרות ולקרוא ולכתוב נתונים ביומן השיחות של הטלפון"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"אפשרות לשלוח הודעות SMS ולצפות בהן"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"גישה לאנשי הקשר"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"אפשרות לגשת ליומן"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"המיקרופון יכול להקליט אודיו"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"אפשרות למצוא מכשירים בקרבת מקום, להתחבר אליהם ולהעריך את המיקום היחסי שלהם"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"גישת קריאה לכל ההתראות, כולל מידע כמו אנשי קשר, הודעות ותמונות."</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"שידור אפליקציות מהטלפון"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"העברה של אפליקציות ותכונות מערכת אחרות בסטרימינג מהטלפון"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ja/strings.xml b/packages/CompanionDeviceManager/res/values-ja/strings.xml
index 6275e59..964b63f 100644
--- a/packages/CompanionDeviceManager/res/values-ja/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ja/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> の管理対象となる<xliff:g id="PROFILE_NAME">%1$s</xliff:g>の選択"</string>
<string name="summary_watch" msgid="6566922405914995759">"このアプリは <xliff:g id="DEVICE_NAME">%1$s</xliff:g> の管理に必要です。<xliff:g id="APP_NAME">%2$s</xliff:g> は通話相手の名前などの情報を同期したり、デバイスの通知を使用したり、電話、SMS、連絡先、カレンダー、通話履歴、付近のデバイスの権限にアクセスしたりできるようになります。"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"このアプリは <xliff:g id="DEVICE_NAME">%1$s</xliff:g> の管理に必要です。<xliff:g id="APP_NAME">%2$s</xliff:g> は通話相手の名前などの情報を同期したり、次の権限にアクセスしたりできるようになります。"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> の管理を許可しますか?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"眼鏡"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"このアプリは <xliff:g id="DEVICE_NAME">%1$s</xliff:g> の管理に必要です。<xliff:g id="APP_NAME">%2$s</xliff:g> はデバイスの通知を使用したり、電話、SMS、連絡先、マイク、付近のデバイスの権限にアクセスしたりできるようになります。"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"このアプリは、スマートフォンの以下の権限へのアクセスが可能になります:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"スマートフォンのこの情報へのアクセスを <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> に許可"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"クロスデバイス サービス"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってデバイス間でアプリをストリーミングする権限をリクエストしています"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 開発者サービス"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> に代わってスマートフォンの写真、メディア、通知にアクセスする権限をリクエストしています"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> にこの操作の実行を許可しますか?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> が <xliff:g id="DEVICE_NAME">%2$s</xliff:g> に代わって、アプリやその他のシステム機能を付近のデバイスにストリーミングする権限をリクエストしています"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"デバイス"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"このアプリは、あなたのスマートフォンと <xliff:g id="DEVICE_NAME">%1$s</xliff:g> との間で、通話相手の名前などの情報を同期できるようになります。"</string>
<string name="summary_generic" msgid="4988130802522924650">"このアプリは、あなたのスマートフォンと選択したデバイスとの間で、通話相手の名前などの情報を同期できるようになります。"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"写真とメディア"</string>
<string name="permission_notification" msgid="693762568127741203">"通知"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"アプリ"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"ストリーミング"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"電話の発信と管理を行えます"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"通話履歴の読み取りと書き込みを行えます"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS メッセージの送信、表示を行えます"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"連絡先にアクセスできます"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"カレンダーにアクセスできます"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"録音できる"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"付近のデバイスの検出、接続、相対位置の特定を行えます"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"連絡先、メッセージ、写真に関する情報を含め、すべての通知を読み取ることができます"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"スマートフォンのアプリをストリーミングします"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"アプリやその他のシステム機能をスマートフォンからストリーミングする"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ka/strings.xml b/packages/CompanionDeviceManager/res/values-ka/strings.xml
index 0e0d08d..930ef90 100644
--- a/packages/CompanionDeviceManager/res/values-ka/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ka/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"აირჩიეთ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, რომელიც უნდა მართოს <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>-მა"</string>
<string name="summary_watch" msgid="6566922405914995759">"ეს აპი საჭიროა თქვენი <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ის სამართავად. <xliff:g id="APP_NAME">%2$s</xliff:g>-ს ექნება უფლება, მოახდინოს ისეთი ინფორმაციის სინქრონიზაცია, როგორიც იმ ადამიანის სახელია, რომელიც რეკავს, მოახდინოს ინტერაქცია თქვენს შეტყობინებებთან და ჰქონდეს წვდომა თქვენს ტელეფონზე, SMS-ებზე, კონტაქტებზე, კალენდარზე, ზარების ჟურნალებზე და ახლომახლო მოწყობილობების ნებართვებზე."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"ეს აპი საჭიროა თქვენი <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ის სამართავად. <xliff:g id="APP_NAME">%2$s</xliff:g>-ს ექნება უფლება, მოახდინოს ისეთი ინფორმციის სინქრონიზაცია, როგორიც იმ ადამიანის სახელია, რომელიც რეკავს, და ჰქონდეს წვდომა შემდეგ ნებართვებზე:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"ნება დართეთ <strong><xliff:g id="APP_NAME">%1$s</xliff:g>-ს</strong> მართოს <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"სათვალე"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"ეს აპი საჭიროა თქვენი <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ის სამართავად. <xliff:g id="APP_NAME">%2$s</xliff:g> შეძლებს თქვენს შეტყობინებებთან ინტერაქციას და თქვენს ტელეფონზე, SMS-ებზე, კონტაქტებზე, მიკროფონსა და ახლომახლო მოწყობილობების ნებართვებზე წვდომას."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"ამ აპისთვის ნებადართული იქნება მოცემულ ნებართვებზე წვდომა თქვენს ტელეფონში:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ნება დართეთ, რომ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> აპს ჰქონდეს ამ ინფორმაციაზე წვდომა თქვენი ტელეფონიდან"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"მოწყობილობათშორისი სერვისები"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ მოწყობილობებს შორის აპების სტრიმინგი შეძლოს"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს უფლებას თქვენი <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-ის სახელით, რომ წვდომა ჰქონდეს თქვენი ტელეფონის ფოტოებზე, მედიასა და შეტყობინებებზე"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"გსურთ ნება მისცეთ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ს</strong> ამ მოქმედების შესასრულებლად?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ითხოვს თქვენი <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-ის სახელით აპების და სისტემის სხვა ფუნქციების ახლომახლო მოწყობილობებზე სტრიმინგის ნებართვას"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"მოწყობილობა"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"ეს აპი შეძლებს, მოახდინოს ისეთი ინფორმაციის სინქრონიზაცია, როგორიც იმ ადამიანის სახელია, რომელიც რეკავს, თქვენს ტელეფონსა და <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-ს შორის."</string>
<string name="summary_generic" msgid="4988130802522924650">"ეს აპი შეძლებს, მოახდინოს ისეთი ინფორმაციის სინქრონიზაცია, როგორიც იმ ადამიანის სახელია, რომელიც რეკავს, თქვენს ტელეფონსა და არჩეულ მოწყობილობას შორის."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ფოტოები და მედია"</string>
<string name="permission_notification" msgid="693762568127741203">"შეტყობინებები"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"აპები"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"სტრიმინგი"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"შეძლოს სატელეფონო ზარების განხორციელება და მართვა"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"შეეძლოს ზარების ჟურნალის წაკითხვა და მასში ჩაწერა"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"შეძლოს SMS ტექსტური შეტყობინებების გაგზავნა და მიღება"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"ჰქონდეს თქვენს კონტაქტებზე წვდომის საშუალება"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"ჰქონდეს თქვენს კალენდარზე წვდომის საშუალება"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"შეიძლებოდეს აუდიოს ჩაწერა"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"შეძლოს ახლომახლო მოწყობილობების აღმოჩენა, მათთან დაკავშირება და მათი შედარებითი პოზიციის დადგენა"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"შეუძლია წაიკითხოს ყველა შეტყობინება, მათ შორის ისეთი ინფორმაცია, როგორიცაა კონტაქტები, ტექსტური შეტყობინებები და ფოტოები"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"თქვენი ტელეფონის აპების სტრიმინგი"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"აწარმოეთ აპების და სისტემის სხვა ფუნქციების სტრიმინგი თქვენი ტელეფონიდან"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-kk/strings.xml b/packages/CompanionDeviceManager/res/values-kk/strings.xml
index e857852..21b9ff8 100644
--- a/packages/CompanionDeviceManager/res/values-kk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kk/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> арқылы басқарылатын <xliff:g id="PROFILE_NAME">%1$s</xliff:g> құрылғысын таңдаңыз"</string>
<string name="summary_watch" msgid="6566922405914995759">"Қолданба <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысын басқару үшін қажет. <xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасына қоңырау шалушының аты сияқты деректі синхрондау, хабарландыруларды оқу, телефон, SMS, контактілер, күнтізбе, қоңырау журналдары қолданбаларын және маңайдағы құрылғыларды пайдалану рұқсаттары беріледі."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Қолданба <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысын басқару үшін қажет. <xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасына деректі (мысалы, қоңырау шалушының аты) синхрондауға және мына рұқсаттарды пайдалануға рұқсат беріледі:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> құрылғысын басқаруға рұқсат беру керек пе?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"көзілдірік"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Бұл қолданба <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысын басқару үшін қажет. <xliff:g id="APP_NAME">%2$s</xliff:g> қолданбасына хабарландыруларды оқуға, телефонды, хабарларды, контактілерді, микрофон мен маңайдағы құрылғыларды пайдалануға рұқсат беріледі."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Бұл қолданба телефоныңыздағы мына рұқсаттарды пайдалана алады:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> қолданбасына телефоныңыздағы осы ақпаратты пайдалануға рұқсат беріңіз."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Аралық құрылғы қызметтері"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан құрылғылар арасында қолданбалар трансляциялау үшін рұқсат сұрайды."</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play қызметтері"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> атынан телефондағы фотосуреттерді, медиафайлдар мен хабарландыруларды пайдалану үшін рұқсат сұрайды."</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> құрылғысына бұл әрекетті орындауға рұқсат беру керек пе?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> қолданбасы <xliff:g id="DEVICE_NAME">%2$s</xliff:g> атынан қолданбалар мен басқа да жүйе функцияларын маңайдағы құрылғыларға трансляциялау рұқсатын сұрап тұр."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"құрылғы"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Бұл қолданба телефон мен <xliff:g id="DEVICE_NAME">%1$s</xliff:g> құрылғысы арасында деректі (мысалы, қоңырау шалушының атын) синхрондайды."</string>
<string name="summary_generic" msgid="4988130802522924650">"Бұл қолданба телефон мен таңдалған құрылғы арасында деректі (мысалы, қоңырау шалушының атын) синхрондайды."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Фотосуреттер мен медиафайлдар"</string>
<string name="permission_notification" msgid="693762568127741203">"Хабарландырулар"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Қолданбалар"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Трансляция"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Қоңырау шалып, оларды басқара алады."</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Телефонның қоңыраулар журналын оқып, жаза алады."</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS хабарларды көріп, жібере алады."</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Контактілеріңізді пайдалана алады."</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Күнтізбеңізді пайдалана алады."</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Аудио жаза алады."</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Маңайдағы құрылғыларды тауып, олармен байланысып, бір-біріне қатысты локациясын анықтайды."</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Барлық хабарландыруды, соның ішінде контактілер, хабарлар және фотосуреттер сияқты ақпаратты оқи алады."</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Телефон қолданбаларын трансляциялайды."</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Қолданбалар мен басқа да жүйе функцияларын телефоннан трансляциялау"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-km/strings.xml b/packages/CompanionDeviceManager/res/values-km/strings.xml
index c4901d7..5048616 100644
--- a/packages/CompanionDeviceManager/res/values-km/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-km/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"ជ្រើសរើស <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ដើម្បីឱ្យស្ថិតក្រោមការគ្រប់គ្រងរបស់ <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"ត្រូវការកម្មវិធីនេះ ដើម្បីគ្រប់គ្រង <xliff:g id="DEVICE_NAME">%1$s</xliff:g> របស់អ្នក។ <xliff:g id="APP_NAME">%2$s</xliff:g> នឹងត្រូវបានអនុញ្ញាតឱ្យធ្វើសមកាលកម្មព័ត៌មានដូចជា ឈ្មោះមនុស្សដែលហៅទូរសព្ទ ធ្វើអន្តរកម្មជាមួយការជូនដំណឹងរបស់អ្នក និងចូលប្រើការអនុញ្ញាតទូរសព្ទ, SMS, ទំនាក់ទំនង, ប្រតិទិន, កំណត់ហេតុហៅទូរសព្ទ និងឧបករណ៍នៅជិតរបស់អ្នក។"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"ត្រូវការកម្មវិធីនេះ ដើម្បីគ្រប់គ្រង <xliff:g id="DEVICE_NAME">%1$s</xliff:g> របស់អ្នក។ <xliff:g id="APP_NAME">%2$s</xliff:g> នឹងត្រូវបានអនុញ្ញាតឱ្យធ្វើសមកាលកម្មព័ត៌មានដូចជា ឈ្មោះមនុស្សដែលហៅទូរសព្ទ និងចូលប្រើការអនុញ្ញាតទាំងនេះ៖"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> គ្រប់គ្រង <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ឬ?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"វ៉ែនតា"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"ត្រូវការកម្មវិធីនេះ ដើម្បីគ្រប់គ្រង <xliff:g id="DEVICE_NAME">%1$s</xliff:g>។ <xliff:g id="APP_NAME">%2$s</xliff:g> នឹងត្រូវបានអនុញ្ញាតឱ្យធ្វើអន្តរកម្មជាមួយការជូនដំណឹងរបស់អ្នក និងចូលប្រើការអនុញ្ញាតរបស់ទូរសព្ទ, SMS, ទំនាក់ទំនង, មីក្រូហ្វូន និងឧបករណ៍នៅជិតរបស់អ្នក។"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"កម្មវិធីនេះនឹងត្រូវបានអនុញ្ញាតឱ្យចូលប្រើការកំណត់ទាំងនេះនៅលើទូរសព្ទរបស់អ្នក៖"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"អនុញ្ញាតឱ្យ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ចូលប្រើព័ត៌មាននេះពីទូរសព្ទរបស់អ្នក"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"សេវាកម្មឆ្លងកាត់ឧបករណ៍"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីបញ្ចាំងកម្មវិធីរវាងឧបករណ៍របស់អ្នក"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"សេវាកម្ម Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> របស់អ្នក ដើម្បីចូលប្រើរូបថត មេឌៀ និងការជូនដំណឹងរបស់ទូរសព្ទអ្នក"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"អនុញ្ញាតឱ្យ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ធ្វើសកម្មភាពនេះឬ?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> កំពុងស្នើសុំការអនុញ្ញាតជំនួសឱ្យ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> របស់អ្នក ដើម្បីចាក់ផ្សាយកម្មវិធី និងមុខងារប្រព័ន្ធផ្សេងទៀតទៅកាន់ឧបករណ៍នៅជិត"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ឧបករណ៍"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"កម្មវិធីនឹងអាចធ្វើសមកាលកម្មព័ត៌មានដូចជា ឈ្មោះមនុស្សដែលហៅទូរសព្ទរវាងទូរសព្ទ និង <xliff:g id="DEVICE_NAME">%1$s</xliff:g> របស់អ្នក។"</string>
<string name="summary_generic" msgid="4988130802522924650">"កម្មវិធីនេះនឹងអាចធ្វើសមកាលកម្មព័ត៌មានដូចជា ឈ្មោះមនុស្សដែលហៅទូរសព្ទរវាងឧបករណ៍ដែលបានជ្រើសរើស និងទូរសព្ទរបស់អ្នក។"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"រូបថត និងមេឌៀ"</string>
<string name="permission_notification" msgid="693762568127741203">"ការជូនដំណឹង"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"កម្មវិធី"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"ការផ្សាយ"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"អាចហៅទូរសព្ទ និងគ្រប់គ្រងការហៅទូរសព្ទ"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"អាចអាន និងសរសេរកំណត់ហេតុហៅទូរសព្ទ"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"អាចផ្ញើ និងមើលសារ SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"អាចចូលប្រើទំនាក់ទំនងរបស់អ្នក"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"អាចចូលប្រើប្រតិទិនរបស់អ្នក"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"អាចថតសំឡេង"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"អាចស្វែងរក ភ្ជាប់ទៅ និងកំណត់ចម្ងាយពាក់ព័ន្ធរវាងឧបករណ៍ដែលនៅជិត"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"អាចអានការជូនដំណឹងទាំងអស់ រួមទាំងព័ត៌មានដូចជាទំនាក់ទំនង សារ និងរូបថត"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"ផ្សាយកម្មវិធីរបស់ទូរសព្ទអ្នក"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"ចាក់ផ្សាយកម្មវិធី និងមុខងារប្រព័ន្ធផ្សេងទៀតពីទូរសព្ទរបស់អ្នក"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-kn/strings.xml b/packages/CompanionDeviceManager/res/values-kn/strings.xml
index 6f93275..e7f9f7d 100644
--- a/packages/CompanionDeviceManager/res/values-kn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-kn/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ಮೂಲಕ ನಿರ್ವಹಿಸಬೇಕಾದ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ಅನ್ನು ಆಯ್ಕೆಮಾಡಿ"</string>
<string name="summary_watch" msgid="6566922405914995759">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಆ್ಯಪ್ನ ಅಗತ್ಯವಿದೆ. ಕರೆ ಮಾಡುವವರ ಹೆಸರು, ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಲು ಮತ್ತು ಫೋನ್, SMS, ಸಂಪರ್ಕಗಳು, ಕ್ಯಾಲೆಂಡರ್, ಕರೆ ಲಾಗ್ಗಳು ಮತ್ತು ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳ ದೃಢೀಕರಣಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಆ್ಯಪ್ನ ಅಗತ್ಯವಿದೆ. ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಮತ್ತು ಈ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <xliff:g id="APP_NAME">%2$s</xliff:g> ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>? ನಿರ್ವಹಿಸಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಬೇಕೇ?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"ಗ್ಲಾಸ್ಗಳು"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಅನ್ನು ನಿರ್ವಹಿಸಲು ಈ ಆ್ಯಪ್ನ ಅಗತ್ಯವಿದೆ. <xliff:g id="APP_NAME">%2$s</xliff:g> ನಿಮ್ಮ ಅಧಿಸೂಚನೆಗಳೊಂದಿಗೆ ಸಂವಹನ ನಡೆಸಲು ಮತ್ತು ನಿಮ್ಮ ಫೋನ್, SMS, ಸಂಪರ್ಕಗಳು, ಮೈಕ್ರೊಫೋನ್ ಮತ್ತು ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಅನುಮತಿಸಲಾಗುತ್ತದೆ."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"ನಿಮ್ಮ ಫೋನ್ನಲ್ಲಿ ಈ ಅನುಮತಿಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು ಈ ಆ್ಯಪ್ಗೆ ಅನುಮತಿಸಲಾಗುತ್ತದೆ:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ನಿಮ್ಮ ಫೋನ್ ಮೂಲಕ ಈ ಮಾಹಿತಿಯನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಲು <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ಗೆ ಅನುಮತಿಸಿ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ಕ್ರಾಸ್-ಡಿವೈಸ್ ಸೇವೆಗಳು"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"ನಿಮ್ಮ ಸಾಧನಗಳ ನಡುವೆ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ಸೇವೆಗಳು"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"ನಿಮ್ಮ ಫೋನ್ನ ಫೋಟೋಗಳು, ಮೀಡಿಯಾ ಮತ್ತು ಅಧಿಸೂಚನೆಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ನಿಮ್ಮ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ನ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸಿಕೊಳ್ಳುತ್ತಿದೆ"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"ಈ ಆ್ಯಕ್ಷನ್ ಅನ್ನು ತೆಗೆದುಕೊಳ್ಳಲು <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ಅನುಮತಿಸಬೇಕೇ?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳಿಗೆ ಆ್ಯಪ್ಗಳು ಮತ್ತು ಇತರ ಸಿಸ್ಟಂ ಫೀಚರ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ನಿಮ್ಮ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ರ ಪರವಾಗಿ <xliff:g id="APP_NAME">%1$s</xliff:g> ಅನುಮತಿಯನ್ನು ವಿನಂತಿಸುತ್ತಿದೆ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ಸಾಧನ"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"ಈ ಆ್ಯಪ್, ಮೊಬೈಲ್ ಫೋನ್ ಮತ್ತು <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಸಾಧನದ ನಡುವೆ ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string>
<string name="summary_generic" msgid="4988130802522924650">"ಈ ಆ್ಯಪ್, ಮೊಬೈಲ್ ಫೋನ್ ಮತ್ತು ಆಯ್ಕೆಮಾಡಿದ ಸಾಧನದ ನಡುವೆ ಕರೆ ಮಾಡುವವರ ಹೆಸರಿನಂತಹ ಮಾಹಿತಿಯನ್ನು ಸಿಂಕ್ ಮಾಡಲು ಸಾಧ್ಯವಾಗುತ್ತದೆ."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ಫೋಟೋಗಳು ಮತ್ತು ಮಾಧ್ಯಮ"</string>
<string name="permission_notification" msgid="693762568127741203">"ಅಧಿಸೂಚನೆಗಳು"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ಆ್ಯಪ್ಗಳು"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"ಸ್ಟ್ರೀಮಿಂಗ್"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ಫೋನ್ ಕರೆಗಳನ್ನು ಮಾಡಬಹುದು ಮತ್ತು ನಿರ್ವಹಿಸಬಹುದು"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ಪೋನ್ ಕರೆಯ ಲಾಗ್ ಅನ್ನು ಓದಬಹುದು ಮತ್ತು ಬರೆಯಬಹುದು"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಬಹುದು ಮತ್ತು ವೀಕ್ಷಿಸಬಹುದು"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"ನಿಮ್ಮ ಸಂಪರ್ಕಗಳನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಬಹುದು"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"ನಿಮ್ಮ ಕ್ಯಾಲೆಂಡರ್ ಅನ್ನು ಆ್ಯಕ್ಸೆಸ್ ಮಾಡಬಹುದು"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ಆಡಿಯೋ ರೆಕಾರ್ಡ್ ಮಾಡಬಹುದು"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"ಸಮೀಪದಲ್ಲಿರುವ ಸಾಧನಗಳನ್ನು ಹುಡುಕಬಹುದು, ಅವುಗಳಿಗೆ ಕನೆಕ್ಟ್ ಆಗಬಹುದು ಮತ್ತು ಅವುಗಳ ಸಂಬಂಧಿತ ಸ್ಥಾನವನ್ನು ನಿರ್ಧರಿಸಬಹುದು"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"ಸಂಪರ್ಕಗಳು, ಸಂದೇಶಗಳು ಮತ್ತು ಫೋಟೋಗಳಂತಹ ಮಾಹಿತಿಯನ್ನು ಒಳಗೊಂಡಂತೆ ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ಓದಬಹುದು"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"ನಿಮ್ಮ ಫೋನ್ನ ಆ್ಯಪ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಿ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"ನಿಮ್ಮ ಫೋನ್ನಿಂದ ಆ್ಯಪ್ಗಳು ಮತ್ತು ಇತರ ಸಿಸ್ಟಂ ಫೀಚರ್ಗಳನ್ನು ಸ್ಟ್ರೀಮ್ ಮಾಡಿ"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ko/strings.xml b/packages/CompanionDeviceManager/res/values-ko/strings.xml
index 38b3df1..67ca4a0 100644
--- a/packages/CompanionDeviceManager/res/values-ko/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ko/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>에서 관리할 <xliff:g id="PROFILE_NAME">%1$s</xliff:g>을(를) 선택"</string>
<string name="summary_watch" msgid="6566922405914995759">"이 앱은 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 기기를 관리하는 데 필요합니다. <xliff:g id="APP_NAME">%2$s</xliff:g>에서 전화를 건 사람 이름과 같은 정보를 동기화하며 알림과 상호작용하고 내 전화, SMS, 연락처, Calendar, 통화 기록, 근처 기기에 액세스할 수 있게 됩니다."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"이 앱은 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 기기를 관리하는 데 필요합니다. <xliff:g id="APP_NAME">%2$s</xliff:g>에서 전화를 건 사람 이름과 같은 정보를 동기화하며 이러한 권한에 액세스할 수 있게 됩니다."</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>에서 <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>? 기기를 관리하도록 허용"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"안경"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"이 앱은 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 기기를 관리하는 데 필요합니다. <xliff:g id="APP_NAME">%2$s</xliff:g>에서 알림과 상호작용하고 내 전화, SMS, 연락처, 마이크, 근처 기기에 대한 권한을 갖게 됩니다."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"앱이 내 휴대전화에서 이러한 권한에 액세스할 수 있게 됩니다."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>이 휴대전화의 이 정보에 액세스하도록 허용합니다."</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"교차 기기 서비스"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 기기 간에 앱을 스트리밍할 수 있는 권한을 요청하고 있습니다."</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 서비스"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 대신 휴대전화의 사진, 미디어, 알림에 액세스할 수 있는 권한을 요청하고 있습니다."</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> 기기가 이 작업을 수행하도록 허용하시겠습니까?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g>에서 <xliff:g id="DEVICE_NAME">%2$s</xliff:g> 대신 근처 기기로 앱 및 기타 시스템 기능을 스트리밍할 권한을 요청하고 있습니다."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"기기"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"이 앱이 전화를 건 사람 이름과 같은 정보를 휴대전화와 <xliff:g id="DEVICE_NAME">%1$s</xliff:g> 간에 동기화할 수 있습니다."</string>
<string name="summary_generic" msgid="4988130802522924650">"이 앱이 전화를 건 사람 이름과 같은 정보를 휴대전화와 선택한 기기 간에 동기화할 수 있습니다."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"사진 및 미디어"</string>
<string name="permission_notification" msgid="693762568127741203">"알림"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"앱"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"스트리밍"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"전화를 걸고 통화를 관리할 수 있습니다."</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"통화 기록을 읽고 쓸 수 있습니다."</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS 메시지를 전송하고 볼 수 있습니다."</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"연락처에 액세스할 수 있습니다."</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"캘린더에 액세스할 수 있습니다."</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"오디오 녹음 가능"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"근처 기기를 찾아 연결하고 기기 간 상대적 위치를 파악할 수 있습니다."</string>
<string name="permission_notification_summary" msgid="884075314530071011">"연락처, 메시지, 사진 등의 정보를 포함한 모든 알림을 읽을 수 있습니다."</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"휴대전화의 앱을 스트리밍합니다."</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"내 휴대전화의 앱 및 기타 시스템 기능 스트리밍"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ky/strings.xml b/packages/CompanionDeviceManager/res/values-ky/strings.xml
index c40e080..acbc031 100644
--- a/packages/CompanionDeviceManager/res/values-ky/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ky/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<xliff:g id="PROFILE_NAME">%1$s</xliff:g> <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> тарабынан башкарылсын"</string>
<string name="summary_watch" msgid="6566922405914995759">"Бул колдонмо <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздү тескөө үчүн керек. <xliff:g id="APP_NAME">%2$s</xliff:g> маалыматты шайкештирип, мисалы, билдирмелериңизди көрүп, телефонуңуз, SMS билдирүүлөр, байланыштар, жылнаама, чалуулар тизмеси жана жакын жердеги түзмөктөргө болгон уруксаттарды пайдалана алат."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Бул колдонмо <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүңүздү тескөө үчүн керек. <xliff:g id="APP_NAME">%2$s</xliff:g> маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын шайкештирет жана анын төмөнкү уруксаттары болот:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> түзмөгүн тескөөгө уруксат бересизби?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"көз айнектер"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Бул колдонмо <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгүн башкаруу үчүн керек. <xliff:g id="APP_NAME">%2$s</xliff:g> билдирмелериңизди көрүп, телефонуңуз, SMS билдирүүлөр, Байланыштар, Микрофон жана Жакын жердеги түзмөктөргө болгон уруксаттарды пайдалана алат."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Бул колдонмого телефонуңузда төмөнкүлөрдү аткарууга уруксат берилет:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> колдонмосуна телефонуңуздагы ушул маалыматты көрүүгө уруксат бериңиз"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Түзмөктөр аралык кызматтар"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан түзмөктөрүңүздүн ортосунда колдонмолорду өткөрүүгө уруксат сурап жатат"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play кызматтары"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> колдонмосу <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> түзмөгүңүздүн атынан телефондогу сүрөттөрдү, медиа файлдарды жана билдирмелерди колдонууга уруксат сурап жатат"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> түзмөгүнө бул аракетти аткарууга уруксат бересизби?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> <xliff:g id="DEVICE_NAME">%2$s</xliff:g> түзмөгүңүздүн атынан жакын жердеги түзмөктөрдө колдонмолорду жана тутумдун башка функцияларын алып ойнотууга уруксат сурап жатат"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"түзмөк"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана <xliff:g id="DEVICE_NAME">%1$s</xliff:g> түзмөгү менен шайкештирет."</string>
<string name="summary_generic" msgid="4988130802522924650">"Бул колдонмо маалыматты шайкештире алат, мисалы, чалып жаткан кишинин атын телефон жана тандалган түзмөк менен шайкештирет."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Сүрөттөр жана медиафайлдар"</string>
<string name="permission_notification" msgid="693762568127741203">"Билдирмелер"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Колдонмолор"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Алып ойнотуу"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Телефон чалууларды аткарып жана тескей алат"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Телефондогу чалуулар тизмесин окуп жана жаза алат"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS билдирүүлөрдү жөнөтүп жана көрө алат"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Байланыштарыңызга кире алат"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Жылнаамаңызга кире алат"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Аудио жаздыра алат"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Жакын жердеги түзмөктөрдү таап, аларга туташып, абалын аныктай алат"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Бардык билдирмелерди, анын ичинде байланыштар, билдирүүлөр жана сүрөттөр сыяктуу маалыматты окуй алат"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Телефондогу колдонмолорду алып ойнотуу"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Телефонуңуздагы колдонмолорду жана тутумдун башка функцияларын алып ойнотуу"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lo/strings.xml b/packages/CompanionDeviceManager/res/values-lo/strings.xml
index a7b0cac..9b48836 100644
--- a/packages/CompanionDeviceManager/res/values-lo/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lo/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"ເລືອກ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ເພື່ອໃຫ້ຖືກຈັດການໂດຍ <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"ຕ້ອງໃຊ້ແອັບດັ່ງກ່າວເພື່ອຈັດການ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຂອງທ່ານ. <xliff:g id="APP_NAME">%2$s</xliff:g> ຈະໄດ້ຮັບອະນຸຍາດໃຫ້ຊິງຂໍ້ມູນເຊັ່ນ: ຊື່ຂອງບາງຄົນທີ່ກຳລັງໂທ, ໂຕ້ຕອບກັບການແຈ້ງເຕືອນຂອງທ່ານ ແລະ ເຂົ້າເຖິງການອະນຸຍາດໂທລະສັບ, SMS, ລາຍຊື່ຜູ້ຕິດຕໍ່, ປະຕິທິນ, ບັນທຶກການໂທ ແລະ ອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງຂອງທ່ານ."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"ຕ້ອງໃຊ້ແອັບດັ່ງກ່າວເພື່ອຈັດການ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ຂອງທ່ານ. <xliff:g id="APP_NAME">%2$s</xliff:g> ຈະໄດ້ຮັບອະນຸຍາດໃຫ້ຊິງຂໍ້ມູນເຊັ່ນ: ຊື່ຂອງບາງຄົນທີ່ກຳລັງໂທ ແລະ ເຂົ້າເຖິງການອະນຸຍາດເຫຼົ່ານີ້:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ຈັດການ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ບໍ?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"ແວ່ນຕາ"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"ຕ້ອງໃຊ້ແອັບນີ້ເພື່ອຈັດການ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ຈະໄດ້ຮັບອະນຸຍາດໃຫ້ໂຕ້ຕອບກັບການແຈ້ງເຕືອນຂອງທ່ານ ແລະ ການອະນຸຍາດສິດເຂົ້າເຖິງໂທລະສັບ, SMS, ລາຍຊື່ຜູ້ຕິດຕໍ່, ໄມໂຄຣໂຟນ ແລະ ອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງຂອງທ່ານ."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"ແອັບນີ້ຈະຖືກອະນຸຍາດໃຫ້ເຂົ້າເຖິງການອະນຸຍາດເຫຼົ່ານີ້ຢູ່ໃນໂທລະສັບຂອງທ່ານ:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ອະນຸຍາດ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ໃຫ້ເຂົ້າເຖິງຂໍ້ມູນນີ້ຈາກໂທລະສັບຂອງທ່ານໄດ້"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ບໍລິການຂ້າມອຸປະກອນ"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອສະຕຣີມແອັບລະຫວ່າງອຸປະກອນຂອງທ່ານ"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"ບໍລິການ Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກຳລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມຂອງ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ເພື່ອເຂົ້າເຖິງຮູບພາບ, ມີເດຍ ແລະ ການແຈ້ງເຕືອນຂອງໂທລະສັບທ່ານ"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"ອະນຸຍາດ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ເພື່ອດຳເນີນຄຳສັ່ງນີ້ບໍ?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ກໍາລັງຮ້ອງຂໍການອະນຸຍາດໃນນາມ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ຂອງທ່ານເພື່ອສະຕຣີມແອັບ ແລະ ຄຸນສົມບັດລະບົບອື່ນໆໄປຫາອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ອຸປະກອນ"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"ແອັບນີ້ຈະສາມາດຊິງຂໍ້ມູນເຊັ່ນ: ຊື່ຂອງບາງຄົນທີ່ກຳລັງໂທຢູ່ລະຫວ່າງໂທລະສັບຂອງທ່ານ ແລະ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ໄດ້."</string>
<string name="summary_generic" msgid="4988130802522924650">"ແອັບນີ້ຈະສາມາດຊິງຂໍ້ມູນເຊັ່ນ: ຊື່ຂອງບາງຄົນທີ່ກຳລັງໂທຢູ່ລະຫວ່າງໂທລະສັບຂອງທ່ານ ແລະ ອຸປະກອນທີ່ເລືອກໄດ້."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ຮູບພາບ ແລະ ມີເດຍ"</string>
<string name="permission_notification" msgid="693762568127741203">"ການແຈ້ງເຕືອນ"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ແອັບ"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"ກຳລັງສະຕຣີມ"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ສາມາດໂທອອກ ແລະ ຈັດການການໂທໄດ້"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ສາມາດອ່ານ ແລະ ຂຽນບັນທຶກການໂທຂອງໂທລະສັບ"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"ສາມາດສົ່ງ ແລະ ເບິ່ງຂໍ້ຄວາມ SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"ສາມາດເຂົ້າເຖິງລາຍຊື່ຜູ້ຕິດຕໍ່ຂອງທ່ານ"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"ສາມາດເຂົ້າເຖິງປະຕິທິນຂອງທ່ານ"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ສາມາດບັນທຶກສຽງໄດ້"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"ສາມາດຊອກຫາ, ເຊື່ອມຕໍ່ ແລະ ລະບຸສະຖານທີ່ທີ່ກ່ຽວຂ້ອງກັນຂອງອຸປະກອນທີ່ຢູ່ໃກ້ຄຽງ"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"ສາມາດອ່ານການແຈ້ງເຕືອນທັງໝົດ, ຮວມທັງຂໍ້ມູນ ເຊັ່ນ: ລາຍຊື່ຜູ້ຕິດຕໍ່, ຂໍ້ຄວາມ ແລະ ຮູບພາບ"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"ສະຕຣີມແອັບຂອງໂທລະສັບທ່ານ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"ສະຕຣີມແອັບ ແລະ ຄຸນສົມບັດລະບົບອື່ນໆຈາກໂທລະສັບຂອງທ່ານ"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lt/strings.xml b/packages/CompanionDeviceManager/res/values-lt/strings.xml
index d3d8ca9..4b4deec 100644
--- a/packages/CompanionDeviceManager/res/values-lt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lt/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Jūsų <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, kurį valdys <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> (pasirinkite)"</string>
<string name="summary_watch" msgid="6566922405914995759">"Programa reikalinga norint tvarkyti jūsų įrenginį „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. Programai „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, sąveikauti su jūsų pranešimais ir pasiekti jūsų leidimus „Telefonas“, „SMS“, „Kontaktai“, „Kalendorius“, „Skambučių žurnalai“ ir „Įrenginiai netoliese“."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Programa reikalinga norint tvarkyti jūsų įrenginį „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. Programai „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, ir pasiekti toliau nurodytus leidimus."</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> valdyti <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"akiniai"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Ši programa reikalinga norint tvarkyti įrenginį „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“. Programai „<xliff:g id="APP_NAME">%2$s</xliff:g>“ bus leidžiama sąveikauti su jūsų pranešimais ir pasiekti jūsų leidimus „Telefonas“, „SMS“, „Kontaktai“, „Mikrofonas“ ir „Įrenginiai netoliese“."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Šiai programai bus leidžiama pasiekti toliau nurodytus leidimus jūsų telefone."</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Leisti <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> pasiekti šią informaciją iš jūsų telefono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Pasl. keliuose įrenginiuose"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas iš vieno įrenginio į kitą"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"„Google Play“ paslaugos"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Programa „<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>“ vardu, kad galėtų pasiekti telefono nuotraukas, mediją ir pranešimus"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Leisti <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> atlikti šį veiksmą?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"„<xliff:g id="APP_NAME">%1$s</xliff:g>“ prašo leidimo jūsų „<xliff:g id="DEVICE_NAME">%2$s</xliff:g>“ vardu, kad galėtų srautu perduoti programas ir kitas sistemos funkcijas įrenginiams netoliese"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"įrenginys"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ši programa galės sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, su jūsų telefonu ir įrenginiu „<xliff:g id="DEVICE_NAME">%1$s</xliff:g>“."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ši programa galės sinchronizuoti tam tikrą informaciją, pvz., skambinančio asmens vardą, su jūsų telefonu ir pasirinktu įrenginiu."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Nuotraukos ir medija"</string>
<string name="permission_notification" msgid="693762568127741203">"Pranešimai"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Programos"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Srautinis perdavimas"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Gali atlikti ir tvarkyti telefono skambučius"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Gali skaityti ir rašyti telefono skambučių žurnalą"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Gali siųsti ir peržiūrėti SMS pranešimus"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Gali pasiekti jūsų kontaktus"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Gali pasiekti jūsų kalendorių"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Gali įrašyti garsą"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Gali rasti apytikslę netoliese esančių įrenginių poziciją, aptikti juos ir prisijungti prie jų"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Galima skaityti visus pranešimus, įskaitant tokią informaciją kaip kontaktai, pranešimai ir nuotraukos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Telefono programų perdavimas srautu"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Srautu perduokite programas ir kitas sistemos funkcijas iš telefono"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-lv/strings.xml b/packages/CompanionDeviceManager/res/values-lv/strings.xml
index 8fe14bd4..76ca97e 100644
--- a/packages/CompanionDeviceManager/res/values-lv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-lv/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Profila (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>) izvēle, ko pārvaldīt lietotnē <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Šī lietotne ir nepieciešama jūsu ierīces (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) pārvaldībai. <xliff:g id="APP_NAME">%2$s</xliff:g> drīkstēs sinhronizēt informāciju, piemēram, zvanītāja vārdu, mijiedarboties ar jūsu paziņojumiem un piekļūt atļaujām Tālrunis, Īsziņas, Kontaktpersonas, Kalendārs, Zvanu žurnāli un Tuvumā esošas ierīces."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Šī lietotne ir nepieciešama jūsu ierīces (<xliff:g id="DEVICE_NAME">%1$s</xliff:g>) pārvaldībai. <xliff:g id="APP_NAME">%2$s</xliff:g> drīkstēs sinhronizēt informāciju, piemēram, zvanītāja vārdu, un piekļūt šīm atļaujām:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vai atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt ierīcei <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"brilles"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Šī lietotne ir nepieciešama šādas ierīces pārvaldībai: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> drīkstēs mijiedarboties ar jūsu paziņojumiem un piekļūt atļaujām Tālrunis, Īsziņas, Kontaktpersonas, Mikrofons un Tuvumā esošas ierīces."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Šai lietotnei tiks sniegta piekļuve šādām atļaujām jūsu tālrunī:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Atļaut lietotnei <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> piekļūt šai informācijai no jūsu tālruņa"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Vairāku ierīču pakalpojumi"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju straumēt lietotnes starp jūsu ierīcēm šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play pakalpojumi"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju piekļūt jūsu tālruņa fotoattēliem, multivides saturam un paziņojumiem šīs ierīces vārdā: <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vai atļaut ierīcei <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> veikt šo darbību?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> pieprasa atļauju tuvumā esošās ierīcēs straumēt lietotnes un citas sistēmas funkcijas šīs ierīces vārdā: <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ierīce"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Šī lietotne varēs sinhronizēt informāciju, piemēram, zvanītāja vārdu, starp jūsu tālruni un šo ierīci: <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Šī lietotne varēs sinhronizēt informāciju, piemēram, zvanītāja vārdu, starp jūsu tālruni un izvēlēto ierīci."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotoattēli un multivides faili"</string>
<string name="permission_notification" msgid="693762568127741203">"Paziņojumi"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Lietotnes"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Straumēšana"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Var veikt un pārvaldīt tālruņa zvanus"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Var lasīt un rakstīt tālruņa zvanu žurnālu"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Var sūtīt un skatīt īsziņas"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Var piekļūt jūsu kontaktpersonām"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Var piekļūt jūsu kalendāram"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Var ierakstīt audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Var atrast tuvumā esošas ierīces, izveidot ar tām savienojumu un noteikt to relatīvo atrašanās vietu"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Var lasīt visus paziņojumus, tostarp tādu informāciju kā kontaktpersonas, ziņojumi un fotoattēli."</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Straumēt jūsu tālruņa lietotnes"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"No sava tālruņa straumējiet lietotnes un citas sistēmas funkcijas"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mk/strings.xml b/packages/CompanionDeviceManager/res/values-mk/strings.xml
index 0fc9061..1df8093 100644
--- a/packages/CompanionDeviceManager/res/values-mk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mk/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Изберете <xliff:g id="PROFILE_NAME">%1$s</xliff:g> со којшто ќе управува <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Апликацијата е потребна за управување со вашиот <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ќе може да ги синхронизира податоците како што се имињата на јавувачите, да остварува интеракција со известувањата и да пристапува до дозволите за „Телефон“, SMS, „Контакти“, „Календар“, „Евиденција на повици“ и „Уреди во близина“."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Апликацијата е потребна за управување со вашиот <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ќе има дозвола да ги синхронизира податоците како што се имињата на јавувачите и да пристапува до следниве дозволи:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Ќе дозволите <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да управува со <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"очила"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Апликацијава е потребна за управување со <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ќе може да остварува интеракција со известувањата и да пристапува до дозволите за „Телефон“, SMS, „Контакти“, „Микрофон“ и „Уреди во близина“."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Апликацијава ќе може да пристапува до овие дозволи на телефонот:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Овозможете <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> да пристапува до овие податоци на телефонот"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Повеќенаменски услуги"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да стримува апликации помеѓу вашите уреди"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Услуги на Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за да пристапува до фотографиите, аудиовизуелните содржини и известувањата на телефонот"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ќе дозволите <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> да го преземе ова дејство?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> бара дозвола во име на вашиот <xliff:g id="DEVICE_NAME">%2$s</xliff:g> за да стримува апликации и други системски карактеристики на уредите во близина"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уред"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Оваа апликација ќе може да ги синхронизира податоците како што се имињата на јавувачите помеѓу вашиот телефон и <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Оваа апликација ќе може да ги синхронизира податоците како што се имињата на јавувачите помеѓу вашиот телефон и избраниот уред."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Аудиовизуелни содржини"</string>
<string name="permission_notification" msgid="693762568127741203">"Известувања"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Апликации"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Стриминг"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Може да упатува и управува со телефонски повици"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Може да чита и пишува евиденција на повици во телефонот"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Може да испраќа и гледа SMS-пораки"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Може да пристапува до вашите контакти"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Може да пристапува до вашиот календар"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Може да снима аудио"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Може да наоѓа и да се поврзува со уреди во близина и да ја утврдува нивната релативна положба"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"може да ги чита сите известувања, вклучително и податоци како контакти, пораки и фотографии"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Стримувајте ги апликациите на телефонот"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Апликации за стриминг и други системски карактеристики од вашиот телефон"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ml/strings.xml b/packages/CompanionDeviceManager/res/values-ml/strings.xml
index ee8b25b..99219e2 100644
--- a/packages/CompanionDeviceManager/res/values-ml/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ml/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ഉപയോഗിച്ച് മാനേജ് ചെയ്യുന്നതിന് ഒരു <xliff:g id="PROFILE_NAME">%1$s</xliff:g> തിരഞ്ഞെടുക്കുക"</string>
<string name="summary_watch" msgid="6566922405914995759">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ആപ്പ് ആവശ്യമാണ്. വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ സമന്വയിപ്പിക്കുന്നതിനും നിങ്ങളുടെ അറിയിപ്പുകളുമായി സംവദിക്കാനും നിങ്ങളുടെ ഫോൺ, SMS, Contacts, Calendar, കോൾ ചരിത്രം, സമീപമുള്ള ഉപകരണങ്ങളുടെ അനുമതികൾ എന്നിവ ആക്സസ് ചെയ്യാനും <xliff:g id="APP_NAME">%2$s</xliff:g> ആപ്പിനെ അനുവദിക്കും."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ആപ്പ് ആവശ്യമാണ്. വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ സമന്വയിപ്പിക്കുന്നതിനും ഈ അനുമതികൾ ആക്സസ് ചെയ്യുന്നതിനും <xliff:g id="APP_NAME">%2$s</xliff:g> എന്നതിനെ അനുവദിക്കും:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>? മാനേജ് ചെയ്യാൻ, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> എന്നതിനെ അനുവദിക്കുക"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"ഗ്ലാസുകൾ"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> മാനേജ് ചെയ്യാൻ ഈ ആപ്പ് ആവശ്യമാണ്. നിങ്ങളുടെ അറിയിപ്പുകളുമായി ഇടപഴകാനും ഫോൺ, SMS, കോൺടാക്റ്റുകൾ, മൈക്രോഫോൺ, സമീപമുള്ള ഉപകരണങ്ങളുടെ അനുമതികൾ എന്നിവ ആക്സസ് ചെയ്യാനും <xliff:g id="APP_NAME">%2$s</xliff:g> എന്നതിനെ അനുവദിക്കും."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"നിങ്ങളുടെ ഫോണിൽ ഇനിപ്പറയുന്ന അനുമതികൾ ആക്സസ് ചെയ്യാൻ ഈ ആപ്പിനെ അനുവദിക്കും:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ഈ വിവരങ്ങൾ ആക്സസ് ചെയ്യാൻ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ആപ്പിനെ അനുവദിക്കുക"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ക്രോസ്-ഉപകരണ സേവനങ്ങൾ"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"നിങ്ങളുടെ ഉപകരണങ്ങളിൽ ഒന്നിൽ നിന്ന് അടുത്തതിലേക്ക് ആപ്പുകൾ സ്ട്രീം ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play സേവനങ്ങൾ"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"നിങ്ങളുടെ ഫോണിലെ ഫോട്ടോകൾ, മീഡിയ, അറിയിപ്പുകൾ എന്നിവ ആക്സസ് ചെയ്യാൻ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ഉപകരണത്തിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"ഈ പ്രവർത്തനം നടത്താൻ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> എന്നതിനെ അനുവദിക്കണോ?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"സമീപമുള്ള ഉപകരണങ്ങളിൽ ആപ്പുകളും മറ്റ് സിസ്റ്റം ഫീച്ചറുകളും സ്ട്രീം ചെയ്യാൻ നിങ്ങളുടെ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> എന്നതിന് വേണ്ടി <xliff:g id="APP_NAME">%1$s</xliff:g> അനുമതി അഭ്യർത്ഥിക്കുന്നു"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ഉപകരണം"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ ഫോണിനും <xliff:g id="DEVICE_NAME">%1$s</xliff:g> എന്നതിനും ഇടയിൽ സമന്വയിപ്പിക്കുന്നതിന് ഈ ആപ്പിന് കഴിയും."</string>
<string name="summary_generic" msgid="4988130802522924650">"വിളിക്കുന്നയാളുടെ പേര് പോലുള്ള വിവരങ്ങൾ നിങ്ങളുടെ ഫോണിനും തിരഞ്ഞെടുത്ത ഉപകരണത്തിനും ഇടയിൽ സമന്വയിപ്പിക്കുന്നതിന് ഈ ആപ്പിന് കഴിയും."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ഫോട്ടോകളും മീഡിയയും"</string>
<string name="permission_notification" msgid="693762568127741203">"അറിയിപ്പുകൾ"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ആപ്പുകൾ"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"സ്ട്രീമിംഗ്"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ഫോൺ കോളുകൾ ചെയ്യാനും അവ മാനേജ് ചെയ്യാനും കഴിയും"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ഫോൺ കോൾ ചരിത്രം റീഡ് ചെയ്യാനും റൈറ്റ് ചെയ്യാനും കഴിയും"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS സന്ദേശങ്ങൾ അയയ്ക്കാനും കാണാനും കഴിയും"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"നിങ്ങളുടെ കോൺടാക്റ്റുകൾ ആക്സസ് ചെയ്യാൻ കഴിയും"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"നിങ്ങളുടെ കലണ്ടർ ആക്സസ് ചെയ്യാൻ കഴിയും"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ഓഡിയോ റെക്കോർഡ് ചെയ്യാം"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"സമീപമുള്ള ഉപകരണങ്ങൾ കണ്ടെത്താനും അവയിലേക്ക് കണക്റ്റ് ചെയ്യാനും അവയുടെ ആപേക്ഷിക സ്ഥാനം നിർണ്ണയിക്കാനും കഴിയും"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"കോൺടാക്റ്റുകൾ, സന്ദേശങ്ങൾ, ഫോട്ടോകൾ മുതലായ വിവരങ്ങൾ ഉൾപ്പെടെയുള്ള എല്ലാ അറിയിപ്പുകളും വായിക്കാനാകും"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"നിങ്ങളുടെ ഫോണിലെ ആപ്പുകൾ സ്ട്രീം ചെയ്യുക"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"നിങ്ങളുടെ ഫോണിൽ നിന്ന് ആപ്പുകളും മറ്റ് സിസ്റ്റം ഫീച്ചറുകളും സ്ട്രീം ചെയ്യാം"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mn/strings.xml b/packages/CompanionDeviceManager/res/values-mn/strings.xml
index e005b48..e4d658f 100644
--- a/packages/CompanionDeviceManager/res/values-mn/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mn/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>-н удирдах<xliff:g id="PROFILE_NAME">%1$s</xliff:g>-г сонгоно уу"</string>
<string name="summary_watch" msgid="6566922405914995759">"Энэ апп таны <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-г удирдахад шаардлагатай. <xliff:g id="APP_NAME">%2$s</xliff:g>-д залгаж буй хүний нэр зэрэг мэдээллийг синк хийх, таны мэдэгдэлтэй харилцан үйлдэл хийх, Утас, SMS, Харилцагчид, Календарь, Дуудлагын жагсаалт болон Ойролцоох төхөөрөмжүүдийн зөвшөөрөлд хандахыг зөвшөөрнө."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Энэ апп таны <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-г удирдахад шаардлагатай. <xliff:g id="APP_NAME">%2$s</xliff:g>-д залгаж буй хүний нэр зэрэг мэдээллийг синк хийх болон эдгээр зөвшөөрөлд хандахыг зөвшөөрнө:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>-г удирдахыг зөвшөөрөх үү?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"нүдний шил"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Энэ апп <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-г удирдахад шаардлагатай. <xliff:g id="APP_NAME">%2$s</xliff:g>-д таны мэдэгдэлтэй харилцан үйлдэл хийх, Утас, SMS, Харилцагчид, Микрофон болон Ойролцоох төхөөрөмжүүдийн зөвшөөрөлд хандахыг зөвшөөрнө."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Энэ апп таны утасны эдгээр зөвшөөрөлд хандах эрхтэй байх болно:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>-д таны утаснаас энэ мэдээлэлд хандахыг зөвшөөрнө үү"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Төхөөрөмж хоорондын үйлчилгээ"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Таны төхөөрөмжүүд хооронд апп дамжуулахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play үйлчилгээ"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Таны утасны зураг, медиа болон мэдэгдэлд хандахын тулд <xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>-н өмнөөс зөвшөөрөл хүсэж байна"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>-д энэ үйлдлийг хийхийг зөвшөөрөх үү?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> таны <xliff:g id="DEVICE_NAME">%2$s</xliff:g>-н өмнөөс аппууд болон системийн бусад онцлогийг ойролцоох төхөөрөмжүүд рүү дамжуулах зөвшөөрөл хүсэж байна"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"төхөөрөмж"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Энэ апп залгаж буй хүний нэр зэрэг мэдээллийг таны утас болон <xliff:g id="DEVICE_NAME">%1$s</xliff:g>-н хооронд синк хийх боломжтой болно."</string>
<string name="summary_generic" msgid="4988130802522924650">"Энэ апп залгаж буй хүний нэр зэрэг мэдээллийг таны утас болон сонгосон төхөөрөмжийн хооронд синк хийх боломжтой болно."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Зураг болон медиа"</string>
<string name="permission_notification" msgid="693762568127741203">"Мэдэгдэл"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Аппууд"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Дамжуулах"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Дуудлага хийх, удирдах боломжтой"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Утасны дуудлагын жагсаалтыг уншиж, бичих боломжтой"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS мессеж илгээх, үзэх боломжтой"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Таны харилцагчдад хандах боломжтой"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Таны календарьт хандах боломжтой"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Аудио бичих боломжтой"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Ойролцоох төхөөрөмжүүдийн харьцангуй байршлыг тодорхойлох, холбох, олох боломжтой"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Харилцагчид, мессеж болон зураг зэрэг мэдээллийг оруулаад бүх мэдэгдлийг унших боломжтой"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Утасныхаа аппуудыг дамжуулаарай"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Утаснаасаа аппууд болон системийн бусад онцлогийг дамжуулаарай"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-mr/strings.xml b/packages/CompanionDeviceManager/res/values-mr/strings.xml
index b693748..c7edf74 100644
--- a/packages/CompanionDeviceManager/res/values-mr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-mr/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> द्वारे व्यवस्थापित करण्यासाठी <xliff:g id="PROFILE_NAME">%1$s</xliff:g> निवडा"</string>
<string name="summary_watch" msgid="6566922405914995759">"तुमचे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापित करण्यासाठी हे ॲप आवश्यक आहे. <xliff:g id="APP_NAME">%2$s</xliff:g> ला कॉल करत असलेल्या एखाद्या व्यक्तीचे नाव यासारखी माहिती सिंक करण्याची, तुमच्या सूचनांसोबत संवाद साधण्याची आणि तुमचा फोन, एसएमएस, संपर्क, कॅलेंडर, कॉल लॉग व जवळपासच्या डिव्हाइसच्या परवानग्या अॅक्सेस करण्याची अनुमती मिळेल."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"तुमचे <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापित करण्यासाठी हे ॲप आवश्यक आहे. <xliff:g id="APP_NAME">%2$s</xliff:g> ला कॉल करत असलेल्या एखाद्या व्यक्तीचे नाव यासारखी माहिती सिंक करण्याची आणि पुढील परवानग्या अॅक्सेस करण्याची अनुमती मिळेल:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> व्यवस्थापित करण्याची अनुमती द्यायची आहे?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"Glasses"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापित करण्यासाठी हे ॲप आवश्यक आहे. <xliff:g id="APP_NAME">%2$s</xliff:g> ला तुमच्या सूचनांसोबत संवाद साधण्याची आणि तुमचा फोन, एसएमएस, संपर्क, मायक्रोफोन व जवळपासच्या डिव्हाइसच्या परवानग्या अॅक्सेस करण्याची अनुमती मिळेल."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"या अॅपला तुमच्या फोनवर या परवानग्या अॅक्सेस करण्याची अनुमती दिली जाईल:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ला ही माहिती तुमच्या फोनवरून अॅक्सेस करण्यासाठी अनुमती द्या"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रॉस-डिव्हाइस सेवा"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"तुमच्या डिव्हाइसदरम्यान ॲप्स स्ट्रीम करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play सेवा"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"तुमच्या फोनमधील फोटो, मीडिया आणि सूचना ॲक्सेस करण्यासाठी <xliff:g id="APP_NAME">%1$s</xliff:g> हे तुमच्या <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करत आहे"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ला ही कृती करण्याची अनुमती द्यायची आहे का?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> हे जवळपासच्या डिव्हाइसवर अॅप्स आणि इतर सिस्टीम वैशिष्ट्ये स्ट्रीम करण्यासाठी तुमच्या <xliff:g id="DEVICE_NAME">%2$s</xliff:g> च्या वतीने परवानगीची विनंती करा"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"डिव्हाइस"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"हे ॲप तुमचा फोन आणि <xliff:g id="DEVICE_NAME">%1$s</xliff:g> दरम्यान कॉल करत असलेल्या एखाद्या व्यक्तीचे नाव यासारखी माहिती सिंक करू शकेल."</string>
<string name="summary_generic" msgid="4988130802522924650">"हे ॲप तुमचा फोन आणि निवडलेल्या डिव्हाइसदरम्यान कॉल करत असलेल्या एखाद्या व्यक्तीचे नाव यासारखी माहिती सिंक करू शकेल."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"फोटो आणि मीडिया"</string>
<string name="permission_notification" msgid="693762568127741203">"सूचना"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ॲप्स"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"स्ट्रीमिंग"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"फोन कॉल करू आणि व्यवस्थापित करू शकते"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"फोन कॉल लॉग रीड अँड राइट करू शकते"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"एसएमएस मेसेज पाठवू आणि पाहू शकते"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"तुमचे संपर्क अॅक्सेस करू शकते"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"तुमचे कॅलेंडर अॅक्सेस करू शकते"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ऑडिओ रेकॉर्ड करू शकते"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"जवळील डिव्हाइस शोधू शकते, त्यांच्याशी कनेक्ट करू शकते आणि त्यांचे संबंधित स्थान निर्धारित करू शकते"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"संपर्क, मेसेज आणि फोटो यांसारख्या माहितीचा समावेश असलेल्या सर्व सूचना वाचू शकते"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"तुमच्या फोनवरील ॲप्स स्ट्रीम करा"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"तुमच्या फोनवरून अॅप्स आणि इतर सिस्टीम वैशिष्ट्ये स्ट्रीम करा"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ms/strings.xml b/packages/CompanionDeviceManager/res/values-ms/strings.xml
index 78d272d..7589417 100644
--- a/packages/CompanionDeviceManager/res/values-ms/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ms/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Pilih <xliff:g id="PROFILE_NAME">%1$s</xliff:g> untuk diurus oleh <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan untuk menyegerakkan maklumat seperti nama individu yang memanggil, berinteraksi dengan pemberitahuan anda dan mengakses kebenaran Telefon, SMS, Kenalan, Kalendar, Log panggilan dan Peranti berdekatan anda."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g> anda. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan untuk menyegerakkan maklumat seperti nama individu yang memanggil dan mengakses kebenaran ini:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengurus <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"cermin mata"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Apl ini diperlukan untuk mengurus <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> akan dibenarkan untuk berinteraksi dengan pemberitahuan anda dan mengakses kebenaran Telefon, SMS, Kenalan, Mikrofon dan Peranti berdekatan anda."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Apl ini akan dibenarkan untuk mengakses kebenaran yang berikut pada telefon anda:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Benarkan <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> mengakses maklumat ini daripada telefon anda"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Perkhidmatan silang peranti"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk menstrim apl antara peranti anda"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Perkhidmatan Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> anda untuk mengakses foto, media dan pemberitahuan telefon anda"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Benarkan <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> mengambil tindakan ini?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> sedang meminta kebenaran bagi pihak <xliff:g id="DEVICE_NAME">%2$s</xliff:g> anda untuk menstrim apl dan ciri sistem yang lain pada peranti berdekatan"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"peranti"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Apl ini akan dapat menyegerakkan maklumat seperti nama individu yang memanggil, antara telefon anda dengan <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Apl ini akan dapat menyegerakkan maklumat seperti nama individu yang memanggil, antara telefon anda dengan peranti yang dipilih."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto dan media"</string>
<string name="permission_notification" msgid="693762568127741203">"Pemberitahuan"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apl"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Penstriman"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Boleh membuat dan mengurus panggilan telefon"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Boleh membaca dan menulis log panggilan telefon"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Boleh menghantar dan melihat mesej SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Boleh mengakses kenalan anda"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Boleh mengakses kalendar anda"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Boleh merakamkan audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Boleh mencari, menyambung dan menentukan kedudukan relatif peranti berdekatan"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Boleh membaca semua pemberitahuan, termasuk maklumat seperti kenalan, mesej dan foto"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Strim apl telefon anda"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Strim apl dan ciri sistem yang lain daripada telefon anda"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-my/strings.xml b/packages/CompanionDeviceManager/res/values-my/strings.xml
index d63e4f2..91ac47a 100644
--- a/packages/CompanionDeviceManager/res/values-my/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-my/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> က စီမံခန့်ခွဲရန် <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ကို ရွေးချယ်ပါ"</string>
<string name="summary_watch" msgid="6566922405914995759">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်ရန်၊ သင်၏ဖုန်း၊ SMS စာတိုစနစ်၊ အဆက်အသွယ်များ၊ ပြက္ခဒိန်၊ ခေါ်ဆိုမှတ်တမ်းနှင့် အနီးတစ်ဝိုက်ရှိ စက်များဆိုင်ရာ ခွင့်ပြုချက်များသုံးရန်၊ အကြောင်းကြားချက်များနှင့် ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> ကို ခွင့်ပြုမည်။"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"သင်၏ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်ရန်နှင့် ဤခွင့်ပြုချက်များသုံးရန် <xliff:g id="APP_NAME">%2$s</xliff:g> ကို ခွင့်ပြုမည်-"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ကို <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> အား စီမံခွင့်ပြုမလား။"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"မျက်မှန်"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ကို စီမံခန့်ခွဲရန် ဤအက်ပ်လိုအပ်သည်။ သင်၏ဖုန်း၊ SMS စာတိုစနစ်၊ အဆက်အသွယ်များ၊ မိုက်ခရိုဖုန်းနှင့် အနီးတစ်ဝိုက်ရှိ စက်များဆိုင်ရာ ခွင့်ပြုချက်များသုံးရန်၊ အကြောင်းကြားချက်များနှင့် ပြန်လှန်တုံ့ပြန်ရန် <xliff:g id="APP_NAME">%2$s</xliff:g> ကို ခွင့်ပြုမည်။"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"ဤအက်ပ်သည် သင့်ဖုန်းတွင် ဤခွင့်ပြုချက်များကို သုံးခွင့်ရပါမည်-"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ကို သင့်ဖုန်းမှ ဤအချက်အလက် သုံးခွင့်ပြုမည်"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"စက်များကြားသုံး ဝန်ဆောင်မှုများ"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင်၏စက်များအကြား အက်ပ်များတိုက်ရိုက်လွှင့်ရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ဝန်ဆောင်မှုများ"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် သင့်ဖုန်း၏ ဓာတ်ပုံ၊ မီဒီယာနှင့် အကြောင်းကြားချက်များသုံးရန် <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ကို ဤသို့လုပ်ဆောင်ခွင့်ပြုမလား။"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> သည် အနီးတစ်ဝိုက်ရှိ အက်ပ်များနှင့် အခြားစနစ်အင်္ဂါရပ်များကို တိုက်ရိုက်ဖွင့်ရန် သင့် <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ကိုယ်စား ခွင့်ပြုချက်တောင်းနေသည်"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"စက်"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"ဤအက်ပ်သည် သင့်ဖုန်းနှင့် <xliff:g id="DEVICE_NAME">%1$s</xliff:g> အကြား ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်နိုင်ပါမည်။"</string>
<string name="summary_generic" msgid="4988130802522924650">"ဤအက်ပ်သည် သင့်ဖုန်းနှင့် ရွေးထားသောစက်အကြား ခေါ်ဆိုသူ၏အမည်ကဲ့သို့ အချက်အလက်ကို စင့်ခ်လုပ်နိုင်ပါမည်။"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ဓာတ်ပုံနှင့် မီဒီယာများ"</string>
<string name="permission_notification" msgid="693762568127741203">"အကြောင်းကြားချက်များ"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"အက်ပ်များ"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"တိုက်ရိုက်ဖွင့်ခြင်း"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ဖုန်းခေါ်ဆိုမှုများကို ပြုလုပ်ခြင်းနှင့် စီမံခြင်းတို့ လုပ်နိုင်သည်"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ဖုန်းခေါ်ဆိုမှတ်တမ်းကို ဖတ်ခြင်းနှင့် ရေးခြင်းတို့ လုပ်နိုင်သည်"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS မက်ဆေ့ဂျ်များကို ပို့ခြင်းနှင့် ကြည့်ရှုခြင်းတို့ လုပ်နိုင်သည်"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"သင့်အဆက်အသွယ်များကို ဝင်ကြည့်နိုင်သည်"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"သင့်ပြက္ခဒိန်ကို သုံးနိုင်သည်"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"အသံဖမ်းနိုင်သည်"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"အနီးတစ်ဝိုက်ရှိ စက်များ၏ ဆက်စပ်နေရာကို ရှာခြင်း၊ ချိတ်ဆက်ခြင်းနှင့် သတ်မှတ်ခြင်းတို့ လုပ်နိုင်သည်"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"အဆက်အသွယ်၊ မက်ဆေ့ဂျ်နှင့် ဓာတ်ပုံကဲ့သို့ အချက်အလက်များအပါအဝင် အကြောင်းကြားချက်အားလုံးကို ဖတ်နိုင်သည်"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"သင့်ဖုန်းရှိအက်ပ်များကို တိုက်ရိုက်ဖွင့်နိုင်သည်"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"သင့်ဖုန်းမှ အက်ပ်များနှင့် အခြားစနစ်အင်္ဂါရပ်များကို တိုက်ရိုက်ဖွင့်သည်"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nb/strings.xml b/packages/CompanionDeviceManager/res/values-nb/strings.xml
index 6c76f2b..60be245 100644
--- a/packages/CompanionDeviceManager/res/values-nb/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nb/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Velg <xliff:g id="PROFILE_NAME">%1$s</xliff:g> som skal administreres av <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Appen kreves for å administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillatelse til å synkronisere informasjon som navnet til noen som ringer, og samhandle med varslene dine, og får tilgang til tillatelsene for telefon, SMS, kontakter, kalender, samtalelogger og enheter i nærheten."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Appen kreves for å administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillatelse til å synkronisere informasjon som navnet til noen som ringer, og kan bruke disse tillatelsene:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vil du la <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> administrere <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"briller"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Denne appen kreves for å administrere <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tilgang til varslene dine og får tillatelsene for telefon, SMS, kontakter, mikrofon og enheter i nærheten."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Denne appen får disse tillatelsene på telefonen din:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Gi <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> tilgang til denne informasjonen fra telefonen din"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjenester på flere enheter"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å strømme apper mellom enhetene dine, på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjenester"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse til å få tilgang til bilder, medier og varsler på telefonen din, på vegne av <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vil du la <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> gjøre dette?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ber om tillatelse på vegne av <xliff:g id="DEVICE_NAME">%2$s</xliff:g> til å strømme apper og andre systemfunksjoner til enheter i nærheten"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Denne appen kan synkronisere informasjon som navnet til noen som ringer, mellom telefonen og <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Denne appen kan synkronisere informasjon som navnet til noen som ringer, mellom telefonen og den valgte enheten."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Bilder og medier"</string>
<string name="permission_notification" msgid="693762568127741203">"Varsler"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apper"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Strømming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Kan ringe ut og administrere anrop"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Kan lese og skrive samtaleloggen"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Kan sende og lese SMS-meldinger"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Kan bruke kontaktene dine"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Kan bruke kalenderen din"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Kan ta opp lyd"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Kan finne, koble til og fastslå den relative posisjonen til enheter i nærheten"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Kan lese alle varsler, inkludert informasjon som kontakter, meldinger og bilder"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Strøm appene på telefonen"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Strøm apper og andre systemfunksjoner fra telefonen"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ne/strings.xml b/packages/CompanionDeviceManager/res/values-ne/strings.xml
index 6e0a66d..6e51cd0 100644
--- a/packages/CompanionDeviceManager/res/values-ne/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ne/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"आफूले <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> प्रयोग गरी व्यवस्थापन गर्न चाहेको <xliff:g id="PROFILE_NAME">%1$s</xliff:g> चयन गर्नुहोस्"</string>
<string name="summary_watch" msgid="6566922405914995759">"तपाईंको <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापन गर्न यो एप चाहिन्छ। <xliff:g id="APP_NAME">%2$s</xliff:g> लाई कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्ने, तपाईंका सूचना हेर्ने र फोन, SMS, कन्ट्याक्ट, पात्रो, कल लग तथा नजिकैका डिभाइससम्बन्धी अनुमतिहरू हेर्ने तथा प्रयोग गर्ने अनुमति दिइने छ।"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"तपाईंको <xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापन गर्न यो एप चाहिन्छ। <xliff:g id="APP_NAME">%2$s</xliff:g> लाई कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्ने र यी अनुमतिहरू हेर्ने तथा प्रयोग गर्ने अनुमति दिइने छ:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> व्यवस्थापन गर्ने अनुमति दिने हो?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"चस्मा"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> व्यवस्थापन गर्न यो एप चाहिन्छ। <xliff:g id="APP_NAME">%2$s</xliff:g> लाई तपाईंका सूचना हेर्ने र फोन, SMS, कन्ट्याक्ट, माइक्रोफोन तथा नजिकैका डिभाइससम्बन्धी अनुमतिहरू हेर्ने तथा प्रयोग गर्ने अनुमति दिइने छ।"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"तपाईंको फोनमा यो एपलाई निम्न अनुमति दिइने छ:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> लाई तपाईंको फोनमा भएको यो जानकारी हेर्ने तथा प्रयोग गर्ने अनुमति दिनुहोस्"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"क्रस-डिभाइस सेवाहरू"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंका कुनै एउटा डिभाइसबाट अर्को डिभाइसमा एप स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> को तर्फबाट तपाईंको फोनमा भएका फोटो, मिडिया र सूचनाहरू हेर्ने तथा प्रयोग गर्ने अनुमति माग्दै छ"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> लाई यो कार्य गर्ने अनुमति दिने हो?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> तपाईंको डिभाइस <xliff:g id="DEVICE_NAME">%2$s</xliff:g> को तर्फबाट नजिकैका डिभाइसहरूमा एप र सिस्टमका अन्य सुविधाहरू स्ट्रिम गर्ने अनुमति माग्दै छ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"यन्त्र"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"यो एपले तपाईंको फोन र तपाईंले छनौट गर्ने <xliff:g id="DEVICE_NAME">%1$s</xliff:g> का बिचमा कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्न सक्ने छ।"</string>
<string name="summary_generic" msgid="4988130802522924650">"यो एपले तपाईंको फोन र तपाईंले छनौट गर्ने डिभाइसका बिचमा कल गर्ने व्यक्तिको नाम जस्ता जानकारी सिंक गर्न सक्ने छ।"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"फोटो र मिडिया"</string>
<string name="permission_notification" msgid="693762568127741203">"सूचनाहरू"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"एपहरू"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"स्ट्रिमिङ"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"फोन कल गर्न र कलहरू व्यवस्थापन गर्न सक्छ"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"फोनको कल लग रिड र राइट गर्न सक्छ"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS म्यासेजहरू पठाउन र हेर्न सक्छ"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"तपाईंका कन्ट्याक्टहरू हेर्न सक्छ"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"तपाईंको पात्रो हेर्न सक्छ"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"अडियो रेकर्ड गर्न सक्छ"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"नजिकैका डिभाइसहरू भेट्टाउन, ती डिभाइससँग कनेक्ट गर्न र तिनको सापेक्ष स्थिति निर्धारण गर्न सक्छ"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"कन्ट्याक्ट, म्यासेज र फोटोलगायतका जानकारीसहित सबै सूचनाहरू पढ्न सक्छ"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"आफ्नो फोनका एपहरू प्रयोग गर्नुहोस्"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"आफ्नो फोनबाट एप र सिस्टमका अन्य सुविधाहरू स्ट्रिम गर्नुहोस्"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-nl/strings.xml b/packages/CompanionDeviceManager/res/values-nl/strings.xml
index aadf83d..628379b 100644
--- a/packages/CompanionDeviceManager/res/values-nl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-nl/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Een <xliff:g id="PROFILE_NAME">%1$s</xliff:g> kiezen om te beheren met <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"De app is nodig om je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> mag informatie (zoals de naam van iemand die belt) synchroniseren, interactie hebben met je meldingen en krijgt toegang tot de rechten Telefoon, Sms, Contacten, Agenda, Gesprekslijsten en Apparaten in de buurt."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"De app is nodig om je <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> mag informatie (zoals de naam van iemand die belt) synchroniseren en krijgt toegang tot deze rechten:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toestaan <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> te beheren?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"brillen"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Deze app is nodig om <xliff:g id="DEVICE_NAME">%1$s</xliff:g> te beheren. <xliff:g id="APP_NAME">%2$s</xliff:g> mag interactie hebben met je meldingen en krijgt toegang tot de rechten Telefoon, Sms, Contacten, Microfoon en Apparaten in de buurt."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Deze app krijgt toegang tot deze rechten op je telefoon:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> toegang geven tot deze informatie op je telefoon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device-services"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toestemming om apps te streamen tussen je apparaten"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens jouw <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> toegang tot de foto\'s, media en meldingen van je telefoon"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Toestaan dat <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> deze actie uitvoert?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> vraagt namens je <xliff:g id="DEVICE_NAME">%2$s</xliff:g> toestemming om apps en andere systeemfuncties naar apparaten in de buurt te streamen"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"apparaat"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Deze app kan informatie, zoals de naam van iemand die belt, synchroniseren tussen je telefoon en <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Deze app kan informatie (zoals de naam van iemand die belt) synchroniseren tussen je telefoon en het gekozen apparaat."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Foto\'s en media"</string>
<string name="permission_notification" msgid="693762568127741203">"Meldingen"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Kan telefoongesprekken starten en beheren"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Kan gesprekslijst lezen en ernaar schrijven"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Kan sms-berichten sturen en bekijken"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Heeft toegang tot je contacten"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Heeft toegang tot je agenda"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Kan audio opnemen"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Kan apparaten in de buurt vinden, er verbinding mee maken en de relatieve positie ervan bepalen"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Kan alle meldingen lezen, waaronder informatie zoals contacten, berichten en foto\'s"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Stream de apps van je telefoon"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Apps en andere systeemfuncties streamen vanaf je telefoon"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-or/strings.xml b/packages/CompanionDeviceManager/res/values-or/strings.xml
index 2fbeea3..ba61866 100644
--- a/packages/CompanionDeviceManager/res/values-or/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-or/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ଦ୍ୱାରା ପରିଚାଳିତ ହେବା ପାଇଁ ଏକ <xliff:g id="PROFILE_NAME">%1$s</xliff:g>କୁ ବାଛନ୍ତୁ"</string>
<string name="summary_watch" msgid="6566922405914995759">"ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ ଆପ ଆବଶ୍ୟକ। କଲ କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ନାମ ପରି ସୂଚନା ସିଙ୍କ କରିବା, ଆପଣଙ୍କ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରିବା ଏବଂ ଆପଣଙ୍କର ଫୋନ, SMS, କଣ୍ଟାକ୍ଟ, କେଲେଣ୍ଡର, କଲ ଲଗ ଓ ଆଖପାଖର ଡିଭାଇସ ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%2$s</xliff:g>କୁ ଅନୁମତି ଦିଆଯିବ।"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ ଆପ ଆବଶ୍ୟକ। କଲ କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ନାମ ପରି ସୂଚନା ସିଙ୍କ କରିବା ଏବଂ ଏହି ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%2$s</xliff:g>କୁ ଅନୁମତି ଦିଆଯିବ:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>କୁ ପରିଚାଳନା କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦେବେ?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"ଚଷମା"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>କୁ ପରିଚାଳନା କରିବା ପାଇଁ ଏହି ଆପ ଆବଶ୍ୟକ। ଆପଣଙ୍କ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ ସହ ଇଣ୍ଟରାକ୍ଟ କରିବା ଏବଂ ଆପଣଙ୍କର ଫୋନ, SMS, କଣ୍ଟାକ୍ଟ, ମାଇକ୍ରୋଫୋନ ଓ ଆଖପାଖର ଡିଭାଇସ ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%2$s</xliff:g>କୁ ଅନୁମତି ଦିଆଯିବ।"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"ଆପଣଙ୍କ ଫୋନରେ ଏହି ଅନୁମତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ ଏହି ଆପକୁ ଅନୁମତି ଦିଆଯିବ:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"ଆପଣଙ୍କ ଫୋନରୁ ଏହି ସୂଚନାକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"କ୍ରସ-ଡିଭାଇସ ସେବାଗୁଡ଼ିକ"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"ଆପଣଙ୍କ ଡିଭାଇସଗୁଡ଼ିକ ମଧ୍ୟରେ ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କର <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ସେବାଗୁଡ଼ିକ"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"ଆପଣଙ୍କ ଫୋନର ଫଟୋ, ମିଡିଆ ଏବଂ ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କର <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"ଏହି ପଦକ୍ଷେପ ନେବା ପାଇଁ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>କୁ ଅନୁମତି ଦେବେ?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକରେ ଆପ୍ସ ଏବଂ ଅନ୍ୟ ସିଷ୍ଟମ ଫିଚରଗୁଡ଼ିକୁ ଷ୍ଟ୍ରିମ କରିବା ପାଇଁ <xliff:g id="APP_NAME">%1$s</xliff:g> ଆପଣଙ୍କ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ତରଫରୁ ଅନୁମତି ପାଇଁ ଅନୁରୋଧ କରୁଛି"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ଡିଭାଇସ୍"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"ଆପଣଙ୍କ ଫୋନ ଏବଂ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ମଧ୍ୟରେ, କଲ କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ନାମ ପରି ସୂଚନା ସିଙ୍କ କରିବାକୁ ଏହି ଆପ ସକ୍ଷମ ହେବ।"</string>
<string name="summary_generic" msgid="4988130802522924650">"ଆପଣଙ୍କ ଫୋନ ଏବଂ ବଛାଯାଇଥିବା ଡିଭାଇସ ମଧ୍ୟରେ, କଲ କରୁଥିବା ଯେ କୌଣସି ବ୍ୟକ୍ତିଙ୍କ ନାମ ପରି ସୂଚନା ସିଙ୍କ କରିବାକୁ ଏହି ଆପ ସକ୍ଷମ ହେବ।"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ଫଟୋ ଏବଂ ମିଡିଆ"</string>
<string name="permission_notification" msgid="693762568127741203">"ବିଜ୍ଞପ୍ତିଗୁଡ଼ିକ"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ଆପ୍ସ"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"ଷ୍ଟ୍ରିମିଂ"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ଫୋନ କଲଗୁଡ଼ିକ କରିପାରିବ ଏବଂ ସେଗୁଡ଼ିକୁ ପରିଚାଳନା କରିପାରିବ"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ଫୋନ କଲ ଲଗକୁ ପଢ଼ିପାରିବ ଏବଂ ଲେଖିପାରିବ"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS ମେସେଜଗୁଡ଼ିକ ପଠାଇପାରିବ ଏବଂ ଦେଖିପାରିବ"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"ଆପଣଙ୍କ କଣ୍ଟାକ୍ଟଗୁଡ଼ିକୁ ଆକ୍ସେସ କରିପାରିବ"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"ଆପଣଙ୍କ କେଲେଣ୍ଡରକୁ ଆକ୍ସେସ କରିପାରିବ"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ଅଡିଓ ରେକର୍ଡ କରିପାରିବ"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"ଆଖପାଖର ଡିଭାଇସଗୁଡ଼ିକୁ ଖୋଜିପାରିବ, କନେକ୍ଟ କରିପାରିବ ଏବଂ ସେଗୁଡ଼ିକର ଆପେକ୍ଷିକ ଅବସ୍ଥିତିକୁ ନିର୍ଦ୍ଧାରଣ କରିପାରିବ"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"ଯୋଗାଯୋଗ, ମେସେଜ ଏବଂ ଫଟୋଗୁଡ଼ିକ ପରି ସୂଚନା ସମେତ ସମସ୍ତ ବିଜ୍ଞପ୍ତିକୁ ପଢ଼ିପାରିବ"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"ଆପଣଙ୍କ ଫୋନର ଆପ୍ସକୁ ଷ୍ଟ୍ରିମ କରନ୍ତୁ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"ଆପଣଙ୍କ ଫୋନରୁ ଆପ୍ସ ଏବଂ ଅନ୍ୟ ସିଷ୍ଟମ ଫିଚରଗୁଡ଼ିକୁ ଷ୍ଟ୍ରିମ କରନ୍ତୁ"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pa/strings.xml b/packages/CompanionDeviceManager/res/values-pa/strings.xml
index 869f54c..7dd03c2 100644
--- a/packages/CompanionDeviceManager/res/values-pa/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pa/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ਵੱਲੋਂ ਪ੍ਰਬੰਧਿਤ ਕੀਤੇ ਜਾਣ ਲਈ <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ਚੁਣੋ"</string>
<string name="summary_watch" msgid="6566922405914995759">"ਇਹ ਐਪ ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਲੋੜੀਂਦੀ ਹੈ। <xliff:g id="APP_NAME">%2$s</xliff:g> ਨੂੰ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰਨ, ਤੁਹਾਡੀਆਂ ਸੂਚਨਾਵਾਂ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰਨ ਅਤੇ ਤੁਹਾਡੇ ਫ਼ੋਨ, SMS, ਸੰਪਰਕਾਂ, ਕੈਲੰਡਰ, ਕਾਲ ਲੌਗਾਂ ਅਤੇ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਸੰਬੰਧੀ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ।"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"ਇਹ ਐਪ ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਲੋੜੀਂਦੀ ਹੈ। <xliff:g id="APP_NAME">%2$s</xliff:g> ਨੂੰ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰਨ ਅਤੇ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"ਕੀ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"ਐਨਕਾਂ"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"ਇਹ ਐਪ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਲਈ ਲੋੜੀਂਦੀ ਹੈ। <xliff:g id="APP_NAME">%2$s</xliff:g> ਨੂੰ ਤੁਹਾਡੀਆਂ ਸੂਚਨਾਵਾਂ ਨਾਲ ਅੰਤਰਕਿਰਿਆ ਕਰਨ ਅਤੇ ਤੁਹਾਡੇ ਫ਼ੋਨ, SMS, ਸੰਪਰਕਾਂ, ਮਾਈਕ੍ਰੋਫ਼ੋਨ ਅਤੇ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਸੰਬੰਧੀ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ।"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"ਇਸ ਐਪ ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ \'ਤੇ ਇਨ੍ਹਾਂ ਇਜਾਜ਼ਤਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਹੋਵੇਗੀ:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਤੋਂ ਇਸ ਜਾਣਕਾਰੀ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਆਗਿਆ ਦਿਓ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"ਕ੍ਰਾਸ-ਡੀਵਾਈਸ ਸੇਵਾਵਾਂ"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਡੀਵਾਈਸਾਂ ਵਿਚਕਾਰ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play ਸੇਵਾਵਾਂ"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਤੁਹਾਡੇ ਫ਼ੋਨ ਦੀਆਂ ਫ਼ੋਟੋਆਂ, ਮੀਡੀਆ ਅਤੇ ਸੂਚਨਾਵਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"ਕੀ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ਨੂੰ ਇਹ ਕਾਰਵਾਈ ਕਰਨ ਦੀ ਆਗਿਆ ਦੇਣੀ ਹੈ?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ਤੁਹਾਡੇ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> ਦੀ ਤਰਫ਼ੋਂ ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ \'ਤੇ ਐਪਾਂ ਅਤੇ ਹੋਰ ਸਿਸਟਮ ਸੰਬੰਧੀ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਮੰਗ ਰਹੀ ਹੈ"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"ਡੀਵਾਈਸ"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ ਅਤੇ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ਵਿਚਕਾਰ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰ ਸਕੇਗੀ।"</string>
<string name="summary_generic" msgid="4988130802522924650">"ਇਹ ਐਪ ਤੁਹਾਡੇ ਫ਼ੋਨ ਅਤੇ ਚੁਣੇ ਗਏ ਡੀਵਾਈਸ ਵਿਚਕਾਰ ਕਾਲਰ ਦੇ ਨਾਮ ਵਰਗੀ ਜਾਣਕਾਰੀ ਨੂੰ ਸਿੰਕ ਕਰ ਸਕੇਗੀ।"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ਫ਼ੋਟੋਆਂ ਅਤੇ ਮੀਡੀਆ"</string>
<string name="permission_notification" msgid="693762568127741203">"ਸੂਚਨਾਵਾਂ"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ਐਪਾਂ"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"ਸਟ੍ਰੀਮਿੰਗ"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ਫ਼ੋਨ ਕਾਲਾਂ ਕਰਨ ਅਤੇ ਉਨ੍ਹਾਂ ਦਾ ਪ੍ਰਬੰਧਨ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਹੈ"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ਫ਼ੋਨ ਦੇ ਕਾਲ ਲੌਗ ਨੂੰ ਪੜ੍ਹਣ ਅਤੇ ਲਿਖਣ ਦੀ ਇਜਾਜ਼ਤ ਹੈ"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS ਸੁਨੇਹੇ ਭੇਜਣ ਅਤੇ ਦੇਖਣ ਦੀ ਇਜਾਜ਼ਤ ਹੈ"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"ਆਪਣੇ ਸੰਪਰਕਾਂ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਹੈ"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"ਆਪਣੇ ਕੈਲੰਡਰ ਤੱਕ ਪਹੁੰਚ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਹੈ"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ਆਡੀਓ ਰਿਕਾਰਡ ਕੀਤੀ ਜਾ ਸਕਦੀ ਹੈ"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"ਨਜ਼ਦੀਕੀ ਡੀਵਾਈਸਾਂ ਨੂੰ ਲੱਭਣ, ਉਨ੍ਹਾਂ ਨਾਲ ਕਨੈਕਟ ਕਰਨ ਅਤੇ ਸੰਬੰਧਿਤ ਸਥਿਤੀ ਨਿਰਧਾਰਿਤ ਕਰਨ ਦੀ ਇਜਾਜ਼ਤ ਹੈ"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"ਤੁਸੀਂ ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਪੜ੍ਹ ਸਕਦੇ ਹੋ, ਜਿਨ੍ਹਾਂ ਵਿੱਚ ਸੰਪਰਕਾਂ, ਸੁਨੇਹਿਆਂ ਅਤੇ ਫ਼ੋਟੋਆਂ ਵਰਗੀ ਜਾਣਕਾਰੀ ਸ਼ਾਮਲ ਹੁੰਦੀ ਹੈ"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"ਆਪਣੇ ਫ਼ੋਨ ਦੀਆਂ ਐਪਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰੋ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"ਆਪਣੇ ਫ਼ੋਨ ਤੋਂ ਐਪਾਂ ਅਤੇ ਹੋਰ ਸਿਸਟਮ ਸੰਬੰਧੀ ਵਿਸ਼ੇਸ਼ਤਾਵਾਂ ਨੂੰ ਸਟ੍ਰੀਮ ਕਰੋ"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pl/strings.xml b/packages/CompanionDeviceManager/res/values-pl/strings.xml
index 38e4bc0..776f4b8 100644
--- a/packages/CompanionDeviceManager/res/values-pl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pl/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Wybierz profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, którym ma zarządzać aplikacja <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Ta aplikacja jest niezbędna do zarządzania urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacja <xliff:g id="APP_NAME">%2$s</xliff:g> będzie mogła synchronizować informacje takie jak nazwa osoby dzwoniącej, korzystać z powiadomień oraz uprawnień dotyczących Telefonu, SMS-ów, Kontaktów, Kalendarza, rejestrów połączeń i Urządzeń w pobliżu."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Ta aplikacja jest niezbędna do zarządzania urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacja <xliff:g id="APP_NAME">%2$s</xliff:g> będzie mogła synchronizować informacje takie jak nazwa osoby dzwoniącej i korzystać z tych uprawnień:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Zezwolić na dostęp aplikacji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> do urządzenia <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"Okulary"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Ta aplikacja jest niezbędna do zarządzania urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Aplikacja <xliff:g id="APP_NAME">%2$s</xliff:g> będzie mogła wchodzić w interakcję z powiadomieniami i korzystać z uprawnień dotyczących telefonu, SMS-ów, kontaktów, mikrofonu oraz urządzeń w pobliżu."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Aplikacja będzie miała dostęp do tych uprawnień na Twoim telefonie:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Zezwól urządzeniu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na dostęp do tych informacji na Twoim telefonie"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Usługi na innym urządzeniu"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące strumieniowego odtwarzania treści z aplikacji na innym urządzeniu"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Usługi Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> o uprawnienia dotyczące dostępu do zdjęć, multimediów i powiadomień na telefonie"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Zezwolić urządzeniu <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> na wykonanie tego działania?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacja <xliff:g id="APP_NAME">%1$s</xliff:g> prosi w imieniu urządzenia <xliff:g id="DEVICE_NAME">%2$s</xliff:g> o uprawnienia do strumieniowego odtwarzania treści i innych funkcji systemowych na urządzeniach w pobliżu"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"urządzenie"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ta aplikacja może synchronizować informacje takie jak nazwa osoby dzwoniącej między Twoim telefonem i urządzeniem <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ta aplikacja może synchronizować informacje takie jak nazwa osoby dzwoniącej między Twoim telefonem i wybranym urządzeniem."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Zdjęcia i multimedia"</string>
<string name="permission_notification" msgid="693762568127741203">"Powiadomienia"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikacje"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Strumieniowanie"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Może wykonywać i odbierać połączenia"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Może odczytywać i zapisywać rejestr połączeń telefonicznych"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Może wysyłać i odbierać SMS-y"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Może uzyskać dostęp do kontaktów"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Może uzyskać dostęp do kalendarza"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Może nagrywać dźwięk"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Może znajdować urządzenia w pobliżu, określać ich względne położenie oraz łączyć się z nimi"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Może odczytywać wszystkie powiadomienia, w tym informacje takie jak kontakty, wiadomości i zdjęcia"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Odtwarzaj strumieniowo aplikacje z telefonu"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Aplikacje do odtwarzania strumieniowego i inne funkcje systemowe na Twoim telefonie"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
index 6c620df..7b9cc8c 100644
--- a/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt-rBR/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá sincronizar informações, como o nome de quem está ligando, interagir com suas notificações e acessar as permissões de telefone, SMS, contatos, agenda, registro de chamadas e dispositivos por perto."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar seu dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá sincronizar informações, como o nome de quem está ligando, e acessar estas permissões:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gerencie o dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"óculos"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá interagir com suas notificações e acessar suas permissões de telefone, SMS, contatos, microfone e dispositivos por perto."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Esse app poderá acessar estas permissões no smartphone:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> realize essa ação?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
<string name="permission_notification" msgid="693762568127741203">"Notificações"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Pode fazer e gerenciar ligações"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Pode ler e gravar o registro de chamadas"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Pode enviar e acessar mensagens SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Pode acessar seus contatos"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Pode acessar sua agenda"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Pode gravar áudio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Pode encontrar, determinar o posicionamento relativo e se conectar a dispositivos por perto"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Fazer transmissão dos apps no seu smartphone"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Faça streaming de apps e outros recursos do sistema pelo smartphone"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-pt/strings.xml b/packages/CompanionDeviceManager/res/values-pt/strings.xml
index 6c620df..7b9cc8c 100644
--- a/packages/CompanionDeviceManager/res/values-pt/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-pt/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Escolha um <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para ser gerenciado pelo app <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá sincronizar informações, como o nome de quem está ligando, interagir com suas notificações e acessar as permissões de telefone, SMS, contatos, agenda, registro de chamadas e dispositivos por perto."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar seu dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá sincronizar informações, como o nome de quem está ligando, e acessar estas permissões:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> gerencie o dispositivo <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"óculos"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"O app <xliff:g id="APP_NAME">%2$s</xliff:g> é necessário para gerenciar o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Ele poderá interagir com suas notificações e acessar suas permissões de telefone, SMS, contatos, microfone e dispositivos por perto."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Esse app poderá acessar estas permissões no smartphone:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permitir que o app <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> acesse estas informações do smartphone"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Serviços entre dispositivos"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para fazer streaming de apps entre seus dispositivos"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play Services"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"O app <xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para acessar fotos, mídia e notificações do smartphone."</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permitir que o dispositivo <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> realize essa ação?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> está pedindo permissão em nome do seu dispositivo <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para fazer streaming de apps e de outros recursos do sistema para dispositivos por perto"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispositivo"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"O app poderá sincronizar informações, como o nome de quem está ligando, entre seu smartphone e o dispositivo escolhido."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotos e mídia"</string>
<string name="permission_notification" msgid="693762568127741203">"Notificações"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Apps"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Pode fazer e gerenciar ligações"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Pode ler e gravar o registro de chamadas"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Pode enviar e acessar mensagens SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Pode acessar seus contatos"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Pode acessar sua agenda"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Pode gravar áudio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Pode encontrar, determinar o posicionamento relativo e se conectar a dispositivos por perto"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Pode ler todas as notificações, incluindo informações como contatos, mensagens e fotos"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Fazer transmissão dos apps no seu smartphone"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Faça streaming de apps e outros recursos do sistema pelo smartphone"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ro/strings.xml b/packages/CompanionDeviceManager/res/values-ro/strings.xml
index 240e7da..63e9d7c 100644
--- a/packages/CompanionDeviceManager/res/values-ro/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ro/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Alege un profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g> pe care să îl gestioneze <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Aplicația este necesară pentru a gestiona <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> va putea să sincronizeze informații, cum ar fi numele unui apelant, să interacționeze cu notificările tale și să îți acceseze permisiunile pentru Telefon, SMS, Agendă, Calendar, Jurnale de apeluri și Dispozitive din apropiere."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Aplicația este necesară pentru a gestiona <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> va putea să sincronizeze informații, cum ar fi numele unui apelant, și să acceseze următoarele permisiuni:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Permiți ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să gestioneze <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"ochelari"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Această aplicație este necesară pentru a gestiona <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> va putea să interacționeze cu notificările tale și să-ți acceseze permisiunile pentru Telefon, SMS, Agendă, Microfon și Dispozitive din apropiere."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Aplicația va putea să acceseze următoarele permisiuni pe telefon:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Permite ca <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> să acceseze aceste informații de pe telefon"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Servicii pe mai multe dispozitive"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a reda în stream aplicații între dispozitivele tale"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Servicii Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> de a accesa fotografiile, conținutul media și notificările de pe telefon"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Permiți ca <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> să realizeze această acțiune?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> solicită permisiunea pentru <xliff:g id="DEVICE_NAME">%2$s</xliff:g> de a reda în stream conținut din aplicații și alte funcții de sistem pe dispozitivele din apropiere"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"dispozitiv"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Aplicația va putea să sincronizeze informații, cum ar fi numele unui apelant, între telefonul tău și <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Aplicația va putea să sincronizeze informații, cum ar fi numele unui apelant, între telefonul tău și dispozitivul ales."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografii și media"</string>
<string name="permission_notification" msgid="693762568127741203">"Notificări"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplicații"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Poate să facă și să gestioneze apeluri telefonice"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Poate să citească și să scrie în jurnalul de apeluri telefonice"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Poate să trimită și să vadă mesaje SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Poate accesa agenda"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Poate accesa calendarul"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Poate să înregistreze conținut audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Poate să găsească, să se conecteze la și să determine poziția relativă a dispozitivelor apropiate"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Poate să citească toate notificările, inclusiv informații cum ar fi agenda, mesajele și fotografiile"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Să redea în stream aplicațiile telefonului"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Redă în stream conținut din aplicații și alte funcții de sistem de pe telefon"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ru/strings.xml b/packages/CompanionDeviceManager/res/values-ru/strings.xml
index f888ff9..b1699c3 100644
--- a/packages/CompanionDeviceManager/res/values-ru/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ru/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Выберите устройство (<xliff:g id="PROFILE_NAME">%1$s</xliff:g>), которым будет управлять приложение <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Это приложение необходимо для управления устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Приложение \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" сможет синхронизировать данные, например журнала звонков, а также получит доступ к уведомлениям и разрешения \"Телефон\", \"SMS\", \"Контакты\", \"Микрофон\" и \"Устройства поблизости\"."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Это приложение необходимо для управления устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Приложение \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" сможет синхронизировать данные, например журнала звонков, и получит следующие разрешения:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Разрешить приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> управлять устройством <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"Очки"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Это приложение необходимо для управления устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Приложение \"<xliff:g id="APP_NAME">%2$s</xliff:g>\" сможет взаимодействовать с уведомлениями, а также получит разрешения \"Телефон\", SMS, \"Контакты\", \"Микрофон\" и \"Устройства поблизости\"."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Это приложение получит следующие разрешения на телефоне:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Разрешите приложению <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> получать эту информацию с вашего телефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервисы стриминга приложений"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы транслировать приложения между вашими устройствами."</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сервисы Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" запрашивает разрешение от имени вашего устройства <xliff:g id="DEVICE_TYPE">%2$s</xliff:g>, чтобы получить доступ к фотографиям, медиаконтенту и уведомлениям на телефоне."</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Разрешить приложению <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> выполнять это действие?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Приложение \"<xliff:g id="APP_NAME">%1$s</xliff:g>\" от имени вашего устройства \"<xliff:g id="DEVICE_NAME">%2$s</xliff:g>\" запрашивает разрешение транслировать приложения и системные функции на устройства поблизости."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"устройство"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Приложение сможет синхронизировать информацию между телефоном и устройством \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\", например данные из журнала звонков."</string>
<string name="summary_generic" msgid="4988130802522924650">"Приложение сможет синхронизировать информацию между телефоном и выбранным устройством, например данные из журнала звонков."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Фотографии и медиафайлы"</string>
<string name="permission_notification" msgid="693762568127741203">"Уведомления"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Приложения"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Потоковая передача"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Приложение сможет совершать вызовы и управлять ими."</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Приложение сможет читать список вызовов и создавать записи в этом списке."</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Приложение сможет отправлять и просматривать SMS."</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Приложение сможет получать доступ к вашему списку контактов."</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Приложение сможет получать доступ к вашему календарю."</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Может записывать аудио"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Приложение сможет находить устройства поблизости, подключаться к ним и определять их относительное местоположение."</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Чтение всех уведомлений, в том числе сведений о контактах, сообщениях и фотографиях."</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Трансляция приложений с телефона."</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Трансляция приложений и системных функций с телефона"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-si/strings.xml b/packages/CompanionDeviceManager/res/values-si/strings.xml
index 8da88cf..af68659 100644
--- a/packages/CompanionDeviceManager/res/values-si/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-si/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> මගින් කළමනාකරණය කරනු ලැබීමට <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ක් තෝරන්න"</string>
<string name="summary_watch" msgid="6566922405914995759">"ඔබේ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> කළමනාකරණය කිරීමට මෙම යෙදුම අවශ්යයි. <xliff:g id="APP_NAME">%2$s</xliff:g> හට අමතන කෙනෙකුගේ නම වැනි, තතු සමමුහුර්ත කිරීමට, ඔබේ දැනුම්දීම් සමග අන්තර්ක්රියා කිරීමට සහ ඔබේ දුරකථනය, SMS, සම්බන්ධතා, දින දර්ශනය, ඇමතුම් ලොග සහ අවට උපාංග අවසර වෙත ප්රවේශ වීමට ඉඩ දෙනු ඇත."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"ඔබේ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> කළමනාකරණය කිරීමට මෙම යෙදුම අවශ්යයි. <xliff:g id="APP_NAME">%2$s</xliff:g> හට අමතන කෙනෙකුගේ නම වැනි, තතු සමමුහුර්ත කිරීමට සහ මෙම අවසරවලට ප්රවේශ වීමට ඉඩ දෙනු ඇත:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> කළමනා කිරීමට ඉඩ දෙන්න ද?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"කණ්ණාඩි"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> කළමනා කිරීමට මෙම යෙදුම අවශ්යයි. <xliff:g id="APP_NAME">%2$s</xliff:g> හට ඔබේ දැනුම්දීම් සමග අන්තර්ක්රියා කිරීමට සහ ඔබේ දුරකථනය, කෙටි පණිවුඩය, සම්බන්ධතා, මයික්රොෆෝනය සහ අවට උපාංග අවසර වෙත ප්රවේශ වීමට ඉඩ දෙයි."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"මෙම යෙදුමට ඔබේ දුරකථනයේ මෙම අවසර වෙත ප්රවේශ වීමට ඉඩ ලැබේ:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> හට ඔබගේ දුරකථනයෙන් මෙම තොරතුරුවලට ප්රවේශ වීමට ඉඩ දෙන්න"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"හරස්-උපාංග සේවා"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ උපාංග අතර යෙදුම් ප්රවාහ කිරීමට අවසරය ඉල්ලමින් සිටියි"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play සේවා"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබගේ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> වෙනුවෙන් ඔබගේ දුරකථනයෙහි ඡායාරූප, මාධ්ය සහ දැනුම්දීම් වෙත ප්රවේශ වීමට අවසරය ඉල්ලමින් සිටියි"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"මෙම ක්රියාව කිරීමට <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> හට ඉඩ දෙන්න ද?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ඔබේ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> වෙනුවෙන් යෙදුම් සහ අනෙකුත් පද්ධති විශේෂාංග අවට උපාංග වෙත ප්රවාහ කිරීමට අවසර ඉල්ලයි"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"උපාංගය"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"මෙම යෙදුමට ඔබේ දුරකථනය සහ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> අතර, අමතන කෙනෙකුගේ නම වැනි, තතු සමමුහුර්ත කිරීමට හැකි වනු ඇත."</string>
<string name="summary_generic" msgid="4988130802522924650">"මෙම යෙදුමට ඔබේ දුරකථනය සහ තෝරා ගත් උපාංගය අතර, අමතන කෙනෙකුගේ නම වැනි, තතු සමමුහුර්ත කිරීමට හැකි වනු ඇත."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ඡායාරූප සහ මාධ්ය"</string>
<string name="permission_notification" msgid="693762568127741203">"දැනුම්දීම්"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"යෙදුම්"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"ප්රවාහ කිරීම"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"දුරකථන ඇමතුම් ගැනීමට සහ කළමනාකරණය කිරීමට හැක"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"දුරකථන ඇමතුම් ලොගය කියවීමට සහ ලිවීමට හැක"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS පණිවිඩ යැවීමට සහ බැලීමට හැක"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"ඔබේ සම්බන්ධතා වෙත ප්රවේශ විය හැක"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"ඔබේ දින දර්ශනයට ප්රවේශ විය හැක"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ශ්රව්ය පටිගත කළ හැක"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"අවට උපාංගවල සාපේක්ෂ පිහිටීම සොයා ගැනීමට, සම්බන්ධ කිරීමට, සහ තීරණය කිරීමට හැක"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"සම්බන්ධතා, පණිවිඩ සහ ඡායාරූප වැනි තොරතුරු ඇතුළුව සියලු දැනුම්දීම් කියවිය හැකිය"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"ඔබේ දුරකථනයේ යෙදුම් ප්රවාහ කරන්න"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"ඔබේ දුරකථනයෙන් යෙදුම් සහ අනෙකුත් පද්ධති විශේෂාංග ප්රවාහ කරන්න"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sk/strings.xml b/packages/CompanionDeviceManager/res/values-sk/strings.xml
index d73f0c6..d10da15 100644
--- a/packages/CompanionDeviceManager/res/values-sk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sk/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Vyberte profil <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, ktorý bude spravovať aplikácia <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Daná aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť synchronizovať informácie, napríklad meno volajúceho, interagovať s vašimi upozorneniami a získavať prístup k povoleniam telefónu, SMS, kontaktov, kalendára, zoznamu hovorov a zariadení v okolí."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Daná aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť synchronizovať informácie, napríklad meno volajúceho, a získavať prístup k týmto povoleniam:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Chcete povoliť aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> spravovať zariadenie <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"okuliare"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Táto aplikácia sa vyžaduje na správu zariadenia <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> bude môcť interagovať s vašimi upozorneniami a získa prístup k povoleniam pre telefón, SMS, kontakty, mikrofón a zariadenia v okolí."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Táto aplikácia bude mať vo vašom telefóne prístup k týmto povoleniam:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Povoľte aplikácii <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> prístup k týmto informáciám z vášho telefónu"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Služby pre viacero zariadení"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na streamovanie aplikácií medzi vašimi zariadeniami v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Služby Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Aplikácia <xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje povolenie na prístup k fotkám, médiám a upozorneniam vášho telefónu v mene tohto zariadenia (<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>)"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Chcete povoliť zariadeniu <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> vykonať túto akciu?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> vyžaduje pre zariadenie <xliff:g id="DEVICE_NAME">%2$s</xliff:g> povolenie streamovať aplikácie a ďalšie systémové funkcie do zariadení v okolí"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"zariadenie"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, medzi telefónom a zariadením <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Táto aplikácia bude môcť synchronizovať informácie, napríklad meno volajúceho, medzi telefónom a vybraným zariadením."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotky a médiá"</string>
<string name="permission_notification" msgid="693762568127741203">"Upozornenia"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikácie"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Môže uskutočňovať a spravovať telefonické hovory"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Môže čítať zo zoznamu hovorov telefónu a zapisovať doň"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Môže odosielať a zobrazovať správy SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Má prístup k vašim kontaktom"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Má prístup k vášmu kalendáru"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Môže nahrávať zvuk"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Môže vyhľadávať zariadenia v okolí, určovať ich relatívnu pozíciu a pripájať sa k nim"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Môže čítať všetky upozornenia vrátane informácií, ako sú kontakty, správy a fotky"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Streamovať aplikácie telefónu"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Steaming aplikácii a ďalších systémov funkcií zo zariadenia"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sl/strings.xml b/packages/CompanionDeviceManager/res/values-sl/strings.xml
index 118e85a..ee330dd 100644
--- a/packages/CompanionDeviceManager/res/values-sl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sl/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Izbira naprave »<xliff:g id="PROFILE_NAME">%1$s</xliff:g>«, ki jo bo upravljala aplikacija <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Ta aplikacija je potrebna za upravljanje naprave »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> bodo omogočene sinhronizacija podatkov, na primer imena klicatelja, interakcija z obvestili in uporaba dovoljenj Telefon, SMS, Stiki, Koledar, Dnevniki klicev in Naprave v bližini."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Ta aplikacija je potrebna za upravljanje naprave »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> bosta omogočena sinhronizacija podatkov, na primer imena klicatelja, in dostop do teh dovoljenj:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Želite aplikaciji <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dovoliti upravljanje naprave <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"očala"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Ta aplikacija je potrebna za upravljanje naprave »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«. Aplikaciji <xliff:g id="APP_NAME">%2$s</xliff:g> bosta omogočeni interakcija z obvestili in uporaba dovoljenj Telefon, SMS, Stiki, Mikrofon in Naprave v bližini."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Ta aplikacija bo lahko dostopala do teh dovoljenj v telefonu:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Dovolite, da <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> dostopa do teh podatkov v vašem telefonu"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Storitve za zunanje naprave"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij v vaših napravah."</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Storitve Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>« zahteva dovoljenje za dostop do fotografij, predstavnosti in obvestil v telefonu."</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ali napravi <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> dovolite izvedbo tega dejanja?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Aplikacija <xliff:g id="APP_NAME">%1$s</xliff:g> v imenu naprave »<xliff:g id="DEVICE_NAME">%2$s</xliff:g>« zahteva dovoljenje za pretočno predvajanje aplikacij in drugih sistemskih funkcij v napravah v bližini."</string>
<string name="profile_name_generic" msgid="6851028682723034988">"naprava"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ta aplikacija bo lahko sinhronizirala podatke, na primer ime klicatelja, v telefonu in napravi »<xliff:g id="DEVICE_NAME">%1$s</xliff:g>«."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ta aplikacija bo lahko sinhronizirala podatke, na primer ime klicatelja, v telefonu in izbrani napravi."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografije in predstavnost"</string>
<string name="permission_notification" msgid="693762568127741203">"Obvestila"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikacije"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Pretočno predvajanje"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Lahko opravlja in upravlja telefonske klice"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Lahko bere in zapisuje dnevnik klicev v telefonu"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Lahko pošilja in si ogleduje sporočila SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Lahko dostopa do stikov"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Lahko dostopa do koledarja"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Lahko snema zvok"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Lahko išče naprave v bližini, se povezuje z njimi in določa njihov relativni položaj"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Lahko bere vsa obvestila, vključno s podatki, kot so stiki, sporočila in fotografije."</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Pretočno predvajanje aplikacij telefona"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Pretočno predvajanje aplikacij in drugih sistemskih funkcij iz telefona"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sq/strings.xml b/packages/CompanionDeviceManager/res/values-sq/strings.xml
index 472fcf3..afff09d 100644
--- a/packages/CompanionDeviceManager/res/values-sq/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sq/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Zgjidh \"<xliff:g id="PROFILE_NAME">%1$s</xliff:g>\" që do të menaxhohet nga <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Aplikacioni nevojitet për të menaxhuar profilin tënd të <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të sinkronizojë informacione, si p.sh. emri i dikujt që po telefonon, të ndërveprojë me njoftimet e tua dhe të ketë qasje te lejet e \"Telefonit\", \"SMS-ve\", \"Kontakteve\", \"Kalendarit\", \"Evidencave të telefonatave\" dhe \"Pajisjeve në afërsi\"."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Aplikacioni nevojitet për të menaxhuar profilin tënd të <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të sinkronizojë informacione, si p.sh. emri i dikujt që po telefonon dhe të ketë qasje te këto leje:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Të lejohet që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të menaxhojë <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"syzet"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Ky aplikacion nevojitet për të menaxhuar <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> do të lejohet të ndërveprojë me njoftimet e tua dhe të ketë qasje te lejet e \"Telefonit\", \"SMS-ve\", \"Kontakteve\", \"Mikrofonit\" dhe të \"Pajisjeve në afërsi\"."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Ky aplikacion do të lejohet të ketë qasje te këto leje në telefonin tënd:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Lejo që <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> të ketë qasje në këtë informacion nga telefoni yt"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Shërbimet mes pajisjeve"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të transmetuar aplikacione ndërmjet pajisjeve të tua"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Shërbimet e Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> për të marrë qasje te fotografitë, media dhe njoftimet e telefonit tënd"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Të lejohet që <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> të ndërmarrë këtë veprim?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> po kërkon leje në emër të (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) tënde për të transmetuar aplikacione dhe veçori të tjera të sistemit te pajisjet në afërsi"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"pajisja"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ky aplikacion do të mund të sinkronizojë informacione, si p.sh emri i dikujt që po telefonon, mes telefonit tënd dhe <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ky aplikacion do të mund të sinkronizojë informacione, si p.sh emri i dikujt që po telefonon, mes telefonit tënd dhe pajisjes së zgjedhur."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotografitë dhe media"</string>
<string name="permission_notification" msgid="693762568127741203">"Njoftimet"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Aplikacionet"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Transmetimi"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Mund të bëjë dhe të menaxhojë telefonatat"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Mund të lexojë dhe të shkruajë në evidencën e telefonatave"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Mund të dërgojë dhe të shikojë mesazhet SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Mund të ketë qasje te kontaktet e tua"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Mund të ketë qasje te kalendari"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Mund të regjistrojë audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Mund të gjejë, të lidhet dhe të përcaktojë pozicionin e përafërt të pajisjeve në afërsi"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Mund të lexojë të gjitha njoftimet, duke përfshirë informacione si kontaktet, mesazhet dhe fotografitë"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Transmeto aplikacionet e telefonit tënd"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Transmeto aplikacionet dhe veçoritë e tjera të sistemit nga telefoni yt"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sr/strings.xml b/packages/CompanionDeviceManager/res/values-sr/strings.xml
index 8dbcd2a..2c02500 100644
--- a/packages/CompanionDeviceManager/res/values-sr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sr/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Одаберите <xliff:g id="PROFILE_NAME">%1$s</xliff:g> којим ће управљати апликација <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Апликација је потребна за управљање уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ће добити дозволу за синхронизовање информација, попут особе која упућује позив, за интеракцију са обавештењима и приступ дозволама за телефон, SMS, контакте, календар, евиденције позива и уређаје у близини."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Апликација је потребна за управљање уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ће добити дозволу за синхронизацију информација, попут особе која упућује позив, као за приступ следећим дозволама:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Желите ли да дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> управља уређајем <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"наочаре"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Ова апликација је потребна за управљање уређајем <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> ће добити дозволу за интеракцију са обавештењима и приступ дозволама за телефон, SMS, контакте, микрофон и уређаје у близини."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Овој апликацији ће бити дозвољено да приступа овим дозволама на телефону:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Дозволите да <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> приступа овим информацијама са телефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Услуге на више уређаја"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за стримовање апликација између уређаја"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play услуге"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> за приступ сликама, медијском садржају и обавештењима са телефона"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Желите ли да дозволите да <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> обави ову радњу?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Апликација <xliff:g id="APP_NAME">%1$s</xliff:g> захтева дозволу у име уређаја <xliff:g id="DEVICE_NAME">%2$s</xliff:g> да стримује апликације и друге системске функције на уређаје у близини"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"уређај"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ова апликација ће моћи да синхронизује податке, попут имена особе која упућује позив, између телефона и уређаја <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ова апликација ће моћи да синхронизује податке, попут имена особе која упућује позив, између телефона и одабраног уређаја."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Слике и медији"</string>
<string name="permission_notification" msgid="693762568127741203">"Обавештења"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Апликације"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Стриминг"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Може да упућује телефонске позиве и управља њима"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Може да чита и пише евиденцију позива на телефону"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Може да шаље и прегледа SMS поруке"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Може да приступа контактима"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Може да приступа календару"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Може да снима звук"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Може да проналази и утврђује релативну позицију уређаја у близини, као и да се повезује са њима"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Може да чита сва обавештења, укључујући информације попут контаката, порука и слика"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Стримујте апликације на телефону"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Стримујте апликације и друге системске функције са телефона"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sv/strings.xml b/packages/CompanionDeviceManager/res/values-sv/strings.xml
index 3545c00..afdec60 100644
--- a/packages/CompanionDeviceManager/res/values-sv/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sv/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Välj en <xliff:g id="PROFILE_NAME">%1$s</xliff:g> för hantering av <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Appen behövs för att hantera <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillåtelse att synkronisera information, till exempel namnet på någon som ringer, interagera med dina aviseringar och får åtkomst till behörigheterna Telefon, Sms, Kontakter, Kalender, Samtalsloggar och Enheter i närheten."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Appen behövs för att hantera <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillåtelse att synkronisera information, till exempel namnet på någon som ringer, och får åtkomst till följande behörigheter:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Tillåt att <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> hanterar <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"glasögon"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Appen behövs för att hantera <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> får tillåtelse att interagera med dina aviseringar och får åtkomst till behörigheterna Telefon, Sms, Kontakter, Mikrofon och Enheter i närheten."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Appen får tillåtelse att använda dessa behörigheter på din telefon:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ge <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> åtkomstbehörighet till denna information på telefonen"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Tjänster för flera enheter"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att låta <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> streama appar mellan enheter"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play-tjänster"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att ge <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> åtkomst till foton, mediefiler och aviseringar på telefonen"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vill du tillåta att <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> utför denna åtgärd?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> begär behörighet att streama appar och andra systemfunktioner till enheter i närheten för din <xliff:g id="DEVICE_NAME">%2$s</xliff:g>"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"enhet"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Den här appen kommer att kunna synkronisera information mellan telefonen och <xliff:g id="DEVICE_NAME">%1$s</xliff:g>, till exempel namnet på någon som ringer."</string>
<string name="summary_generic" msgid="4988130802522924650">"Den här appen kommer att kunna synkronisera information mellan telefonen och den valda enheten, till exempel namnet på någon som ringer."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Foton och media"</string>
<string name="permission_notification" msgid="693762568127741203">"Aviseringar"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Appar"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Får skapa och hantera telefonsamtal"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Får läsa och skriva samtalslogg"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Får skicka och visa sms"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Får åtkomst till dina kontakter"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Får åtkomst till din kalender"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Kan spela in ljud"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Får hitta, ansluta till och avgöra den relativa positionen för enheter i närheten"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Kan läsa alla aviseringar, inklusive information som kontakter, meddelanden och foton"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Streama telefonens appar"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Streama appar och andra systemfunktioner från din telefon"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-sw/strings.xml b/packages/CompanionDeviceManager/res/values-sw/strings.xml
index 3e3ee8f..3cbcc6a 100644
--- a/packages/CompanionDeviceManager/res/values-sw/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-sw/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Chagua <xliff:g id="PROFILE_NAME">%1$s</xliff:g> ili idhibitiwe na <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Programu hii inahitajika ili udhibiti <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako. <xliff:g id="APP_NAME">%2$s</xliff:g> itaruhusiwa kusawazisha maelezo, kama vile jina la mtu anayepiga simu, kutumia arifa zako na ruhusa zako za Simu, SMS, Anwani, Maikrofoni na vifaa vilivyo Karibu."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Programu hii inahitajika ili udhibiti <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako. <xliff:g id="APP_NAME">%2$s</xliff:g> itaruhusiwa kusawazisha maelezo, kama vile jina la mtu anayepiga simu na kufikia ruhusa hizi:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Ungependa kuruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> idhibiti <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"miwani"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Programu hii inahitajika ili udhibiti <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> itaruhusiwa kutumia arifa zako na kufikia ruhusa zako za Simu, SMS, Anwani, Maikrofoni na Vifaa vilivyo Karibu."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Programu hii itaruhusiwa kufikia ruhusa hizi kwenye simu yako:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Ruhusu <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifikie maelezo haya kutoka kwenye simu yako"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Huduma za kifaa kilichounganishwa kwingine"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili itiririshe programu kati ya vifaa vyako"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Huduma za Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Programu ya <xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yako ili ifikie picha, maudhui na arifa za simu yako"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Ungependa kuruhusu <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> itekeleze kitendo hiki?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> inaomba ruhusa kwa niaba ya <xliff:g id="DEVICE_NAME">%2$s</xliff:g> chako ili itiririshe programu na vipengele vingine vya mfumo kwenye vifaa vilivyo karibu"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"kifaa"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Programu hii itaweza kusawazisha maelezo, kama vile jina la mtu anayepiga simu, kati ya simu na <xliff:g id="DEVICE_NAME">%1$s</xliff:g> yako."</string>
<string name="summary_generic" msgid="4988130802522924650">"Programu hii itaweza kusawazisha maelezo, kama vile jina la mtu anayepiga simu, kati ya simu yako na kifaa ulichochagua."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Picha na maudhui"</string>
<string name="permission_notification" msgid="693762568127741203">"Arifa"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Programu"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Kutiririsha maudhui"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Inaweza kupiga na kudhibiti simu"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Inaweza kusoma na kuandika rekodi ya nambari za simu"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Inaweza kutuma na kuangalia ujumbe wa SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Inaweza kufikia anwani zako"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Inaweza kufikia kalenda yako"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Inaweza kurekodi sauti"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Inaweza kutafuta, kuunganisha na kubaini nafasi ya makadirio ya vifaa vilivyo karibu"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Inaweza kusoma arifa zote, ikiwa ni pamoja na maelezo kama vile anwani, ujumbe na picha"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Tiririsha programu za simu yako"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Kutiririsha programu na vipengele vya mfumo kwenye simu yako"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ta/strings.xml b/packages/CompanionDeviceManager/res/values-ta/strings.xml
index ab05c26..939ba8e 100644
--- a/packages/CompanionDeviceManager/res/values-ta/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ta/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ஆப்ஸ் நிர்வகிக்கக்கூடிய <xliff:g id="PROFILE_NAME">%1$s</xliff:g> தேர்ந்தெடுக்கப்பட வேண்டும்"</string>
<string name="summary_watch" msgid="6566922405914995759">"உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தை நிர்வகிக்க இந்த ஆப்ஸ் தேவை. தகவலை (அழைப்பவரின் பெயர் போன்றவை) ஒத்திசைத்தல், உங்கள் அறிவிப்புகளைப் பார்த்தல் போன்றவற்றுக்கான அனுமதியையும் உங்கள் மொபைல், மெசேஜ், தொடர்புகள், கேலெண்டர், அழைப்புப் பதிவுகள், அருகிலுள்ள சாதனங்கள் ஆகியவற்றுக்கான அணுகலையும் <xliff:g id="APP_NAME">%2$s</xliff:g> ஆப்ஸ் பெறும்."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"உங்கள் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தை நிர்வகிக்க இந்த ஆப்ஸ் தேவை. தகவலை (அழைப்பவரின் பெயர் போன்றவை) ஒத்திசைப்பதற்கும் இந்த அனுமதிகளைப் பயன்படுத்துவதற்கும் <xliff:g id="APP_NAME">%2$s</xliff:g> ஆப்ஸுக்கு அனுமதி வழங்கப்படும்:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong&gt சாதனத்தை நிர்வகிக்க <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கவா?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"கிளாஸஸ்"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்தை நிர்வகிக்க இந்த ஆப்ஸ் தேவை. உங்கள் மொபைல், மெசேஜ், தொடர்புகள், மைக்ரோஃபோன், அருகிலுள்ள சாதனங்கள் ஆகியவற்றுக்கான அணுகலையும் உங்கள் அறிவிப்புகளைப் பார்ப்பதற்கான அனுமதியையும் <xliff:g id="APP_NAME">%2$s</xliff:g> பெறும்."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"உங்கள் மொபைலில் இந்த அனுமதிகளை அணுகுவதற்கு ஆப்ஸுக்கு அனுமதி வழங்கப்படும்:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"மொபைலில் உள்ள இந்தத் தகவல்களை அணுக, <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ஆப்ஸை அனுமதிக்கவும்"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"பன்முக சாதன சேவைகள்"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"உங்கள் சாதனங்களுக்கு இடையே ஆப்ஸை ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play சேவைகள்"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"உங்கள் மொபைலில் உள்ள படங்கள், மீடியா, அறிவிப்புகள் ஆகியவற்றை அணுக உங்கள் <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> ஆப்ஸ் அனுமதியைக் கோருகிறது"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"இந்தச் செயலைச் செய்ய <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong&gt சாதனத்தை அனுமதிக்கவா?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"அருகிலுள்ள சாதனங்களுக்கு ஆப்ஸையும் பிற சிஸ்டம் அம்சங்களையும் ஸ்ட்ரீம் செய்ய உங்கள் <xliff:g id="DEVICE_NAME">%2$s</xliff:g> சார்பாக <xliff:g id="APP_NAME">%1$s</xliff:g> அனுமதி கோருகிறது"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"சாதனம்"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"இந்த ஆப்ஸால் தகவலை (அழைப்பவரின் பெயர் போன்றவை) உங்கள் மொபைலிலும் <xliff:g id="DEVICE_NAME">%1$s</xliff:g> சாதனத்திலும் ஒத்திசைக்க முடியும்."</string>
<string name="summary_generic" msgid="4988130802522924650">"இந்த ஆப்ஸால் தகவலை (அழைப்பவரின் பெயர் போன்றவை) உங்கள் மொபைலிலும் தேர்ந்தெடுக்கப்பட்ட சாதனத்திலும் ஒத்திசைக்க முடியும்."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"படங்கள் மற்றும் மீடியா"</string>
<string name="permission_notification" msgid="693762568127741203">"அறிவிப்புகள்"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ஆப்ஸ்"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"ஸ்ட்ரீமிங்"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"மொபைல் அழைப்புகளைச் செய்யலாம் நிர்வகிக்கலாம்"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"மொபைல் அழைப்புப் பதிவைப் படிக்கலாம் எழுதலாம்"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"மெசேஜ்களை அனுப்பலாம் பார்க்கலாம்"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"உங்கள் தொடர்புகளை அணுகலாம்"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"உங்கள் கேலெண்டரை அணுகலாம்"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ஆடியோவை ரெக்கார்டு செய்யலாம்"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"அருகிலுள்ள சாதனங்களைக் கண்டறியலாம் அவற்றுடன் இணையலாம் அவற்றின் தூரத்தைத் தீர்மானிக்கலாம்"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"தொடர்புகள், மெசேஜ்கள், படங்கள் போன்ற தகவல்கள் உட்பட அனைத்து அறிவிப்புகளையும் படிக்க முடியும்"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"உங்கள் மொபைல் ஆப்ஸை ஸ்ட்ரீம் செய்யலாம்"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"உங்கள் மொபைலில் இருந்து ஆப்ஸையும் பிற சிஸ்டம் அம்சங்களையும் ஸ்ட்ரீம் செய்யலாம்"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-te/strings.xml b/packages/CompanionDeviceManager/res/values-te/strings.xml
index 3b1e75e..5009407 100644
--- a/packages/CompanionDeviceManager/res/values-te/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-te/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> ద్వారా మేనేజ్ చేయబడటానికి ఒక <xliff:g id="PROFILE_NAME">%1$s</xliff:g>ను ఎంచుకోండి"</string>
<string name="summary_watch" msgid="6566922405914995759">"మీ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ను మేనేజ్ చేయడానికి ఈ యాప్ అవసరం. కాల్ చేస్తున్న వారి పేరు వంటి సమాచారాన్ని సింక్ చేయడానికి, మీ నోటిఫికేషన్లతో ఇంటరాక్ట్ అవ్వడానికి, అలాగే మీ ఫోన్, SMS, కాంటాక్ట్లు, క్యాలెండర్, కాల్ లాగ్లు, సమీపంలోని పరికరాల అనుమతులను యాక్సెస్ చేయడానికి <xliff:g id="APP_NAME">%2$s</xliff:g> అనుమతించబడుతుంది."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"మీ <xliff:g id="DEVICE_NAME">%1$s</xliff:g>ను మేనేజ్ చేయడానికి ఈ యాప్ అవసరం. కాల్ చేస్తున్న వారి పేరు వంటి సమాచారాన్ని సింక్ చేయడానికి, ఈ అనుమతులను యాక్సెస్ చేయడానికి <xliff:g id="APP_NAME">%2$s</xliff:g> అనుమతించబడుతుంది:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>ను మేనేజ్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>ను అనుమతించాలా?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"గ్లాసెస్"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ను మేనేజ్ చేయడానికి ఈ యాప్ అవసరం. మీ నోటిఫికేషన్లతో ఇంటరాక్ట్ అవ్వడానికి, అలాగే మీ ఫోన్, SMS, కాంటాక్ట్లు, మైక్రోఫోన్, సమీపంలోని పరికరాల అనుమతులను యాక్సెస్ చేయడానికి <xliff:g id="APP_NAME">%2$s</xliff:g> అనుమతించబడుతుంది."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"మీ ఫోన్లో ఈ అనుమతులను యాక్సెస్ చేయడానికి ఈ యాప్ అనుమతించబడుతుంది:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"మీ ఫోన్ నుండి ఈ సమాచారాన్ని యాక్సెస్ చేయడానికి <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> యాప్ను అనుమతించండి"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cross-device services"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"మీ పరికరాల మధ్య యాప్లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play సర్వీసులు"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> మీ ఫోన్లోని ఫోటోలను, మీడియాను, ఇంకా నోటిఫికేషన్లను యాక్సెస్ చేయడానికి మీ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"ఈ చర్యను అమలు చేయడానికి <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>ను అనుమతించాలా?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"సమీపంలోని పరికరాలకు యాప్లను, ఇతర సిస్టమ్ ఫీచర్లను స్ట్రీమ్ చేయడానికి <xliff:g id="APP_NAME">%1$s</xliff:g> మీ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> తరఫున అనుమతిని రిక్వెస్ట్ చేస్తోంది"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"పరికరం"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"కాల్ చేస్తున్న వారి పేరు వంటి సమాచారాన్ని ఈ యాప్ మీ ఫోన్, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> మధ్య సింక్ చేయగలుగుతుంది."</string>
<string name="summary_generic" msgid="4988130802522924650">"కాల్ చేస్తున్న వారి పేరు వంటి సమాచారాన్ని ఈ యాప్ మీ ఫోన్, ఎంచుకున్న పరికరం మధ్య సింక్ చేయగలుగుతుంది."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"ఫోటోలు, మీడియా"</string>
<string name="permission_notification" msgid="693762568127741203">"నోటిఫికేషన్లు"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"యాప్లు"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"స్ట్రీమింగ్"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"ఫోన్ కాల్స్ చేయగలదు, అలాగే మేనేజ్ చేయగలదు"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"ఫోన్ కాల్ లాగ్ను చదవగలదు, రాయగలదు"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS మెసేజ్లను పంపగలదు, అలాగే చూడగలదు"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"మీ కాంటాక్ట్లను యాక్సెస్ చేయగలదు"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"మీ క్యాలెండర్ను యాక్సెస్ చేయగలదు"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"ఆడియోను రికార్డ్ చేయగలదు"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"సమీపంలోని పరికరాలను కనుగొనగలదు, వాటికి కనెక్ట్ అవ్వగలదు, అవి ఎంత దూరంలో ఉన్నాయో తెలుసుకొనగలదు"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"కాంటాక్ట్లు, మెసేజ్లు, ఫోటోల వంటి సమాచారంతో సహా అన్ని నోటిఫికేషన్లను చదవగలదు"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"మీ ఫోన్లోని యాప్లను స్ట్రీమ్ చేయండి"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"మీ ఫోన్ నుండి యాప్లను, ఇతర సిస్టమ్ ఫీచర్లను స్ట్రీమ్ చేస్తుంది"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-th/strings.xml b/packages/CompanionDeviceManager/res/values-th/strings.xml
index abf7ac8..e53f70c 100644
--- a/packages/CompanionDeviceManager/res/values-th/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-th/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"เลือก<xliff:g id="PROFILE_NAME">%1$s</xliff:g>ที่จะให้มีการจัดการโดย <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"ต้องใช้แอปนี้ในการจัดการ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$s</xliff:g> จะได้รับอนุญาตให้ซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา โต้ตอบกับการแจ้งเตือน รวมถึงมีสิทธิ์เข้าถึงโทรศัพท์, SMS, รายชื่อติดต่อ, ปฏิทิน, บันทึกการโทร และอุปกรณ์ที่อยู่ใกล้เคียง"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"ต้องใช้แอปนี้ในการจัดการ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$s</xliff:g> จะได้รับอนุญาตให้ซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา และมีสิทธิ์เข้าถึงสิ่งต่างๆ ต่อไปนี้"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> จัดการ <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> ไหม"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"แว่นตา"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"ต้องใช้แอปนี้ในการจัดการ<xliff:g id="DEVICE_NAME">%1$s</xliff:g> <xliff:g id="APP_NAME">%2$s</xliff:g> จะได้รับอนุญาตให้โต้ตอบกับการแจ้งเตือนและมีสิทธิ์เข้าถึงโทรศัพท์, SMS, รายชื่อติดต่อ, ไมโครโฟน และอุปกรณ์ที่อยู่ใกล้เคียง"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"แอปนี้จะได้รับสิทธิ์ดังต่อไปนี้ในโทรศัพท์ของคุณ"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"อนุญาตให้ <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> เข้าถึงข้อมูลนี้จากโทรศัพท์ของคุณ"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"บริการหลายอุปกรณ์"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อสตรีมแอประหว่างอุปกรณ์ต่างๆ ของคุณ"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"บริการ Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> เพื่อเข้าถึงรูปภาพ สื่อ และการแจ้งเตือนในโทรศัพท์ของคุณ"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"อนุญาตให้ <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ทำงานนี้ไหม"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> กำลังขอสิทธิ์ในนามของ <xliff:g id="DEVICE_NAME">%2$s</xliff:g> เพื่อสตรีมแอปและฟีเจอร์อื่นๆ ของระบบไปยังอุปกรณ์ที่อยู่ใกล้เคียง"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"อุปกรณ์"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"แอปนี้จะสามารถซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา ระหว่างโทรศัพท์ของคุณและ<xliff:g id="DEVICE_NAME">%1$s</xliff:g>ได้"</string>
<string name="summary_generic" msgid="4988130802522924650">"แอปนี้จะสามารถซิงค์ข้อมูล เช่น ชื่อของบุคคลที่โทรเข้ามา ระหว่างโทรศัพท์ของคุณและอุปกรณ์ที่เลือกไว้ได้"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"รูปภาพและสื่อ"</string>
<string name="permission_notification" msgid="693762568127741203">"การแจ้งเตือน"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"แอป"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"สตรีมมิง"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"สามารถโทรออกและจัดการการโทร"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"สามารถอ่านและเขียนบันทึกการโทรของโทรศัพท์"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"สามารถส่งและดูข้อความ SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"สามารถเข้าถึงรายชื่อติดต่อของคุณ"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"สามารถเข้าถึงปฏิทินของคุณ"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"บันทึกเสียงได้"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"สามารถค้นหา เชื่อมต่อ และระบุตำแหน่งซึ่งสัมพันธ์กับอุปกรณ์ที่อยู่ใกล้เคียง"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"สามารถอ่านการแจ้งเตือนทั้งหมด รวมถึงข้อมูลอย่างรายชื่อติดต่อ ข้อความ และรูปภาพ"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"สตรีมแอปของโทรศัพท์คุณ"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"สตรีมแอปและฟีเจอร์อื่นๆ ของระบบจากโทรศัพท์"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-tl/strings.xml b/packages/CompanionDeviceManager/res/values-tl/strings.xml
index 717ce38..4195c6d 100644
--- a/packages/CompanionDeviceManager/res/values-tl/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tl/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Pumili ng <xliff:g id="PROFILE_NAME">%1$s</xliff:g> para pamahalaan ng <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Kailangan ang app para mapamahalaan ang iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Papayagan ang <xliff:g id="APP_NAME">%2$s</xliff:g> na mag-sync ng impormasyon, tulad ng pangalan ng isang taong tumatawag, makipag-ugnayan sa mga notification mo, at ma-access ang iyong mga pahintulot sa Telepono, SMS, Mga Contact, Kalendaryo, Mga log ng tawag, at Mga kalapit na device."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Kailangan ang app para mapamahalaan ang iyong <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Papayagan ang <xliff:g id="APP_NAME">%2$s</xliff:g> na mag-sync ng impormasyon, tulad ng pangalan ng isang taong tumatawag, at na ma-access ang mga pahintulot na ito:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na pamahalaan ang <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"salamin"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Kailangan ang app na ito para mapamahalaan ang <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. Papayagan ang <xliff:g id="APP_NAME">%2$s</xliff:g> na makipag-ugnayan sa mga notification mo at i-access ang iyong mga pahintulot sa Telepono, SMS, Mga Contact, Mikropono, at Mga kalapit na device."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Papayagan ang app na ito na i-access ang mga pahintulot na ito sa iyong telepono:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Payagan ang <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> na i-access ang impormasyong ito sa iyong telepono"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Mga cross-device na serbisyo"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para mag-stream ng mga app sa pagitan ng mga device mo"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Mga serbisyo ng Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Ang <xliff:g id="APP_NAME">%1$s</xliff:g> ay humihiling ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> para i-access ang mga larawan, media, at notification ng telepono mo"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Payagan ang <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> na gawin ang pagkilos na ito?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Humihiling ang <xliff:g id="APP_NAME">%1$s</xliff:g> ng pahintulot sa ngalan ng iyong <xliff:g id="DEVICE_NAME">%2$s</xliff:g> para mag-stream ng mga app at iba pang feature ng system sa mga kalapit na device"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"device"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Magagawa ng app na ito na mag-sync ng impormasyon, tulad ng pangalan ng isang taong tumatawag, sa pagitan ng iyong telepono at ng <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Magagawa ng app na ito na mag-sync ng impormasyon, tulad ng pangalan ng isang taong tumatawag, sa pagitan ng iyong telepono at ng napiling device."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Mga larawan at media"</string>
<string name="permission_notification" msgid="693762568127741203">"Mga Notification"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Mga App"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Streaming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Puwedeng gumawa at mamahala ng mga tawag sa telepono"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Puwedeng magbasa at magsulat ng log ng tawag sa telepono"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Puwedeng magpadala at tumingin ng mga SMS message"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Puwedeng mag-access ng iyong mga contact"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Puwedeng mag-access ng iyong kalendaryo"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Kayang mag-record ng audio"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Puwedeng mahanap ang, kumonekta sa, at tukuyin ang relatibong posisyon ng mga kalapit na device"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Magbasa ng lahat ng notification, kabilang ang impormasyon gaya ng mga contact, mensahe, at larawan"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"I-stream ang mga app ng iyong telepono"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Mag-stream ng mga app at iba pang feature ng system mula sa iyong telepono"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-tr/strings.xml b/packages/CompanionDeviceManager/res/values-tr/strings.xml
index 533e1f9..d90fd33 100644
--- a/packages/CompanionDeviceManager/res/values-tr/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-tr/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> tarafından yönetilecek bir <xliff:g id="PROFILE_NAME">%1$s</xliff:g> seçin"</string>
<string name="summary_watch" msgid="6566922405914995759">"Bu uygulama, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızın yönetilmesi için gereklidir. <xliff:g id="APP_NAME">%2$s</xliff:g> adlı uygulamanın arayan kişinin adı gibi bilgileri senkronize etmesine, bildirimlerinizle etkileşimde bulunup Telefon, SMS, Kişiler, Takvim, Arama kayıtları ve Yakındaki cihazlar izinlerine erişmesine izin verilir."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Bu uygulama, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazınızın yönetilmesi için gereklidir. <xliff:g id="APP_NAME">%2$s</xliff:g> adlı uygulamanın arayan kişinin adı gibi bilgileri senkronize etmesine ve aşağıdaki izinlere erişmesine izin verilir:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasına <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> cihazını yönetmesi için izin verilsin mi?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"glasses"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Bu uygulama, <xliff:g id="DEVICE_NAME">%1$s</xliff:g> cihazının yönetilmesi için gereklidir. <xliff:g id="APP_NAME">%2$s</xliff:g> adlı uygulamanın bildirimlerinizle etkileşimde bulunup Telefon, SMS, Kişiler, Mikrofon ve Yakındaki cihazlar izinlerine erişmesine izin verilir."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Bu uygulamanın telefonunuzda şu izinlere erişmesine izin verilecek:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> uygulamasının, telefonunuzdaki bu bilgilere erişmesine izin verin"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Cihazlar arası hizmetler"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g>, cihazlarınız arasında uygulama akışı gerçekleştirmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play hizmetleri"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g>, telefonunuzdaki fotoğraf, medya ve bildirimlere erişmek için <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> cihazınız adına izin istiyor"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> cihazının bu işlem yapmasına izin verilsin mi?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> uygulaması <xliff:g id="DEVICE_NAME">%2$s</xliff:g> cihazınız adına uygulamaları ve diğer sistem özelliklerini yakındaki cihazlara aktarmak için izin istiyor"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"cihaz"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Bu uygulama, arayan kişinin adı gibi bilgileri telefonunuz ve <xliff:g id="DEVICE_NAME">%1$s</xliff:g> adlı cihaz arasında senkronize edebilir."</string>
<string name="summary_generic" msgid="4988130802522924650">"Bu uygulama, arayan kişinin adı gibi bilgileri telefonunuz ve seçili cihaz arasında senkronize edebilir."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Fotoğraflar ve medya"</string>
<string name="permission_notification" msgid="693762568127741203">"Bildirimler"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Uygulamalar"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Yayınlama"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Telefon aramaları yapabilir ve telefon aramalarını yönetebilir"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Telefon arama kaydını okuma ve yazma"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS mesajları gönderebilir ve görüntüleyebilir"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Kişilerinize erişebilir"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Takviminize erişebilir"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Ses kaydedebilir"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Yakındaki cihazları keşfedip bağlanabilir ve bu cihazların göreli konumunu belirleyebilir"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Kişiler, mesajlar ve fotoğraflar da dahil olmak üzere tüm bildirimleri okuyabilir"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Telefonunuzun uygulamalarını yayınlama"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Telefonunuzdan uygulamaları ve diğer sistem özelliklerini yayınlayın"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uk/strings.xml b/packages/CompanionDeviceManager/res/values-uk/strings.xml
index 01029ae..9af7f46 100644
--- a/packages/CompanionDeviceManager/res/values-uk/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uk/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Виберіть <xliff:g id="PROFILE_NAME">%1$s</xliff:g>, яким керуватиме додаток <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"Цей додаток потрібен, щоб керувати пристроєм \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Додаток <xliff:g id="APP_NAME">%2$s</xliff:g> зможе синхронізувати інформацію (наприклад, ім’я абонента, який викликає), взаємодіяти з вашими сповіщеннями й отримає дозволи \"Телефон\", \"SMS\", \"Контакти\", \"Календар\", \"Журнали викликів\" і \"Пристрої поблизу\"."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Цей додаток потрібен, щоб керувати пристроєм \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Додаток <xliff:g id="APP_NAME">%2$s</xliff:g> зможе синхронізувати інформацію (наприклад, ім’я абонента, який викликає) і отримає такі дозволи:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Дозволити додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> керувати пристроєм <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"окуляри"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Цей додаток потрібен, щоб керувати пристроєм \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\". Додаток <xliff:g id="APP_NAME">%2$s</xliff:g> зможе взаємодіяти з вашими сповіщеннями й отримає дозволи \"Телефон\", \"SMS\", \"Контакти\", \"Мікрофон\" і \"Пристрої поблизу\"."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Цей додаток матиме доступ до таких дозволів на вашому телефоні:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Надайте додатку <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> доступ до цієї інформації з телефона"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Сервіси для кількох пристроїв"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на трансляцію додатків між вашими пристроями"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Сервіси Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> запитує дозвіл на доступ до фотографій, медіафайлів і сповіщень вашого телефона"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Дозволити додатку <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> виконувати цю дію?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"Додаток <xliff:g id="APP_NAME">%1$s</xliff:g> від імені вашого пристрою (<xliff:g id="DEVICE_NAME">%2$s</xliff:g>) запитує дозвіл на трансляцію додатків та інших системних функцій на пристрої поблизу"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"пристрій"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Цей додаток зможе синхронізувати інформацію (наприклад, ім’я абонента, який викликає) між телефоном і пристроєм \"<xliff:g id="DEVICE_NAME">%1$s</xliff:g>\"."</string>
<string name="summary_generic" msgid="4988130802522924650">"Цей додаток зможе синхронізувати інформацію (наприклад, ім’я абонента, який викликає) між телефоном і вибраним пристроєм."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Фотографії та медіафайли"</string>
<string name="permission_notification" msgid="693762568127741203">"Сповіщення"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Додатки"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Потокове передавання"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Може здійснювати телефонні виклики й керувати ними"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Може переглядати й редагувати журнал викликів телефона"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Може надсилати й переглядати SMS-повідомлення"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Має доступ до ваших контактів"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Має доступ до вашого календаря"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Може записувати аудіо"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Може знаходити пристрої поблизу, підключатися до них і визначати їх відносне розташування"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Може читати всі сповіщення, зокрема таку інформацію, як контакти, повідомлення та фотографії"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Транслювати додатки телефона"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Транслюйте додатки й інші системні функції зі свого телефона"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-ur/strings.xml b/packages/CompanionDeviceManager/res/values-ur/strings.xml
index a65cb66..148ffab 100644
--- a/packages/CompanionDeviceManager/res/values-ur/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-ur/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> کے ذریعے نظم کئے جانے کیلئے <xliff:g id="PROFILE_NAME">%1$s</xliff:g> کو منتخب کریں"</string>
<string name="summary_watch" msgid="6566922405914995759">"آپ کے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> کا نظم کرنے کے لیے، ایپ کی ضرورت ہے۔ <xliff:g id="APP_NAME">%2$s</xliff:g> کو کسی کے کال کرنے والے کے نام، آپ کی اطلاعات کے ساتھ تعامل، آپ کے فون، SMS، رابطے، کیلنڈر، کال لاگز اور قریبی آلات کی اجازتوں جیسی معلومات کی مطابقت پذیری کی اجازت ہوگی۔"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"آپ کے <xliff:g id="DEVICE_NAME">%1$s</xliff:g> کا نظم کرنے کے لیے، ایپ کی ضرورت ہے۔ <xliff:g id="APP_NAME">%2$s</xliff:g> کو کسی کال کرنے والے کے نام اور ان اجازتوں تک رسائی جیسی معلومات کی مطابقت پذیری کی اجازت ہوگی:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> کا نظم کرنے کی اجازت دیں؟"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"گلاسز"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> کا نظم کرنے کے لیے، اس ایپ کی ضرورت ہے۔ <xliff:g id="APP_NAME">%2$s</xliff:g> کو آپ کی اطلاعات کے ساتھ تعامل کرنے اور آپ کے فون، SMS، رابطوں، مائیکروفون اور قریبی آلات کی اجازتوں تک رسائی کی اجازت ہوگی۔"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"اس ایپ کو آپ کے فون پر ان اجازتوں تک رسائی کرنے کی اجازت ہوگی:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"اپنے فون سے ان معلومات تک رسائی حاصل کرنے کی <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> کو اجازت دیں"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"کراس ڈیوائس سروسز"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے آلات کے درمیان ایپس کی سلسلہ بندی کرنے کی اجازت کی درخواست کر رہی ہے"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play سروسز"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> ایپ آپ کے <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> کی جانب سے آپ کے فون کی تصاویر، میڈیا اور اطلاعات تک رسائی کی اجازت طلب کر رہی ہے"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> کو یہ کارروائی انجام دینے کی اجازت دیں؟"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> آپ کے <xliff:g id="DEVICE_NAME">%2$s</xliff:g> کی جانب سے ایپس اور سسٹم کی دیگر خصوصیات کی سلسلہ بندی قریبی آلات پر کرنے کی اجازت طلب کر رہی ہے"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"آلہ"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"یہ ایپ آپ کے فون اور <xliff:g id="DEVICE_NAME">%1$s</xliff:g> کے درمیان معلومات، جیسے کسی کال کرنے والے کے نام، کی مطابقت پذیری کر سکے گی۔"</string>
<string name="summary_generic" msgid="4988130802522924650">"یہ ایپ آپ کے فون اور منتخب کردہ آلے کے درمیان معلومات، جیسے کسی کال کرنے والے کے نام، کی مطابقت پذیری کر سکے گی۔"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"تصاویر اور میڈیا"</string>
<string name="permission_notification" msgid="693762568127741203">"اطلاعات"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"ایپس"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"سلسلہ بندی"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"فون کالز کر سکتا ہے اور ان کا نظم کر سکتا ہے"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"فون کال لاگ پڑھ کر لکھ سکتا ہے"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS پیغامات بھیج اور دیکھ سکتا ہے"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"آپ کے رابطوں تک رسائی حاصل کر سکتا ہے"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"آپ کے کیلنڈر تک رسائی حاصل کر سکتا ہے"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"آڈیو ریکارڈ کر سکتی ہے"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"قریبی آلات کی متعلقہ پوزیشن تلاش کر سکتا ہے، ان سے منسلک ہو سکتا ہے اور اس کا تعین کر سکتا ہے"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"رابطوں، پیغامات اور تصاویر جیسی معلومات سمیت تمام اطلاعات پڑھ سکتے ہیں"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"اپنے فون کی ایپس کی سلسلہ بندی کریں"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"اپنے فون سے ایپس اور سسٹم کی دیگر خصوصیات کی سلسلہ بندی کریں"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-uz/strings.xml b/packages/CompanionDeviceManager/res/values-uz/strings.xml
index 76f8e18..0b66e4f 100644
--- a/packages/CompanionDeviceManager/res/values-uz/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-uz/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> boshqaradigan <xliff:g id="PROFILE_NAME">%1$s</xliff:g> qurilmasini tanlang"</string>
<string name="summary_watch" msgid="6566922405914995759">"Ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmangizni boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga chaqiruvchining ismi, bildirishnomalar bilan ishlash va telefon, SMS, kontaktlar, taqvim, chaqiruvlar jurnali va yaqin-atrofdagi qurilmalarni aniqlash kabi maʼlumotlarni sinxronlashga ruxsat beriladi."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmangizni boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga chaqiruvchining ismi kabi maʼlumotlarni sinxronlash va quyidagi amallarni bajarishga ruxsat beriladi:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong> qurilmasini boshqarish uchun ruxsat berilsinmi?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"koʻzoynak"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Bu ilova <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasini boshqarish uchun kerak. <xliff:g id="APP_NAME">%2$s</xliff:g> ilovasiga bildirishnomalar bilan ishlash va telefon, SMS, kontaktlar, mikrofon va yaqin-atrofdagi qurilmalarga kirishga ruxsat beriladi."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Bu ilova telefonda quyidagi ruxsatlarni oladi:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ilovasiga telefondagi ushbu maʼlumot uchun ruxsat bering"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Qurilmalararo xizmatlar"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"Qurilamalararo ilovalar strimingi uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play xizmatlari"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"Telefoningizdagi rasm, media va bildirishnomalarga kirish uchun <xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> nomidan ruxsat soʻramoqda"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> ilovasiga bu amalni bajarish uchun ruxsat berilsinmi?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> ilovasi <xliff:g id="DEVICE_NAME">%2$s</xliff:g> qurilmangizdan nomidan atrofdagi qurilmalarga ilova va boshqa tizim funksiyalarini uzatish uchun ruxsat olmoqchi"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"qurilma"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Bu ilova telefoningiz va <xliff:g id="DEVICE_NAME">%1$s</xliff:g> qurilmasida chaqiruvchining ismi kabi maʼlumotlarni sinxronlay oladi."</string>
<string name="summary_generic" msgid="4988130802522924650">"Bu ilova telefoningiz va tanlangan qurilmada chaqiruvchining ismi kabi maʼlumotlarni sinxronlay oladi."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Suratlar va media"</string>
<string name="permission_notification" msgid="693762568127741203">"Bildirishnomalar"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Ilovalar"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Striming"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Telefon chaqiruvlarini bajarishi va boshqarishi mumkin"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Telefon chaqiruvlari jurnalini koʻrishi va oʻzgartirishi mumkin"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"SMS xabarlarni koʻrishi va yuborishi mumkin"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Kontaktlarga ruxsati bor"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Taqvimga ruxsati bor"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Audio yozib olish mumkin"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Atrofdagi qurilmalarni qidirishi, joylashuvini aniqlashi va ularga ulanishi mumkin"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Barcha bildirishnomalarni, jumladan, kontaktlar, xabarlar va suratlarni oʻqishi mumkin"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Telefondagi ilovalarni translatsiya qilish"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Telefoningizdan ilovalar va tizim funksiyalarini translatsiya qilish"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-vi/strings.xml b/packages/CompanionDeviceManager/res/values-vi/strings.xml
index 4abe51e..c2f9669 100644
--- a/packages/CompanionDeviceManager/res/values-vi/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-vi/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Chọn một <xliff:g id="PROFILE_NAME">%1$s</xliff:g> sẽ do <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> quản lý"</string>
<string name="summary_watch" msgid="6566922405914995759">"Cần có ứng dụng này để quản lý <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn. <xliff:g id="APP_NAME">%2$s</xliff:g> sẽ được phép đồng bộ hoá thông tin (ví dụ: tên người gọi), tương tác với thông báo của bạn cũng như truy cập vào dữ liệu Điện thoại, SMS, Danh bạ, Lịch, Nhật ký cuộc gọi và Thiết bị ở gần."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"Cần có ứng dụng này để quản lý <xliff:g id="DEVICE_NAME">%1$s</xliff:g> của bạn. <xliff:g id="APP_NAME">%2$s</xliff:g> sẽ được phép đồng bộ hoá thông tin (ví dụ: tên người gọi) và có các quyền sau:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> quản lý <strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"kính"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Bạn cần có ứng dụng này để quản lý <xliff:g id="DEVICE_NAME">%1$s</xliff:g>. <xliff:g id="APP_NAME">%2$s</xliff:g> sẽ được phép tương tác với thông báo của bạn, cũng như sử dụng các quyền đối với Điện thoại, SMS, Danh bạ, Micrô và Thiết bị ở gần."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Ứng dụng này sẽ được phép sử dụng những quyền sau trên điện thoại của bạn:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Cho phép <strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> truy cập vào thông tin này trên điện thoại của bạn"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Dịch vụ trên nhiều thiết bị"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truyền trực tuyến ứng dụng giữa các thiết bị của bạn"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Dịch vụ Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang yêu cầu quyền thay cho <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> để truy cập vào ảnh, nội dung nghe nhìn và thông báo trên điện thoại của bạn."</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Cho phép <strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong> thực hiện hành động này?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"<xliff:g id="APP_NAME">%1$s</xliff:g> đang thay <xliff:g id="DEVICE_NAME">%2$s</xliff:g> yêu cầu quyền truyền trực tuyến ứng dụng và các tính năng khác của hệ thống đến các thiết bị ở gần"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"thiết bị"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Ứng dụng này sẽ đồng bộ hoá được thông tin (ví dụ: tên người gọi) giữa điện thoại của bạn và <xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Ứng dụng này sẽ đồng bộ hoá được thông tin (ví dụ: tên người gọi) giữa điện thoại của bạn và thiết bị bạn chọn."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Ảnh và nội dung nghe nhìn"</string>
<string name="permission_notification" msgid="693762568127741203">"Thông báo"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Ứng dụng"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Truyền trực tuyến"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Có thể thực hiện và quản lý các cuộc gọi điện thoại"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Có thể đọc và ghi nhật ký cuộc gọi điện thoại"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Có thể gửi và xem tin nhắn SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Có thể truy cập danh bạ"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Có thể truy cập lịch"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Có thể ghi âm"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Có thể tìm, kết nối và xác định vị trí tương đối của các thiết bị ở gần"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Có thể đọc tất cả các thông báo, kể cả những thông tin như danh bạ, tin nhắn và ảnh"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Truyền các ứng dụng trên điện thoại của bạn"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Truyền trực tuyến ứng dụng và các tính năng khác của hệ thống từ điện thoại của bạn"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
index 30b89e8..e3a90cd8 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rCN/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"选择要由<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="summary_watch" msgid="6566922405914995759">"需要使用此应用才能管理您的“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”。<xliff:g id="APP_NAME">%2$s</xliff:g>将能同步信息(例如来电者的姓名),与通知交互,并可获得电话、短信、通讯录、日历、通话记录和附近设备的访问权限。"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"需要使用此应用才能管理您的“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”。<xliff:g id="APP_NAME">%2$s</xliff:g>将能同步信息(例如来电者的姓名),并可使用以下权限:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"允许<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong>管理<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"眼镜"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"需要使用此应用才能管理<xliff:g id="DEVICE_NAME">%1$s</xliff:g>。“<xliff:g id="APP_NAME">%2$s</xliff:g>”将能与通知交互,并可获得电话、短信、通讯录、麦克风和附近设备的访问权限。"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"该应用将可以获得您手机上的以下权限:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允许“<xliff:g id="APP_NAME">%1$s</xliff:g>”<strong></strong>访问您手机中的这项信息"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨设备服务"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求在您的设备之间流式传输应用内容"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服务"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>请求访问您手机上的照片、媒体内容和通知"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"允许<strong><xliff:g id="DEVICE_NAME">%1$s</xliff:g></strong>进行此操作?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"“<xliff:g id="APP_NAME">%1$s</xliff:g>”正代表您的<xliff:g id="DEVICE_NAME">%2$s</xliff:g>请求将应用和其他系统功能流式传输到附近的设备"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"设备"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"此应用将能够在您的手机和“<xliff:g id="DEVICE_NAME">%1$s</xliff:g>”之间同步信息,例如来电者的姓名。"</string>
<string name="summary_generic" msgid="4988130802522924650">"此应用将能够在您的手机和所选设备之间同步信息,例如来电者的姓名。"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"照片和媒体内容"</string>
<string name="permission_notification" msgid="693762568127741203">"通知"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"应用"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"流式传输"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"可以打电话及管理通话"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"可以读取和写入手机通话记录"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"可以发送和查看短信"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"可以访问您的通讯录"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"可以访问您的日历"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"可以录制音频"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"可以查找、连接附近的设备以及确定附近设备的相对位置"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"可以读取所有通知,包括合同、消息和照片等信息"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"流式传输手机上的应用"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"从您的手机流式传输应用和其他系统功能"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
index 23301b5..66d833d 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rHK/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"選擇由 <strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong> 管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="summary_watch" msgid="6566922405914995759">"必須使用此應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可同步資訊 (例如來電者的名稱)、透過通知與您互動,並存取電話、短訊、通訊錄、日曆、通話記錄和附近的裝置權限。"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"必須使用此應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可同步資訊 (例如來電者的名稱),並存取以下權限:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>管理「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>嗎?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"眼鏡"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"必須使用此應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可透過通知與您互動,並存取電話、短訊、通訊錄、麥克風和附近的裝置權限。"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"此應用程式將可在手機上取得以下權限:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取您手機中的這項資料"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在為 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求權限,以在裝置之間串流應用程式內容"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表 <xliff:g id="DEVICE_TYPE">%2$s</xliff:g> 要求權限,以便存取手機上的相片、媒體和通知"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"要允許「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」<strong></strong>執行此操作嗎?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」要求權限,才能在附近的裝置上串流播放應用程式和其他系統功能"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"此應用程式將可同步手機和「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」的資訊,例如來電者的名稱。"</string>
<string name="summary_generic" msgid="4988130802522924650">"此應用程式將可同步手機和所選裝置的資訊,例如來電者的名稱。"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
<string name="permission_notification" msgid="693762568127741203">"通知"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"應用程式"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"串流"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"可撥打電話和管理通話"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"可讀取及寫入手機通話記錄"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"可傳送及查看短訊"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"可存取通訊錄"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"可存取日曆"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"可以錄音"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"可尋找、連接及判斷附近裝置的相對位置"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"可以讀取所有通知,包括聯絡人、訊息和電話等資訊"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"串流播放手機應用程式內容"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"串流播放手機中的應用程式和其他系統功能"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
index ccc50d9..c0ce419 100644
--- a/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zh-rTW/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"選擇要讓「<xliff:g id="APP_NAME">%2$s</xliff:g>」<strong></strong>管理的<xliff:g id="PROFILE_NAME">%1$s</xliff:g>"</string>
<string name="summary_watch" msgid="6566922405914995759">"你必須使用這個應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可同步資訊 (例如來電者名稱)、存取通知及在通知上執行操作,並取得電話、簡訊、聯絡人、日曆、通話記錄、麥克風和鄰近裝置權限。"</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"你必須使用這個應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可同步資訊 (例如來電者名稱),並取得以下權限:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"要允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>管理「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」<strong></strong>嗎?"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"眼鏡"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"你必須使用這個應用程式,才能管理「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」。「<xliff:g id="APP_NAME">%2$s</xliff:g>」將可存取通知及在通知上執行操作,並取得電話、簡訊、聯絡人、麥克風和鄰近裝置權限。"</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"這個應用程式將可在手機上取得以下權限:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"允許「<xliff:g id="APP_NAME">%1$s</xliff:g>」<strong></strong>存取手機中的這項資訊"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"跨裝置服務"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便在裝置之間串流傳輸應用程式內容"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Google Play 服務"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表你的「<xliff:g id="DEVICE_TYPE">%2$s</xliff:g>」要求必要權限,以便存取手機上的相片、媒體和通知"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"要允許「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」<strong></strong>執行這項操作嗎?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"「<xliff:g id="APP_NAME">%1$s</xliff:g>」正在代表「<xliff:g id="DEVICE_NAME">%2$s</xliff:g>」要求必要權限,才能在鄰近裝置上串流播放應用程式和其他系統功能"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"裝置"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"這個應用程式將可在手機和「<xliff:g id="DEVICE_NAME">%1$s</xliff:g>」之間同步資訊,例如來電者名稱。"</string>
<string name="summary_generic" msgid="4988130802522924650">"這個應用程式將可在手機和指定裝置之間同步資訊,例如來電者名稱。"</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"相片和媒體"</string>
<string name="permission_notification" msgid="693762568127741203">"通知"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"應用程式"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"串流"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"可撥打及管理通話"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"可讀取及寫入通話記錄"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"可傳送及查看簡訊"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"可存取聯絡人"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"可存取日曆"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"可以錄音"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"可尋找、連線及判斷鄰近裝置的相對位置"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"可讀取所有通知,包括聯絡人、訊息和電話等資訊"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"串流傳輸手機應用程式內容"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"串流播放手機中的應用程式和其他系統功能"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values-zu/strings.xml b/packages/CompanionDeviceManager/res/values-zu/strings.xml
index 6ccfd97..39b458c 100644
--- a/packages/CompanionDeviceManager/res/values-zu/strings.xml
+++ b/packages/CompanionDeviceManager/res/values-zu/strings.xml
@@ -22,13 +22,10 @@
<string name="chooser_title" msgid="2262294130493605839">"Khetha i-<xliff:g id="PROFILE_NAME">%1$s</xliff:g> ezophathwa yi-<strong><xliff:g id="APP_NAME">%2$s</xliff:g></strong>"</string>
<string name="summary_watch" msgid="6566922405914995759">"I-app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, ukusebenzisana nezaziso zakho futhi ufinyelele Ifoni yakho, i-SMS, Oxhumana Nabo, Ikhalenda, Amarekhodi Amakholi nezimvume zamadivayisi aseduze."</string>
<string name="summary_watch_single_device" msgid="7443464525873186735">"I-app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> yakho. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, futhi ufinyelele lezi zimvume:"</string>
- <!-- no translation found for confirmation_title_glasses (8288346850537727333) -->
- <skip />
+ <string name="confirmation_title_glasses" msgid="8288346850537727333">"Vumela i-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ukuthi ifinyelele i-<strong><xliff:g id="DEVICE_NAME">%2$s</xliff:g></strong>"</string>
<string name="profile_name_glasses" msgid="8488394059007275998">"Izingilazi"</string>
- <!-- no translation found for summary_glasses_multi_device (615259525961937348) -->
- <skip />
- <!-- no translation found for summary_glasses_single_device (5783761806783565716) -->
- <skip />
+ <string name="summary_glasses_multi_device" msgid="615259525961937348">"Le app iyadingeka ukuphatha i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>. I-<xliff:g id="APP_NAME">%2$s</xliff:g> izovunyelwa ukuthi ihlanganyele nezaziso zakho futhi ifinyelele kufoni yakho, i-SMS, Oxhumana nabo, Imakrofoni Nezimvume zamadivayisi aseduze."</string>
+ <string name="summary_glasses_single_device" msgid="5783761806783565716">"Le-app izovunyelwa ukufinyelela lezi zimvume kufoni yakho:"</string>
<string name="title_app_streaming" msgid="2270331024626446950">"Vumela i-<strong><xliff:g id="APP_NAME">%1$s</xliff:g></strong> ifinyelele lolu lwazi kusukela efonini yakho"</string>
<string name="helper_title_app_streaming" msgid="4151687003439969765">"Amasevisi amadivayisi amaningi"</string>
<string name="helper_summary_app_streaming" msgid="5977509499890099">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze isakaze-bukhoma ama-app phakathi kwamadivayisi akho"</string>
@@ -38,10 +35,8 @@
<string name="summary_computer" msgid="3798467601598297062"></string>
<string name="helper_title_computer" msgid="4671071173916176037">"Amasevisi we-Google Play"</string>
<string name="helper_summary_computer" msgid="9050724687678157852">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_TYPE">%2$s</xliff:g> yakho ukuze ifinyelele izithombe zefoni yakho, imidiya nezaziso"</string>
- <!-- no translation found for title_nearby_device_streaming (7269956847378799794) -->
- <skip />
- <!-- no translation found for helper_summary_nearby_device_streaming (2063965070936844876) -->
- <skip />
+ <string name="title_nearby_device_streaming" msgid="7269956847378799794">"Vumela i-<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ukwenza lesi senzo?"</string>
+ <string name="helper_summary_nearby_device_streaming" msgid="2063965070936844876">"I-<xliff:g id="APP_NAME">%1$s</xliff:g> icela imvume esikhundleni se-<xliff:g id="DEVICE_NAME">%2$s</xliff:g> ukusakaza ama-app nezinye izakhi zesistimu kumadivayisi aseduze"</string>
<string name="profile_name_generic" msgid="6851028682723034988">"idivayisi"</string>
<string name="summary_generic_single_device" msgid="4735072202474939111">"Le app izokwazi ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, phakathi kwefoni yakho ne-<xliff:g id="DEVICE_NAME">%1$s</xliff:g>."</string>
<string name="summary_generic" msgid="4988130802522924650">"Le app izokwazi ukuvumelanisa ulwazi, njengegama lomuntu othile ofonayo, phakathi kwefoni yakho nedivayisi ekhethiwe."</string>
@@ -62,19 +57,16 @@
<string name="permission_storage" msgid="6831099350839392343">"Izithombe nemidiya"</string>
<string name="permission_notification" msgid="693762568127741203">"Izaziso"</string>
<string name="permission_app_streaming" msgid="6009695219091526422">"Ama-app"</string>
- <!-- no translation found for permission_nearby_device_streaming (1023325519477349499) -->
- <skip />
+ <string name="permission_nearby_device_streaming" msgid="1023325519477349499">"Iyasakaza"</string>
<string name="permission_phone_summary" msgid="6684396967861278044">"Ingenza futhi iphathe amakholi wefoni"</string>
<string name="permission_call_logs_summary" msgid="6186103394658755022">"Ingafunda futhi ibhale irekhodi lamakholi efoni"</string>
<string name="permission_sms_summary" msgid="3508442683678912017">"Ingathumela futhi ibuke imiyalezo ye-SMS"</string>
<string name="permission_contacts_summary" msgid="675861979475628708">"Ingakwazi ukufinyelela oxhumana nabo"</string>
<string name="permission_calendar_summary" msgid="6460000922511766226">"Ingakwazi ukufinyelela ikhalenda lakho"</string>
- <!-- no translation found for permission_microphone_summary (3692091540613093394) -->
- <skip />
+ <string name="permission_microphone_summary" msgid="3692091540613093394">"Ingakwazi ukurekhoda umsindo"</string>
<string name="permission_nearby_devices_summary" msgid="931940524460876655">"Ingathola, ixhume, futhi inqume indawo ehlobene yamadivayisi aseduze"</string>
<string name="permission_notification_summary" msgid="884075314530071011">"Ingafunda zonke izaziso, okubandakanya ulwazi olufana noxhumana nabo, imilayezo, nezithombe"</string>
<string name="permission_app_streaming_summary" msgid="606923325679670624">"Sakaza ama-app wefoni yakho"</string>
<string name="permission_storage_summary" msgid="3918240895519506417"></string>
- <!-- no translation found for permission_nearby_device_streaming_summary (8280824871197081246) -->
- <skip />
+ <string name="permission_nearby_device_streaming_summary" msgid="8280824871197081246">"Sakaza ama-app nezinye izakhi zesistimu kusuka kufoni yakho"</string>
</resources>
diff --git a/packages/CompanionDeviceManager/res/values/styles.xml b/packages/CompanionDeviceManager/res/values/styles.xml
index 3c75cd5..b167377 100644
--- a/packages/CompanionDeviceManager/res/values/styles.xml
+++ b/packages/CompanionDeviceManager/res/values/styles.xml
@@ -94,12 +94,12 @@
<style name="NegativeButtonMultipleDevices"
parent="@android:style/Widget.Material.Button.Colored">
- <item name="android:layout_width">100dp</item>
+ <item name="android:layout_width">wrap_content</item>
<item name="android:layout_height">36dp</item>
<item name="android:textAllCaps">false</item>
<item name="android:textSize">14sp</item>
- <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
<item name="android:background">@drawable/btn_negative_multiple_devices</item>
+ <item name="android:textAppearance">@android:style/TextAppearance.DeviceDefault.Medium</item>
</style>
<style name="DeviceListBorder">
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
index 8316f9d..71ae578 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/CompanionDeviceActivity.java
@@ -39,6 +39,7 @@
import static com.android.companiondevicemanager.Utils.getApplicationLabel;
import static com.android.companiondevicemanager.Utils.getHtmlFromResources;
import static com.android.companiondevicemanager.Utils.getIcon;
+import static com.android.companiondevicemanager.Utils.getImageColor;
import static com.android.companiondevicemanager.Utils.getVendorHeaderIcon;
import static com.android.companiondevicemanager.Utils.getVendorHeaderName;
import static com.android.companiondevicemanager.Utils.hasVendorIcon;
@@ -56,7 +57,6 @@
import android.companion.IAssociationRequestCallback;
import android.content.Intent;
import android.content.pm.PackageManager;
-import android.content.res.Configuration;
import android.graphics.BlendMode;
import android.graphics.BlendModeColorFilter;
import android.graphics.Color;
@@ -156,6 +156,9 @@
private ConstraintLayout mConstraintList;
// Only present for self-managed association requests.
private RelativeLayout mVendorHeader;
+ // A linearLayout for mButtonNotAllowMultipleDevices, user will press this layout instead
+ // of the button for accessibility.
+ private LinearLayout mNotAllowMultipleDevicesLayout;
// The recycler view is only shown for multiple-device regular association request, after
// at least one matching device is found.
@@ -327,10 +330,11 @@
mButtonAllow = findViewById(R.id.btn_positive);
mButtonNotAllow = findViewById(R.id.btn_negative);
mButtonNotAllowMultipleDevices = findViewById(R.id.btn_negative_multiple_devices);
+ mNotAllowMultipleDevicesLayout = findViewById(R.id.negative_multiple_devices_layout);
mButtonAllow.setOnClickListener(this::onPositiveButtonClick);
mButtonNotAllow.setOnClickListener(this::onNegativeButtonClick);
- mButtonNotAllowMultipleDevices.setOnClickListener(this::onNegativeButtonClick);
+ mNotAllowMultipleDevicesLayout.setOnClickListener(this::onNegativeButtonClick);
mVendorHeaderButton.setOnClickListener(this::onShowHelperDialog);
@@ -459,8 +463,6 @@
final Drawable vendorIcon;
final CharSequence vendorName;
final Spanned title;
- int nightModeFlags = getResources().getConfiguration().uiMode
- & Configuration.UI_MODE_NIGHT_MASK;
if (!SUPPORTED_SELF_MANAGED_PROFILES.contains(deviceProfile)) {
throw new RuntimeException("Unsupported profile " + deviceProfile);
@@ -473,8 +475,7 @@
vendorName = getVendorHeaderName(this, packageName, userId);
mVendorHeaderImage.setImageDrawable(vendorIcon);
if (hasVendorIcon(this, packageName, userId)) {
- int color = nightModeFlags == Configuration.UI_MODE_NIGHT_YES
- ? android.R.color.system_accent1_200 : android.R.color.system_accent1_600;
+ int color = getImageColor(this);
mVendorHeaderImage.setColorFilter(getResources().getColor(color, /* Theme= */null));
}
} catch (PackageManager.NameNotFoundException e) {
@@ -617,6 +618,7 @@
mButtonNotAllow.setVisibility(View.GONE);
mDeviceListRecyclerView.setVisibility(View.VISIBLE);
mButtonNotAllowMultipleDevices.setVisibility(View.VISIBLE);
+ mNotAllowMultipleDevicesLayout.setVisibility(View.VISIBLE);
mConstraintList.setVisibility(View.VISIBLE);
mMultipleDeviceSpinner.setVisibility(View.VISIBLE);
}
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
index 328c67e..d8348d1 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/DeviceListAdapter.java
@@ -17,6 +17,7 @@
package com.android.companiondevicemanager;
import static com.android.companiondevicemanager.Utils.getIcon;
+import static com.android.companiondevicemanager.Utils.getImageColor;
import android.content.Context;
import android.view.LayoutInflater;
@@ -65,6 +66,10 @@
viewHolder.mImageView.setImageDrawable(
getIcon(mContext, android.R.drawable.stat_sys_data_bluetooth));
}
+
+ viewHolder.mImageView.setColorFilter(
+ mContext.getResources().getColor(getImageColor(mContext), /* Theme= */null));
+
return viewHolder;
}
diff --git a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
index fceca91..8c14f80 100644
--- a/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
+++ b/packages/CompanionDeviceManager/src/com/android/companiondevicemanager/Utils.java
@@ -22,6 +22,7 @@
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.ApplicationInfoFlags;
+import android.content.res.Configuration;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.os.Handler;
@@ -120,6 +121,20 @@
}
}
+ private static boolean isDarkTheme(@NonNull Context context) {
+ int nightModeFlags = context.getResources().getConfiguration().uiMode
+ & Configuration.UI_MODE_NIGHT_MASK;
+ return nightModeFlags == Configuration.UI_MODE_NIGHT_YES;
+ }
+
+ // Get image color for the corresponding theme.
+ static int getImageColor(@NonNull Context context) {
+ if (isDarkTheme(context)) {
+ return android.R.color.system_accent1_200;
+ } else {
+ return android.R.color.system_accent1_600;
+ }
+ }
/**
* Getting ApplicationInfo from meta-data.
*/
diff --git a/packages/CredentialManager/res/values-af/strings.xml b/packages/CredentialManager/res/values-af/strings.xml
index e60cc98..6b621ce 100644
--- a/packages/CredentialManager/res/values-af/strings.xml
+++ b/packages/CredentialManager/res/values-af/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Verbeterde rekeningsekuriteit"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Elke sleutel is uitsluitlik gekoppel aan die app of webwerf waarvoor dit geskep is, en daarom kan jy nooit per ongeluk by ’n bedrieglike app of webwerf aanmeld nie. En omdat bedieners net publieke sleutels hou, is kuberkrakery baie moeiliker."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Moeitevrye oorgang"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Wagwoorde sal steeds saam met wagwoordsleutels beskikbaar wees soos 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Skep wagwoordsleutel vir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Stoor <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> in"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Skep wagwoordsleutel op ’n ander toestel?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Gebruik <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> vir al jou aanmeldings?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Hierdie wagwoordbestuurder vir <xliff:g id="USERNAME">%1$s</xliff:g> sal jou wagwoorde en wagwoordsleutels berg om jou te help om maklik aan te meld"</string>
<string name="set_as_default" msgid="4415328591568654603">"Stel as verstek"</string>
<string name="use_once" msgid="9027366575315399714">"Gebruik een keer"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> wagwoorde • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> wagwoordsleutels"</string>
diff --git a/packages/CredentialManager/res/values-am/strings.xml b/packages/CredentialManager/res/values-am/strings.xml
index e34bbcc..6b00e08 100644
--- a/packages/CredentialManager/res/values-am/strings.xml
+++ b/packages/CredentialManager/res/values-am/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"የተሻሻለ የመለያ ደህንነት"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ወደ አጭበርባሪ መተግበሪያ ወይም ድር ጣቢያ በስህተት መቼም መግባት እንዳይችሉ እያንዳንዱ ቁልፍ ከተፈጠረለት መተግበሪያ ወይም ድር ጣቢያ ጋር ለሚመለከተው ተወስኖ የተገናኘ ነው። በተጨማሪም አገልጋዮች ይፋዊ ቁልፎችን ብቻ ስለሚጠብቁ ሰርጎ መግባት የበለጠ ከባድ ነው።"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"እንከን አልባ ትርጉም"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"ወደ የይለፍ ቃል የሌለው ወደፊት ስንሄድ የይለፍ ቃላት አሁንም ከይለፍ ቁልፎች ጎን ለጎን ይገኛሉ"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ለ<xliff:g id="APPNAME">%1$s</xliff:g> የይለፍ ቁልፍ ይፈጠር?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>ን አስቀምጥ ወደ"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"በሌላ መሣሪያ ውስጥ የይለፍ ቁልፍ ይፈጠር?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"ለሁሉም መግቢያዎችዎ <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>ን ይጠቀሙ?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"ይህ የ<xliff:g id="USERNAME">%1$s</xliff:g> የይለፍ ቃል አስተዳዳሪ በቀላሉ እንዲገቡ ለማገዝ የእርስዎን የይለፍ ቃላት እና የይለፍ ቁልፎች ያከማቻል"</string>
<string name="set_as_default" msgid="4415328591568654603">"እንደ ነባሪ ያዋቅሩ"</string>
<string name="use_once" msgid="9027366575315399714">"አንዴ ይጠቀሙ"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> የይለፍ ቃሎች • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> የይለፍ ቁልፎች"</string>
diff --git a/packages/CredentialManager/res/values-ar/strings.xml b/packages/CredentialManager/res/values-ar/strings.xml
index c55fd0b..2d6a606 100644
--- a/packages/CredentialManager/res/values-ar/strings.xml
+++ b/packages/CredentialManager/res/values-ar/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"تحسين أمان الحساب"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"يرتبط كل مفتاح حصريًا بالتطبيق أو الموقع الإلكتروني الذي تم إنشاؤه من أجله، لذلك لا يمكن أبدًا أن تسجّل الدخول إلى تطبيق أو موقع إلكتروني احتيالي عن طريق الخطأ. بالإضافة إلى ذلك، تكون عملية الاختراق أكثر صعوبة لأن الخوادم تحتفظ بالمفاتيح العامة فقط."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"النقل السلس"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"بينما ننطلق نحو مستقبل بدون كلمات مرور، ستظل كلمات المرور متوفّرة إلى جانب مفاتيح المرور."</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"هل تريد إنشاء مفتاح مرور لتطبيق \"<xliff:g id="APPNAME">%1$s</xliff:g>\"؟"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"حفظ <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> في"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"هل تريد إنشاء مفتاح المرور في خدمة أخرى؟"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"هل تريد استخدام \"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>\" لكل عمليات تسجيل الدخول؟"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"ستخزِّن خدمة \"مدير كلمات المرور\" هذه كلمات المرور ومفاتيح المرور للمستخدم <xliff:g id="USERNAME">%1$s</xliff:g> لمساعدتك في تسجيل الدخول بسهولة."</string>
<string name="set_as_default" msgid="4415328591568654603">"ضبط الخيار كتلقائي"</string>
<string name="use_once" msgid="9027366575315399714">"الاستخدام مرة واحدة"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> كلمة مرور • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> مفتاح مرور"</string>
diff --git a/packages/CredentialManager/res/values-as/strings.xml b/packages/CredentialManager/res/values-as/strings.xml
index c719081..8c5e6372 100644
--- a/packages/CredentialManager/res/values-as/strings.xml
+++ b/packages/CredentialManager/res/values-as/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"একাউণ্টৰ উন্নত সুৰক্ষা"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"প্ৰতিটো চাবি বিশেষভাৱে সেই এপ্ অথবা ৱেবছাইটৰ সৈতে লিংক কৰা হয় যাৰ বাবে সেইটো সৃষ্টি কৰা হৈছে, সেয়ে আপুনি কেতিয়াও ভুলতে কোনো প্ৰৱঞ্চনামূলক এপ্ অথবা ৱেবছাইটত ছাইন ইন কৰিব নোৱাৰে। ইয়াৰ উপৰিও, কেৱল ৰাজহুৱা চাবিসমূহ ৰখা ছাৰ্ভাৰৰ ক্ষেত্ৰত হেক কৰাটো বহুত কঠিন হৈ পৰে।"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"বাধাহীন স্থানান্তৰণ"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"আমি পাছৱৰ্ডবিহীন ভৱিষ্যতৰ দিশে আগবঢ়াৰ লগে লগে পাছকীৰ লগতে পাছৱৰ্ডসমূহো উপলব্ধ হ’ব"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>ৰ বাবে পাছকী সৃষ্টি কৰিবনে?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> ইয়াত ছেভ কৰক"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"অন্য এটা ডিভাইচত পাছকী সৃষ্টি কৰিবনে?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"আপোনাৰ আটাইবোৰ ছাইন ইনৰ বাবে <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> ব্যৱহাৰ কৰিবনে?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"আপোনাক সহজে ছাইন ইন কৰাত সহায় কৰিবলৈ <xliff:g id="USERNAME">%1$s</xliff:g>ৰ বাবে থকা এই পাছৱৰ্ড পৰিচালকে আপোনাৰ পাছৱৰ্ড আৰু পাছকী ষ্ট’ৰ কৰিব"</string>
<string name="set_as_default" msgid="4415328591568654603">"ডিফ’ল্ট হিচাপে ছেট কৰক"</string>
<string name="use_once" msgid="9027366575315399714">"এবাৰ ব্যৱহাৰ কৰক"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> টা পাছৱৰ্ড • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> টা পাছকী"</string>
diff --git a/packages/CredentialManager/res/values-az/strings.xml b/packages/CredentialManager/res/values-az/strings.xml
index d0afaa5..e016760 100644
--- a/packages/CredentialManager/res/values-az/strings.xml
+++ b/packages/CredentialManager/res/values-az/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Təkmilləşdirilmiş hesab təhlükəsizliyi"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Hər bir açar eksklüziv olaraq onların yaradıldığı tətbiq və ya vebsaytla əlaqələndirilib, ona görə də heç vaxt səhvən saxta tətbiqə və ya vebsayta daxil ola bilməzsiniz. Üstəlik, yalnız ictimai açarları saxlayan serverlərlə hekinq daha çətindir."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Rahat keçid"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Paroldan istifadə azalsa da, parollar yenə də giriş 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> üçün giriş açarı yaradılsın?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> burada yadda saxlansın:"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Başqa cihazda giriş açarı yaradılsın?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Bütün girişlər üçün <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> istifadə edilsin?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> üçün bu parol meneceri asanlıqla daxil olmağınız məqsədilə parol və giriş açarlarını saxlayacaq"</string>
<string name="set_as_default" msgid="4415328591568654603">"Defolt olaraq seçin"</string>
<string name="use_once" msgid="9027366575315399714">"Bir dəfə istifadə edin"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> giriş açarı"</string>
diff --git a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
index 5716aa6..c80b17e 100644
--- a/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
+++ b/packages/CredentialManager/res/values-b+sr+Latn/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Poboljšana bezbednost naloga"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Svaki ključ je isključivo povezan sa aplikacijom ili veb-sajtom za koje je napravljen, pa nikad ne možete greškom da se prijavite u aplikaciju ili na veb-sajt koji služe za prevaru. Osim toga, sa serverima koji čuvaju samo javne ključeve hakovanje je mnogo teže."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Besprekoran prelaz"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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 stavke <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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Želite da napravite pristupni kôd za: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Sačuvaj stavku <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> u"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Želite da napravite pristupni kôd na drugom uređaju?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Želite da za sva prijavljivanja koristite: <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Ovaj menadžer lozinki za <xliff:g id="USERNAME">%1$s</xliff:g> će čuvati lozinke i pristupne kodove da biste se lako prijavljivali"</string>
<string name="set_as_default" msgid="4415328591568654603">"Podesi kao podrazumevano"</string>
<string name="use_once" msgid="9027366575315399714">"Koristi jednom"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Lozinki: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Pristupnih kodova:<xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-be/strings.xml b/packages/CredentialManager/res/values-be/strings.xml
index ad82b23..13a329a 100644
--- a/packages/CredentialManager/res/values-be/strings.xml
+++ b/packages/CredentialManager/res/values-be/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Павышаная бяспека ўліковага запісу"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Кожны ключ звязаны толькі з праграмай або вэб-сайтам, для якіх ён быў створаны, таму вы не зможаце памылкова ўвайсці ў праграму ці на вэб-сайт, створаныя ў мэтах махлярства. Акрамя таго, на серверах захоўваюцца толькі адкрытыя ключы, таму правесці ўзлом намнога складаней."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Плаўны пераход"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Хоць мы ўжо рухаемся ў бок будучыні без выкарыстання пароляў, яны па-ранейшаму застануцца даступнымі нароўні з ключамі доступу."</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Стварыце ключ доступу да праграмы \"<xliff:g id="APPNAME">%1$s</xliff:g>\""</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Захаваць <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> сюды:"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Стварыць ключ доступу на іншай прыладзе?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Выкарыстоўваць папку \"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>\" для ўсіх спосабаў уваходу?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Каб вам было прасцей уваходзіць у сістэму, вашы паролі і ключы доступу будуць захоўвацца ў менеджары пароляў для <xliff:g id="USERNAME">%1$s</xliff:g>."</string>
<string name="set_as_default" msgid="4415328591568654603">"Выкарыстоўваць стандартна"</string>
<string name="use_once" msgid="9027366575315399714">"Скарыстаць адзін раз"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Пароляў: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Ключоў доступу: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-bg/strings.xml b/packages/CredentialManager/res/values-bg/strings.xml
index f5015b0..453c58f 100644
--- a/packages/CredentialManager/res/values-bg/strings.xml
+++ b/packages/CredentialManager/res/values-bg/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Подобрена сигурност на профила"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Всеки ключ е свързан само с приложението или уебсайта, за които е създаден. Затова не е възможно да влезете в измамно приложение или уебсайт по погрешка. Освен това сървърите съхраняват само публичните ключове, което значително затруднява опитите за хакерство."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Безпроблемен преход"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Паролите ще продължат да са налице заедно с кодовете за достъп по пътя ни към бъдеще без пароли"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Да се създаде ли код за достъп за <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Запазване на <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> във:"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Искате ли да създадете код за достъп на друго устройство?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Да се използва ли <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> за всичките ви данни за вход?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Мениджърът на пароли за <xliff:g id="USERNAME">%1$s</xliff:g> ще съхранява вашите пароли и кодове за достъп, за да влизате лесно в профила си"</string>
<string name="set_as_default" msgid="4415328591568654603">"Задаване като основно"</string>
<string name="use_once" msgid="9027366575315399714">"Еднократно използване"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> пароли • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> кода за достъп"</string>
diff --git a/packages/CredentialManager/res/values-bn/strings.xml b/packages/CredentialManager/res/values-bn/strings.xml
index ec7e154..8360931 100644
--- a/packages/CredentialManager/res/values-bn/strings.xml
+++ b/packages/CredentialManager/res/values-bn/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"অ্যাকাউন্টের জন্য উন্নত সুরক্ষা"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"প্রতিটি \'কী\' যে অ্যাপ বা ওয়েবসাইটের জন্য তৈরি করা হয়েছে, সেগুলির সাথে এই \'কী\' বিশেষভাবে লিঙ্ক করা থাকে। তাই কখনই আপনি ভুলবশত কোনও ভুয়ো অ্যাপ বা ওয়েবসাইটে সাইন-ইন করতে পারবেন না। পাশাপাশি, যেসব সার্ভারে শুধু সর্বজনীন \'কী\' রয়েছে, তা হ্যাক করা খুবই কঠিন।"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"নির্বিঘ্ন ট্রানজিশন"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"আমরা পাসওয়ার্ডবিহীন ভবিষ্যতের দিকে এগিয়ে গেলেও, এখনও \'পাসকী\'-এর পাশাপাশি পাসওয়ার্ড ব্যবহার করা যাবে"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>-এর জন্য \'পাসকী\' তৈরি করবেন?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> এখানে সেভ করুন"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"অন্য ডিভাইসে পাসকী তৈরি করবেন?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"আপনার সব সাইন-ইনের জন্য <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> ব্যবহার করবেন?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g>-এর জন্য এই Password Manager আপনার পাসওয়ার্ড ও \'পাসকী\' সেভ করবে যাতে সহজেই সাইন-ইন করতে পারেন"</string>
<string name="set_as_default" msgid="4415328591568654603">"ডিফল্ট হিসেবে সেট করুন"</string>
<string name="use_once" msgid="9027366575315399714">"একবার ব্যবহার করুন"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>টি পাসওয়ার্ড • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>টি \'পাসকী\'"</string>
diff --git a/packages/CredentialManager/res/values-bs/strings.xml b/packages/CredentialManager/res/values-bs/strings.xml
index 7d888ec..e37232d 100644
--- a/packages/CredentialManager/res/values-bs/strings.xml
+++ b/packages/CredentialManager/res/values-bs/strings.xml
@@ -20,7 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Poboljšana sigurnost računa"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Svaki ključ je isključivo povezan s aplikacijom ili web lokacijom za koju je kreiran, tako da se nikada ne možete greškom prijaviti u prevarantsku aplikaciju ili na prevarantsku web lokaciju. Osim toga, hakiranje je puno teže zahvaljujući serverima koji čuvaju samo javne ključeve."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Neometani prijelaz"</string>
- <string name="seamless_transition_detail" msgid="3440478759491650823">"Kako idemo u smjeru budućnosti bez zaporki, one će i dalje biti dostupne uz pristupne ključeve"</string>
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Kreirati pristupni ključ za aplikaciju <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -35,7 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Sačuvaj <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> na"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Kreirati pristupni ključ na drugom uređaju?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Koristiti uslugu <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> za sve vaše prijave?"</string>
- <string name="use_provider_for_all_description" msgid="1998772715863958997">"Upravitelj zaporki za korisničko ime <xliff:g id="USERNAME">%1$s</xliff:g> pohranit će vaše zaporke i pristupne ključeve radi jednostavnije prijave"</string>
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Ovaj upravitelj lozinki za <xliff:g id="USERNAME">%1$s</xliff:g> će pohraniti vaše lozinke i pristupne ključeve da vam olakša prijavu"</string>
<string name="set_as_default" msgid="4415328591568654603">"Postavi kao zadano"</string>
<string name="use_once" msgid="9027366575315399714">"Koristi jednom"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Broj lozinki: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Broj pristupnih ključeva: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ca/strings.xml b/packages/CredentialManager/res/values-ca/strings.xml
index 9211b50..aed1610 100644
--- a/packages/CredentialManager/res/values-ca/strings.xml
+++ b/packages/CredentialManager/res/values-ca/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Seguretat dels comptes millorada"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Cada clau està exclusivament enllaçada a l\'aplicació o al lloc web per als quals s\'ha creat. D\'aquesta manera, mai iniciaràs la sessió en una aplicació o un lloc web fraudulents per error. A més, com que els servidors només conserven les claus públiques, el hacking és molt més difícil."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transició fluida"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vols crear la clau d\'accés per a <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Desa la <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> a"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Vols crear una clau d\'accés en un altre dispositiu?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Vols utilitzar <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> per a tots els teus inicis de sessió?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Aquest gestor de contrasenyes per a <xliff:g id="USERNAME">%1$s</xliff:g> emmagatzemarà les teves contrasenyes i claus d\'accés per ajudar-te a iniciar la sessió fàcilment"</string>
<string name="set_as_default" msgid="4415328591568654603">"Estableix com a predeterminada"</string>
<string name="use_once" msgid="9027366575315399714">"Utilitza un cop"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> contrasenyes • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> claus d\'accés"</string>
diff --git a/packages/CredentialManager/res/values-cs/strings.xml b/packages/CredentialManager/res/values-cs/strings.xml
index 0a80fe7..8eb0ff6 100644
--- a/packages/CredentialManager/res/values-cs/strings.xml
+++ b/packages/CredentialManager/res/values-cs/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Vylepšené zabezpečení účtu"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Každý klíč je propojen výhradně s aplikací nebo webem, pro které byl vytvořen, takže se nikdy nemůžete omylem přihlásit k podvodné aplikaci nebo webu. Protože na serverech jsou uloženy pouze veřejné klíče, je hackování navíc mnohem obtížnější."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Bezproblémový přechod"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vytvořit přístupový klíč pro aplikaci <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Uložit <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> do"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Vytvořit přístupový klíč v jiném zařízení?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Používat <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> pro všechna přihlášení?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Správce hesel pro účet <xliff:g id="USERNAME">%1$s</xliff:g> bude ukládat vaše hesla a přístupové klíče, abyste se mohli snadno přihlásit"</string>
<string name="set_as_default" msgid="4415328591568654603">"Nastavit jako výchozí"</string>
<string name="use_once" msgid="9027366575315399714">"Použít jednou"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Hesla: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Přístupové klíče: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-da/strings.xml b/packages/CredentialManager/res/values-da/strings.xml
index f24fdb0..8e24cc9 100644
--- a/packages/CredentialManager/res/values-da/strings.xml
+++ b/packages/CredentialManager/res/values-da/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Forbedret kontosikkerhed"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Hver nøgle er udelukkende tilknyttet den app eller det website, som nøglen blev oprettet til. På denne måde kan du aldrig logge ind i en svigagtig app eller på et svigagtigt website ved en fejl. Og da serverne kun opbevarer offentlige nøgler, er kontoer meget sværere at hacke."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Problemfri overgang"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vil du oprette en adgangsnøgle til <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Gem <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> i"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Vil du oprette en adgangsnøgle på en anden enhed?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Vil du bruge <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> til alle dine loginmetoder?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Denne adgangskodeadministrator for <xliff:g id="USERNAME">%1$s</xliff:g> gemmer dine adgangskoder og adgangsnøgler for at hjælpe dig med nemt at logge ind"</string>
<string name="set_as_default" msgid="4415328591568654603">"Angiv som standard"</string>
<string name="use_once" msgid="9027366575315399714">"Brug én gang"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> adgangskoder • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> adgangsnøgler"</string>
diff --git a/packages/CredentialManager/res/values-de/strings.xml b/packages/CredentialManager/res/values-de/strings.xml
index dc6d81d..8c9138c 100644
--- a/packages/CredentialManager/res/values-de/strings.xml
+++ b/packages/CredentialManager/res/values-de/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Verbesserte Kontosicherheit"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Jeder Schlüssel ist ausschließlich mit der App oder Website verknüpft, für die er erstellt wurde. Du kannst dich also nicht aus Versehen bei einer betrügerischen App oder Website anmelden. Da auf Servern nur öffentliche Schlüssel verwaltet werden, wird das Hacking außerdem erheblich erschwert."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Nahtlose Umstellung"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Passkey für <xliff:g id="APPNAME">%1$s</xliff:g> erstellen?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> speichern unter"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Passkey auf einem anderen Gerät erstellen?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> für alle Anmeldungen verwenden?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Mit diesem Passwortmanager für <xliff:g id="USERNAME">%1$s</xliff:g> werden deine Passwörter und Passkeys gespeichert, damit du dich problemlos anmelden kannst"</string>
<string name="set_as_default" msgid="4415328591568654603">"Als Standard festlegen"</string>
<string name="use_once" msgid="9027366575315399714">"Einmal verwenden"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> Passwörter • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> Passkeys"</string>
diff --git a/packages/CredentialManager/res/values-el/strings.xml b/packages/CredentialManager/res/values-el/strings.xml
index 0abc8de..7189585 100644
--- a/packages/CredentialManager/res/values-el/strings.xml
+++ b/packages/CredentialManager/res/values-el/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Βελτιωμένη ασφάλεια λογαριασμού"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Κάθε κλειδί συνδέεται αποκλειστικά με την εφαρμογή ή τον ιστότοπο για τον οποίο δημιουργήθηκε ώστε να μην συνδέεστε ποτέ κατά λάθος σε μη νόμιμες εφαρμογές ή ιστοτόπους. Επιπλέον, οι παραβιάσεις είναι πολύ πιο δύσκολες, επειδή οι διακομιστές διατηρούν μόνο δημόσια κλειδιά."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Απρόσκοπτη μετάβαση"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Καθώς κινούμαστε προς ένα μέλλον χωρίς κωδικούς πρόσβασης, οι κωδικοί πρόσβασης θα εξακολουθούν να είναι διαθέσιμοι μαζί με τα κλειδιά πρόσβασης"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Δημιουργία κλειδιού πρόσβασης για <xliff:g id="APPNAME">%1$s</xliff:g>;"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Αποθήκευση <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> σε"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Δημιουργία κλειδιού πρόσβασης σε άλλη συσκευή;"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Να χρησιμοποιηθεί το <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> για όλες τις συνδέσεις σας;"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Αυτός ο διαχειριστής κωδικών πρόσβασης για τον χρήστη <xliff:g id="USERNAME">%1$s</xliff:g> θα αποθηκεύει τους κωδικούς πρόσβασης και τα κλειδιά πρόσβασης, για πιο εύκολη πρόσβαση"</string>
<string name="set_as_default" msgid="4415328591568654603">"Ορισμός ως προεπιλογής"</string>
<string name="use_once" msgid="9027366575315399714">"Χρήση μία φορά"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> κωδικοί πρόσβασης • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> κλειδιά πρόσβασης"</string>
diff --git a/packages/CredentialManager/res/values-es-rUS/strings.xml b/packages/CredentialManager/res/values-es-rUS/strings.xml
index 9c006a1..27356a0 100644
--- a/packages/CredentialManager/res/values-es-rUS/strings.xml
+++ b/packages/CredentialManager/res/values-es-rUS/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Mayor seguridad para las cuentas"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Cada llave está vinculada exclusivamente con el sitio web o la app para la que fue creada, por lo que nunca podrás acceder por error a una app o sitio web fraudulentos. Además, como los servidores solo guardan claves públicas, hackearlas es mucho más difícil."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transición fluida"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"¿Quieres crear una llave de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Guardar <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> en"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"¿Quieres crear una llave de acceso en otro dispositivo?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"¿Quieres usar <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> para todos tus accesos?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Este administrador de contraseñas para <xliff:g id="USERNAME">%1$s</xliff:g> almacenará tus contraseñas y llaves de acceso para ayudarte a acceder fácilmente"</string>
<string name="set_as_default" msgid="4415328591568654603">"Establecer como predeterminado"</string>
<string name="use_once" msgid="9027366575315399714">"Usar una vez"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> contraseñas • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> llaves de acceso"</string>
diff --git a/packages/CredentialManager/res/values-es/strings.xml b/packages/CredentialManager/res/values-es/strings.xml
index 54097f8..ebdb00d 100644
--- a/packages/CredentialManager/res/values-es/strings.xml
+++ b/packages/CredentialManager/res/values-es/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Seguridad de las cuentas mejorada"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Cada llave está vinculada exclusivamente con la aplicación o sitio web para los que se crearon, por lo que nunca puedes iniciar sesión en una aplicación o sitio web fraudulentos por error. Además, dado que los servidores solo mantienen claves públicas, es muy difícil que las pirateen."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transición fluida"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"¿Crear llave de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Guardar <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> en"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"¿Crear llave de acceso en otro dispositivo?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"¿Usar <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> para todos tus inicios de sesión?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Este gestor de contraseñas de <xliff:g id="USERNAME">%1$s</xliff:g> almacenará tus contraseñas y llaves de acceso para que puedas iniciar sesión fácilmente"</string>
<string name="set_as_default" msgid="4415328591568654603">"Fijar como predeterminado"</string>
<string name="use_once" msgid="9027366575315399714">"Usar una vez"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> contraseñas • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> llaves de acceso"</string>
diff --git a/packages/CredentialManager/res/values-et/strings.xml b/packages/CredentialManager/res/values-et/strings.xml
index 066a98e..6d8b032 100644
--- a/packages/CredentialManager/res/values-et/strings.xml
+++ b/packages/CredentialManager/res/values-et/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Konto täiustatud turvalisus"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Iga võti on lingitud vaid rakenduse või veebisaidiga, mille jaoks see loodi, seega ei saa te petturlikku rakendusse või veebisaidile kunagi kogemata sisse logida. Ja kuna serverid säilitavad vaid avalikke võtmeid, on häkkimine palju keerulisem."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Sujuv üleminek"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Liigume paroolivaba tuleviku poole, kuid paroolid jäävad 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Kas luua rakenduse <xliff:g id="APPNAME">%1$s</xliff:g> jaoks pääsuvõti?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Salvesta <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>:"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Kas luua pääsuvõti muus seadmes?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Kas kasutada teenust <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> kõigi teie sisselogimisandmete puhul?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Konto <xliff:g id="USERNAME">%1$s</xliff:g> paroolihaldur salvestab teie paroolid ja pääsuvõtmed, et aidata teil hõlpsalt sisse logida"</string>
<string name="set_as_default" msgid="4415328591568654603">"Määra vaikeseadeks"</string>
<string name="use_once" msgid="9027366575315399714">"Kasuta ühe korra"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> parooli • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> pääsuvõtit"</string>
diff --git a/packages/CredentialManager/res/values-fa/strings.xml b/packages/CredentialManager/res/values-fa/strings.xml
index 9bef4b3..2407d10 100644
--- a/packages/CredentialManager/res/values-fa/strings.xml
+++ b/packages/CredentialManager/res/values-fa/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"بهبود امنیت حساب"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"هر کلید با برنامه یا وبسایتی که برای آن ایجاد شده است پیوند انحصاری دارد، بنابراین هرگز نمیتوانید بهاشتباه به سیستم برنامه یا وبسایتی جعلی وارد شوید. بهعلاوه، با سرورهایی که فقط کلیدهای عمومی را نگه میدارند رخنهگری بسیار سختتر است."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"انتقال یکپارچه"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"درحالیکه بهسوی آیندهای بدون گذرواژه حرکت میکنیم، گذرواژهها همچنان در کنار گذرکلیدها دردسترس خواهند بود"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"برای <xliff:g id="APPNAME">%1$s</xliff:g> گذرکلید ایجاد شود؟"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"ذخیره <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> در"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"گذرکلید در دستگاه دیگر ایجاد شود؟"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"از <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> برای همه ورود به سیستمها استفاده شود؟"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"این مدیر گذرواژه برای <xliff:g id="USERNAME">%1$s</xliff:g> گذرکلیدها و گذرواژههای شما را ذخیره میکند تا بهراحتی بتوانید به سیستم وارد شوید"</string>
<string name="set_as_default" msgid="4415328591568654603">"تنظیم بهعنوان پیشفرض"</string>
<string name="use_once" msgid="9027366575315399714">"یکبار استفاده"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> گذرواژه • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> گذرکلید"</string>
diff --git a/packages/CredentialManager/res/values-fi/strings.xml b/packages/CredentialManager/res/values-fi/strings.xml
index 950d410..11b4f59 100644
--- a/packages/CredentialManager/res/values-fi/strings.xml
+++ b/packages/CredentialManager/res/values-fi/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Parempi tilin tietoturva"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Kukin avain yhdistetään vain sovellukseen tai sivustoon, jota varten se on luotu, joten et voi koskaan kirjautua vilpilliseen sovellukseen tai sivustolle vahingossa. Lisäksi palvelimet säilyttävät vain julkisia avaimia, mikä tekee hakkeroinnista paljon vaikeampaa."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Saumaton siirtymä"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Luodaanko avainkoodi (<xliff:g id="APPNAME">%1$s</xliff:g>)?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Tallenna <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> tänne:"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Luodaanko avainkoodi toisella laitteella?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Otetaanko <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> käyttöön kaikissa sisäänkirjautumisissa?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Tämä salasanojen ylläpitotyökalu, jota <xliff:g id="USERNAME">%1$s</xliff:g> käyttää, tallentaa salasanat ja avainkoodit, jotta voit kirjautua helposti sisään"</string>
<string name="set_as_default" msgid="4415328591568654603">"Aseta oletukseksi"</string>
<string name="use_once" msgid="9027366575315399714">"Käytä kerran"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> salasanaa • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> avainkoodia"</string>
diff --git a/packages/CredentialManager/res/values-fr-rCA/strings.xml b/packages/CredentialManager/res/values-fr-rCA/strings.xml
index 230b29c..605eed5 100644
--- a/packages/CredentialManager/res/values-fr-rCA/strings.xml
+++ b/packages/CredentialManager/res/values-fr-rCA/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Sécurité accrue du compte"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est exclusivement liée à l\'application ou au site Web pour lequel elle a été créée, de sorte que vous ne pourrez jamais vous connecter par erreur à une application ou à un site Web frauduleux. En outre, comme les serveurs ne conservent que les clés publiques, le piratage informatique est beaucoup plus difficile."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transition fluide"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"À mesure que nous nous dirigeons vers un avenir sans mots de passe, ceux-ci continueront d\'être utilisés parallèlement aux clés d\'accès"</string>
<string name="choose_provider_title" msgid="8870795677024868108">"Choisir où sauvegarder 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Créer une clé d\'accès pour <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Enregistrer la <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> dans"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Créer une clé d\'accès dans un autre appareil?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Utiliser <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> pour toutes vos connexions?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Ce gestionnaire de mots de passe de <xliff:g id="USERNAME">%1$s</xliff:g> stockera vos mots de passe et vos clés d\'accès pour vous permettre de vous connecter facilement"</string>
<string name="set_as_default" msgid="4415328591568654603">"Définir par défaut"</string>
<string name="use_once" msgid="9027366575315399714">"Utiliser une fois"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mots de passe • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> clés d\'accès"</string>
diff --git a/packages/CredentialManager/res/values-fr/strings.xml b/packages/CredentialManager/res/values-fr/strings.xml
index 1c1189a..3017e74 100644
--- a/packages/CredentialManager/res/values-fr/strings.xml
+++ b/packages/CredentialManager/res/values-fr/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Des comptes plus sécurisés"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Chaque clé est liée exclusivement à l\'appli ou au site Web pour lequel elle a été créée, pour que vous ne puissiez jamais vous connecter par erreur à une appli ou un site Web frauduleux. De plus, le piratage est bien plus difficile, car les serveurs ne conservent que les clés publiques."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Une transition fluide"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Créer une clé d\'accès pour <xliff:g id="APPNAME">%1$s</xliff:g> ?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Enregistrer la <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> dans"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Créer une clé d\'accès sur un autre appareil ?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Utiliser <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> pour toutes vos connexions ?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Ce gestionnaire de mots de passe pour <xliff:g id="USERNAME">%1$s</xliff:g> stockera vos mots de passe et clés d\'accès pour vous permettre de vous connecter facilement"</string>
<string name="set_as_default" msgid="4415328591568654603">"Définir par défaut"</string>
<string name="use_once" msgid="9027366575315399714">"Utiliser une fois"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mot(s) de passe • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> clé(s) d\'accès"</string>
diff --git a/packages/CredentialManager/res/values-gl/strings.xml b/packages/CredentialManager/res/values-gl/strings.xml
index 0cd444c..ccb0e3b 100644
--- a/packages/CredentialManager/res/values-gl/strings.xml
+++ b/packages/CredentialManager/res/values-gl/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Mellora na seguranza das contas"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Cada clave está vinculada de xeito exclusivo coa aplicación ou o sitio web para o que foi creada, de tal forma que nunca poidas iniciar sesión nunha aplicación ou un sitio web fraudulentos por erro. Ademais, como os servidores só gardan as claves públicas, resultan moito máis difíciles de piratear."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transición fluída"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Queres crear unha clave de acceso para <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Gardar <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> en"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Queres crear unha clave de acceso noutro dispositivo?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Queres usar <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> cada vez que inicies sesión?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Este xestor de contrasinais de <xliff:g id="USERNAME">%1$s</xliff:g> almacenará os teus contrasinais e claves de acceso para axudarche a iniciar sesión facilmente"</string>
<string name="set_as_default" msgid="4415328591568654603">"Establecer como predeterminado"</string>
<string name="use_once" msgid="9027366575315399714">"Usar unha vez"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> contrasinais • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> claves de acceso"</string>
diff --git a/packages/CredentialManager/res/values-gu/strings.xml b/packages/CredentialManager/res/values-gu/strings.xml
index c9151ae..ed34209 100644
--- a/packages/CredentialManager/res/values-gu/strings.xml
+++ b/packages/CredentialManager/res/values-gu/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"બહેતર બનાવેલી એકાઉન્ટની સુરક્ષા"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"દરેક કીને જે ઍપ અથવા વેબસાઇટ માટે બનાવવામાં આવી હોય તેની સાથે તે વિશેષ રીતે લિંક થયેલી છે, તેથી તમારાથી ક્યારેય ભૂલથી કપટપૂર્ણ ઍપ અથવા વેબસાઇટ પર સાઇન ઇન ન થાય. ઉપરાંત, સર્વર માત્ર જાહેર કી રાખે છે, હૅકિંગ ઘણું મુશ્કેલ છે."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"વિક્ષેપરહિત ટ્રાન્ઝિશન"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"આપણે પાસવર્ડ રહિત ભવિષ્ય તરફ આગળ વધી રહ્યાં છીએ, છતાં પાસકીની સાથોસાથ હજી પણ પાસવર્ડ ઉપલબ્ધ રહેશે"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> માટે પાસકી બનાવીએ?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>ને આમાં સાચવો"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"અન્ય ડિવાઇસ પર પાસકી બનાવીએ?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"શું તમારા બધા સાઇન-ઇન માટે <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>નો ઉપયોગ કરીએ?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> માટેના આ પાસવર્ડ મેનેજર તમને સરળતાથી સાઇન ઇન કરવામાં સહાય કરવા માટે, તમારા પાસવર્ડ અને પાસકી સ્ટોર કરશે"</string>
<string name="set_as_default" msgid="4415328591568654603">"ડિફૉલ્ટ તરીકે સેટ કરો"</string>
<string name="use_once" msgid="9027366575315399714">"એકવાર ઉપયોગ કરો"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> પાસવર્ડ • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> પાસકી"</string>
diff --git a/packages/CredentialManager/res/values-hi/strings.xml b/packages/CredentialManager/res/values-hi/strings.xml
index 60a7d15..029eeee 100644
--- a/packages/CredentialManager/res/values-hi/strings.xml
+++ b/packages/CredentialManager/res/values-hi/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"खाते की बेहतर सुरक्षा"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"हर कुंजी खास तौर पर उस ऐप्लिकेशन या वेबसाइट से लिंक होती है जिसके लिए उसे बनाया गया है. ऐसा इसलिए किया जाता है, ताकि कोई भी व्यक्ति धोखाधड़ी करने वाले ऐप्लिकेशन या वेबसाइट पर कभी भी गलती से साइन इन न करे. साथ ही, सर्वर के पास सिर्फ़ सार्वजनिक कुंजी होती हैं, इसलिए पूरी कुंजी को हैक करना काफ़ी मुश्किल होता है."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"आसान ट्रांज़िशन"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"आने वाले समय में, बिना पासवर्ड के टेक्नोलॉजी का इस्तेमाल किया जा सकेगा. हालांकि, पासकी के साथ पासवर्ड भी इस्तेमाल किए जा सकेंगे"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"क्या आपको <xliff:g id="APPNAME">%1$s</xliff:g> के लिए पासकी बनानी है?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> को यहां सेव करें"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"क्या किसी दूसरे डिवाइस में पासकी सेव करनी है?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"क्या आपको साइन इन से जुड़ी सारी जानकारी सेव करने के लिए, <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> का इस्तेमाल करना है?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> के लिए यह पासवर्ड मैनेजर, आपके पासवर्ड और पासकी सेव करेगा, ताकि आपको साइन इन करने में आसानी हो"</string>
<string name="set_as_default" msgid="4415328591568654603">"डिफ़ॉल्ट के तौर पर सेट करें"</string>
<string name="use_once" msgid="9027366575315399714">"इसका इस्तेमाल एक बार किया जा सकता है"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> पासवर्ड • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> पासकी"</string>
diff --git a/packages/CredentialManager/res/values-hy/strings.xml b/packages/CredentialManager/res/values-hy/strings.xml
index 7e1c36e6d..66d4339 100644
--- a/packages/CredentialManager/res/values-hy/strings.xml
+++ b/packages/CredentialManager/res/values-hy/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Հաշվի բարելավված անվտանգություն"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Յուրաքանչյուր բանալի բացառապես կապված է հավելվածի կամ կայքի հետ, որի համար այն ստեղծվել է, ուստի դուք երբեք չեք կարող սխալմամբ մուտք գործել կեղծ հավելված կամ կայք։ Բացի այդ՝ սերվերներում պահվում են միայն բաց բանալիներ, ինչը զգալիորեն դժվարացնում է կոտրումը։"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Սահուն անցում"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Թեև մենք առանց գաղտնաբառերի ապագայի ճանապարհին ենք, դրանք դեռ հասանելի կլինեն անցաբառերի հետ մեկտեղ"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Ստեղծե՞լ անցաբառ «<xliff:g id="APPNAME">%1$s</xliff:g>» հավելվածի համար"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Պահել <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>ն այստեղ՝"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Ստեղծե՞լ անցաբառ այլ սարքում"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Միշտ մուտք գործե՞լ <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> հավելվածի միջոցով"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Այս գաղտնաբառերի կառավարչում <xliff:g id="USERNAME">%1$s</xliff:g> օգտատերը կկարողանա պահել իր գաղտնաբառերն ու անցաբառերը, որպեսզի հետագայում ավելի արագ մուտք գործի հաշիվ"</string>
<string name="set_as_default" msgid="4415328591568654603">"Նշել որպես կանխադրված"</string>
<string name="use_once" msgid="9027366575315399714">"Օգտագործել մեկ անգամ"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> գաղտնաբառ • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> անցաբառ"</string>
diff --git a/packages/CredentialManager/res/values-in/strings.xml b/packages/CredentialManager/res/values-in/strings.xml
index 64c6a9f..cd2e49fa 100644
--- a/packages/CredentialManager/res/values-in/strings.xml
+++ b/packages/CredentialManager/res/values-in/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Keamanan akun yang ditingkatkan"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Setiap kunci ditautkan secara eksklusif dengan aplikasi atau situs tempatnya dibuat, sehingga Anda tidak akan login ke aplikasi atau situs yang menipu secara tidak sengaja. Selain itu, peretasan lebih sulit dilakukan karena server hanya menyimpan kunci publik."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transisi yang lancar"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Seiring kita menuju masa depan tanpa sandi, sandi akan tetap tersedia bersama kunci sandi"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Buat kunci sandi untuk <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Simpan <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> ke"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Buat kunci sandi di perangkat lain?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Gunakan <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> untuk semua info login Anda?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Pengelola sandi untuk <xliff:g id="USERNAME">%1$s</xliff:g> ini akan menyimpan sandi dan kunci sandi guna membantu Anda login dengan mudah"</string>
<string name="set_as_default" msgid="4415328591568654603">"Setel sebagai default"</string>
<string name="use_once" msgid="9027366575315399714">"Gunakan sekali"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> sandi • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> kunci sandi"</string>
diff --git a/packages/CredentialManager/res/values-is/strings.xml b/packages/CredentialManager/res/values-is/strings.xml
index 16794c2..3bcf659 100644
--- a/packages/CredentialManager/res/values-is/strings.xml
+++ b/packages/CredentialManager/res/values-is/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Bætt reikningsöryggi"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Hver lykill er eingöngu tengdur forritinu eða vefsvæðinu sem hann var búinn til fyrir. Því er engin hætta á að þú skráir þig óvart inn á sviksamlegt forrit eða vefsvæði. Einnig er erfiðara að hakka þegar þjónar geyma aðeins opinbera lykla."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Snurðulaus skipti"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Viltu búa til aðgangslykil fyrir <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Vista <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> í"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Viltu búa til aðgangslykil í öðru tæki?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Nota <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> fyrir allar innskráningar?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Þessi aðgangsorðastjórnun fyrir <xliff:g id="USERNAME">%1$s</xliff:g> vistar aðgangsorð og aðgangslykla til að auðvelda þér að skrá þig inn"</string>
<string name="set_as_default" msgid="4415328591568654603">"Stilla sem sjálfgefið"</string>
<string name="use_once" msgid="9027366575315399714">"Nota einu sinni"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> aðgangsorð • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> aðgangslyklar"</string>
diff --git a/packages/CredentialManager/res/values-ka/strings.xml b/packages/CredentialManager/res/values-ka/strings.xml
index 5e8a6dc..545106b 100644
--- a/packages/CredentialManager/res/values-ka/strings.xml
+++ b/packages/CredentialManager/res/values-ka/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"ანგარიშის გაუმჯობესებული უსაფრთხოება"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"თითოეული გასაღები დაკავშირებულია მხოლოდ აპთან ან ვებსაიტთან, რომელთათვისაც ის შეიქმნა, ამიტომაც შემთხვევით ვერასდროს შეხვალთ თაღლითურ აპში თუ ვებსაიტზე. ამასთანავე, სერვერები ინახავს მხოლოდ საჯარო გასაღებებს, რაც ართულებს გატეხვის ალბათობას."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"დაუბრკოლებელი გადასვლა"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"უპაროლო მომავალში პაროლები კვლავ ხელმისაწვდომი იქნება, წვდომის გასაღებებთან ერთად"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"შექმნით წვდომის გასაღებს <xliff:g id="APPNAME">%1$s</xliff:g> აპისთვის?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>-ის შენახვა"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"გსურთ პაროლის შექმნა სხვა მოწყობილობაში?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"გსურთ, გამოიყენოთ<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> სისტემაში ყველა შესვლისთვის?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"მოცემული პაროლების მმართველი <xliff:g id="USERNAME">%1$s</xliff:g>-ისთვის შეინახავს თქვენს პაროლებს და წვდომის გასაღებს, რომლებიც დაგეხმარებათ სისტემაში მარტივად შესვლაში"</string>
<string name="set_as_default" msgid="4415328591568654603">"ნაგულისხმევად დაყენება"</string>
<string name="use_once" msgid="9027366575315399714">"ერთხელ გამოყენება"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> პაროლები • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> წვდომის გასაღებები"</string>
diff --git a/packages/CredentialManager/res/values-kk/strings.xml b/packages/CredentialManager/res/values-kk/strings.xml
index 9613989..a4f3dc3 100644
--- a/packages/CredentialManager/res/values-kk/strings.xml
+++ b/packages/CredentialManager/res/values-kk/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Аккаунттың қосымша қауіпсіздігі"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Әрбір кілт өзі арнайы жасалған қолданбамен немесе веб-сайтпен ғана байланысты болады, сондықтан алаяқтар қолданбасына немесе веб-сайтына байқаусызда кіру мүмкін емес. Онымен қоса тек ашық кілттер сақталатын серверлер арқасында хакерлердің бұзып кіруі айтарлықтай қиындады."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Оңай ауысу"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Құпия сөзсіз болашақ жақын болғанына қарамастан, келешекте құпия сөздерді кіру кілттерімен қатар қолдана беруге болады."</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> үшін кіру кілтін жасау керек пе?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> дерегін сақтау орны:"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Кіру кілтін басқа құрылғыда жасау керек пе?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Барлық кіру әрекеті үшін <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> пайдаланылсын ба?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> аккаунтына оңай кіру үшін құпия сөз менеджері құпия сөздер мен кіру кілттерін сақтайды."</string>
<string name="set_as_default" msgid="4415328591568654603">"Әдепкі етіп орнату"</string>
<string name="use_once" msgid="9027366575315399714">"Бір рет пайдалану"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> құпия сөз • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> кіру кілті"</string>
diff --git a/packages/CredentialManager/res/values-ko/strings.xml b/packages/CredentialManager/res/values-ko/strings.xml
index b65f693..502d9ee 100644
--- a/packages/CredentialManager/res/values-ko/strings.xml
+++ b/packages/CredentialManager/res/values-ko/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"계정 보안 향상"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"각 키는 생성 시 대상으로 설정된 앱 또는 웹사이트와 단독으로 연결되어 있으므로 실수로 사기 앱 또는 웹사이트에 로그인할 일이 없습니다. 또한 서버에만 공개 키가 보관되므로 해킹이 더욱 까다롭습니다."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"원활한 이전"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"비밀번호가 필요 없는 미래로 나아가는 동안에도 비밀번호는 여전히 패스키와 함께 사용될 것입니다."</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>의 패스키를 만드시겠습니까?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> 저장 위치"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"다른 기기에서 패스키를 만드시겠습니까?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"모든 로그인에 <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>을(를) 사용하시겠습니까?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g>님을 위한 이 비밀번호 관리자는 비밀번호와 패스키를 저장하여 사용자가 간편하게 로그인할 수 있도록 돕습니다."</string>
<string name="set_as_default" msgid="4415328591568654603">"기본값으로 설정"</string>
<string name="use_once" msgid="9027366575315399714">"한 번 사용"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"비밀번호 <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>개 • 패스키 <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>개"</string>
diff --git a/packages/CredentialManager/res/values-ky/strings.xml b/packages/CredentialManager/res/values-ky/strings.xml
index 8df3219..68f082b 100644
--- a/packages/CredentialManager/res/values-ky/strings.xml
+++ b/packages/CredentialManager/res/values-ky/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Аккаунттун коопсуздугу жакшыртылды"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Ар бир ачкыч өзү арналган колдонмо же вебсайт менен гана байланыштырылгандыктан, эч качан шылуундардын колдонмолоруна же вебсайттарына жаңылыштык менен кирип албайсыз. Мындан тышкары, серверлерде жалпыга ачык ачкычтар гана сакталгандыктан, хакерлик кылуу кыйла кыйын."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Тез которулуу"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Сырсөзсүз келечекти көздөй баратсак да, аларды мүмкүндүк алуу ачкычтары менен бирге колдоно берүүгө болот"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> колдонмосуна киргизүүчү ачкыч түзөсүзбү?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> төмөнкүгө сакталсын:"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Киргизүүчү ачкыч башка түзмөктө түзүлсүнбү?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> бардык аккаунттарга кирүү үчүн колдонулсунбу?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Сырсөздөрүңүздү жана ачкычтарыңызды <xliff:g id="USERNAME">%1$s</xliff:g> аккаунтуңуздагы сырсөздөрдү башкаргычка сактап коюп, каалаган убакта колдоно берсеңиз болот"</string>
<string name="set_as_default" msgid="4415328591568654603">"Демейки катары коюу"</string>
<string name="use_once" msgid="9027366575315399714">"Бир жолу колдонуу"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> сырсөз • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> киргизүүчү ачкыч"</string>
diff --git a/packages/CredentialManager/res/values-lo/strings.xml b/packages/CredentialManager/res/values-lo/strings.xml
index cd074a8..d7e4c31 100644
--- a/packages/CredentialManager/res/values-lo/strings.xml
+++ b/packages/CredentialManager/res/values-lo/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"ປັບປຸງຄວາມປອດໄພບັນຊີ"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ກະແຈແຕ່ລະອັນແມ່ນລິ້ງເຈາະຈົງກັບແອັບ ຫຼື ເວັບໄຊທີ່ພວກມັນຖືກສ້າງໃຫ້, ດັ່ງນັ້ນທ່ານຈະບໍ່ສາມາດເຂົ້າສູ່ລະບົບຫາແອັບ ຫຼື ເວັບໄຊສໍ້ໂກງຕ່າງໆໂດຍບໍ່ໄດ້ຕັ້ງໃຈໄດ້. ນອກຈາກນັ້ນ, ເຊີບເວີຍັງມີການເກັບກະແຈສາທາລະນະໄວ້ເທົ່ານັ້ນ, ການແຮັກຈຶ່ງເປັນເລື່ອງຍາກຂຶ້ນຫຼາຍ."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"ການປ່ຽນຜ່ານທີ່ຕໍ່ເນື່ອງ"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"ໃນຂະນະທີ່ພວກເຮົາກ້າວໄປສູ່ອະນາຄົດທີ່ບໍ່ຕ້ອງໃຊ້ລະຫັດຜ່ານ, ລະຫັດຜ່ານຈະຍັງຄົງໃຊ້ໄດ້ຄວບຄູ່ໄປກັບກະແຈຜ່ານ"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ສ້າງກະແຈຜ່ານສຳລັບ <xliff:g id="APPNAME">%1$s</xliff:g> ບໍ?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"ບັນທຶກ <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> ໃສ່"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"ສ້າງກະແຈຜ່ານໃນອຸປະກອນອື່ນບໍ?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"ໃຊ້ <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> ສຳລັບການເຂົ້າສູ່ລະບົບທັງໝົດຂອງທ່ານບໍ?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"ຕົວຈັດການລະຫັດຜ່ານນີ້ສຳລັບ <xliff:g id="USERNAME">%1$s</xliff:g> ຈະຈັດເກັບລະຫັດຜ່ານ ແລະ ກະແຈຜ່ານຂອງທ່ານໄວ້ເພື່ອຊ່ວຍໃຫ້ທ່ານເຂົ້າສູ່ລະບົບໄດ້ຢ່າງງ່າຍດາຍ"</string>
<string name="set_as_default" msgid="4415328591568654603">"ຕັ້ງເປັນຄ່າເລີ່ມຕົ້ນ"</string>
<string name="use_once" msgid="9027366575315399714">"ໃຊ້ເທື່ອດຽວ"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ລະຫັດຜ່ານ • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ກະແຈຜ່ານ"</string>
diff --git a/packages/CredentialManager/res/values-lt/strings.xml b/packages/CredentialManager/res/values-lt/strings.xml
index 133b357..33944c2 100644
--- a/packages/CredentialManager/res/values-lt/strings.xml
+++ b/packages/CredentialManager/res/values-lt/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Geresnė paskyros sauga"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Kiekvienas raktas išskirtinai susietas su programa ar svetaine, kuriai buvo sukurtas, todėl niekada per klaidą neprisijungsite prie apgavikiškos programos ar svetainės. Be to, viešieji raktai laikomi tik serveriuose, todėl įsilaužti tampa gerokai sudėtingiau."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Sklandus perėjimas"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Kol stengiamės padaryti, kad ateityje nereikėtų naudoti slaptažodžių, jie vis dar bus pasiekiami kartu su „passkey“"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Sukurti „passkey“, skirtą „<xliff:g id="APPNAME">%1$s</xliff:g>“?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Išsaugoti <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Kurti „passkey“ kitame įrenginyje?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Naudoti <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> visada prisijungiant?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Šioje <xliff:g id="USERNAME">%1$s</xliff:g> Slaptažodžių tvarkyklėje bus saugomi jūsų slaptažodžiai ir „passkey“, kad galėtumėte lengvai prisijungti"</string>
<string name="set_as_default" msgid="4415328591568654603">"Nustatyti kaip numatytąjį"</string>
<string name="use_once" msgid="9027366575315399714">"Naudoti vieną kartą"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Slaptažodžių: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • „Passkey“: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-lv/strings.xml b/packages/CredentialManager/res/values-lv/strings.xml
index 5222d52..0aa4aa7 100644
--- a/packages/CredentialManager/res/values-lv/strings.xml
+++ b/packages/CredentialManager/res/values-lv/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Uzlabota kontu drošība"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Katra atslēga ir saistīta tikai ar to lietotni vai vietni, kurai tā tika izveidota, tādēļ jūs nevarēsiet nejauši pierakstīties krāpnieciskā lietotnē vai vietnē. Turklāt uzlaušanu ievērojami sarežģī tas, ka serveros tiek glabātas tikai publiskās atslēgas."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Ērta pāreja"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Kamēr notiek pāreja uz darbu bez parolēm, tās joprojām būs pieejamas līdztekus 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vai izveidot piekļuves atslēgu lietotnei <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Kur jāsaglabā <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Vai izveidot piekļuves atslēgu citā ierīcē?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Vai vienmēr izmantot <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>, lai pierakstītos?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Šis paroļu pārvaldnieks glabās konta <xliff:g id="USERNAME">%1$s</xliff:g> paroles un piekļuves atslēgas, lai atvieglotu pierakstīšanos."</string>
<string name="set_as_default" msgid="4415328591568654603">"Iestatīt kā noklusējumu"</string>
<string name="use_once" msgid="9027366575315399714">"Izmantot vienreiz"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Paroļu skaits: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Piekļuves atslēgu skaits: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ml/strings.xml b/packages/CredentialManager/res/values-ml/strings.xml
index ecf06b2..eb75149 100644
--- a/packages/CredentialManager/res/values-ml/strings.xml
+++ b/packages/CredentialManager/res/values-ml/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"മെച്ചപ്പെടുത്തിയ അക്കൗണ്ട് സുരക്ഷ"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ഓരോ കീയും ഏത് ആപ്പിന് അല്ലെങ്കിൽ വെബ്സൈറ്റിന് വേണ്ടിയാണോ സൃഷ്ടിച്ചത്, അതുമായി മാത്രം ലിങ്ക് ചെയ്തിരിക്കുന്നു, അതുകൊണ്ട് നിങ്ങൾ ഒരിക്കലും വഞ്ചനാപരമായ ഒരു ആപ്പിലേക്കോ വെബ്സൈറ്റിലേക്കോ അബദ്ധവശാൽ സൈൻ ഇൻ ചെയ്യില്ല. ഇതോടൊപ്പം, സെർവറുകളിൽ എല്ലാവർക്കുമായുള്ള കീകൾ മാത്രം സൂക്ഷിക്കുന്നതിനാൽ ഹാക്ക് ചെയ്യാൻ വളരെ ബുദ്ധിമുട്ടാണ്."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"ആയാസരഹിതമായ മാറ്റം"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"നമ്മൾ പാസ്വേഡ് രഹിത ഭാവിയിലേക്ക് ചുവടുവെച്ചുകൊണ്ടിരിക്കുകയാണ് എങ്കിലും, പാസ്കീകൾക്കൊപ്പം പാസ്വേഡുകൾ തുടർന്നും ലഭ്യമായിരിക്കും"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> എന്നതിനായി പാസ്കീ സൃഷ്ടിക്കണോ?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> ഇനിപ്പറയുന്നതിലേക്ക് സംരക്ഷിക്കുക"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"മറ്റൊരു ഉപകരണത്തിൽ പാസ്കീ സൃഷ്ടിക്കണോ?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"നിങ്ങളുടെ എല്ലാ സൈൻ ഇന്നുകൾക്കും <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> ഉപയോഗിക്കണോ?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"എളുപ്പത്തിൽ സൈൻ ഇൻ ചെയ്യാൻ സഹായിക്കുന്നതിന്, <xliff:g id="USERNAME">%1$s</xliff:g> എന്ന വിലാസത്തിന്റെ ഈ Password Manager നിങ്ങളുടെ പാസ്വേഡുകളും പാസ്കീകളും സംഭരിക്കും"</string>
<string name="set_as_default" msgid="4415328591568654603">"ഡിഫോൾട്ടായി സജ്ജീകരിക്കുക"</string>
<string name="use_once" msgid="9027366575315399714">"ഒരു തവണ ഉപയോഗിക്കുക"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> പാസ്വേഡുകൾ • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> പാസ്കീകൾ"</string>
diff --git a/packages/CredentialManager/res/values-mn/strings.xml b/packages/CredentialManager/res/values-mn/strings.xml
index 46f5434..cf6a337 100644
--- a/packages/CredentialManager/res/values-mn/strings.xml
+++ b/packages/CredentialManager/res/values-mn/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Бүртгэлийн сайжруулсан аюулгүй байдал"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Түлхүүр тус бүрийг тэдгээрийг зориулж үүсгэсэн апп эсвэл вебсайттай нь тусгайлан холбодог бөгөөд ингэснээр та залилан мэхэлсэн апп эсвэл вебсайтад санамсаргүй байдлаар хэзээ ч нэвтрэхгүй. Түүнчлэн зөвхөн нийтийн түлхүүрийг хадгалж буй серверүүдийг хакердахад илүү хэцүү байдаг."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Саадгүй шилжилт"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Бид нууц үггүй ирээдүй рүү урагшлахын хэрээр нууц үг нь passkey-н хамтаар боломжтой хэвээр байх болно"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g>-д passkey үүсгэх үү?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>-г дараахад хадгалах"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Өөр төхөөрөмжид passkey үүсгэх үү?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>-г бүх нэвтрэлтдээ ашиглах уу?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Танд хялбархан нэвтрэхэд туслахын тулд <xliff:g id="USERNAME">%1$s</xliff:g>-н энэ нууц үгний менежер таны нууц үг болон passkey-г хадгална"</string>
<string name="set_as_default" msgid="4415328591568654603">"Өгөгдмөлөөр тохируулах"</string>
<string name="use_once" msgid="9027366575315399714">"Нэг удаа ашиглах"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> нууц үг • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> passkey"</string>
diff --git a/packages/CredentialManager/res/values-mr/strings.xml b/packages/CredentialManager/res/values-mr/strings.xml
index adc6121..30538b5 100644
--- a/packages/CredentialManager/res/values-mr/strings.xml
+++ b/packages/CredentialManager/res/values-mr/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"सुधारित खाते सुरक्षा"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"प्रत्येक की ज्यांच्यासाठी बनवली आहे फक्त त्या अॅप किंवा वेबसाइटसोबत लिंक केलेली असते, ज्यमुळे तुम्ही कधीच कपटपूर्ण अॅप किंवा वेबसाइटवर चुकूनही साइन इन करणार नाही. तसेच, सर्व्हर फक्त सार्वजनिक की स्टोअर करत असल्यामुळे, हॅक करणे खूप अवघड आहे."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"अखंड संक्रमण"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"पासवर्ड न वापरणाऱ्या भविष्यात पुढे जाताना, पासवर्ड तरीही पासकीच्या बरोबरीने उपलब्ध असतील"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> साठी पासकी तयार करायची का?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> येथे सेव्ह करा"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"दुसऱ्या डिव्हाइसमध्ये पासकी तयार करायची का?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"तुमच्या सर्व साइन-इन साठी <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>वापरायचे का?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"तुम्हाला सहजरीत्या साइन इन करण्यात मदत करण्यासाठी हा <xliff:g id="USERNAME">%1$s</xliff:g> चा पासवर्ड व्यवस्थापक तुमचे पासवर्ड आणि पासकी स्टोअर करेल"</string>
<string name="set_as_default" msgid="4415328591568654603">"डिफॉल्ट म्हणून सेट करा"</string>
<string name="use_once" msgid="9027366575315399714">"एकदा वापरा"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> पासवर्ड • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> पासकी"</string>
diff --git a/packages/CredentialManager/res/values-my/strings.xml b/packages/CredentialManager/res/values-my/strings.xml
index ba9b59a..8bd934d 100644
--- a/packages/CredentialManager/res/values-my/strings.xml
+++ b/packages/CredentialManager/res/values-my/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"ပိုကောင်းသော အကောင့်လုံခြုံရေး"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ကီးတစ်ခုစီကို ၎င်းအတွက် ပြုလုပ်ထားသော အက်ပ် (သို့) ဝဘ်ဆိုက်နှင့် သီးသန့်လင့်ခ်ချိတ်ထားသဖြင့် လိမ်လည်သော အက်ပ် (သို့) ဝဘ်ဆိုက်သို့ မည်သည့်အခါတွင်မှ မှားယွင်း၍ လက်မှတ်ထိုးဝင်နိုင်မည်မဟုတ်ပါ။ ထို့အပြင် ဆာဗာသီးသန့် သိမ်းထားသော အများသုံးကီးများကို ဟက်လုပ်ရန် ပိုခက်ခဲသည်။"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"အလိုအလျောက် ကူးပြောင်းခြင်း"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"စကားဝှက်မသုံးသော အနာဂတ်ဆီသို့ ရှေ့ဆက်ရာတွင် လျှို့ဝှက်ကီးများနှင့်အတူ စကားဝှက်များကို ဆက်လက်သုံးနိုင်မည်"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> အတွက် လျှို့ဝှက်ကီးပြုလုပ်မလား။"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> သိမ်းမည့်နေရာ"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"အခြားစက်ပစ္စည်းတွင် လျှို့ဝှက်ကီး ပြုလုပ်မလား။"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"သင်၏လက်မှတ်ထိုးဝင်မှု အားလုံးအတွက် <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> သုံးမလား။"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"သင်အလွယ်တကူ လက်မှတ်ထိုးဝင်နိုင်ရန် <xliff:g id="USERNAME">%1$s</xliff:g> အတွက် ဤစကားဝှက်မန်နေဂျာက စကားဝှက်နှင့် လျှို့ဝှက်ကီးများကို သိမ်းမည်"</string>
<string name="set_as_default" msgid="4415328591568654603">"မူရင်းအဖြစ် သတ်မှတ်ရန်"</string>
<string name="use_once" msgid="9027366575315399714">"တစ်ကြိမ်သုံးရန်"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"စကားဝှက် <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ခု • လျှို့ဝှက်ကီး <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ခု"</string>
diff --git a/packages/CredentialManager/res/values-nb/strings.xml b/packages/CredentialManager/res/values-nb/strings.xml
index 50a4b47..7e722a5 100644
--- a/packages/CredentialManager/res/values-nb/strings.xml
+++ b/packages/CredentialManager/res/values-nb/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Forbedret kontosikkerhet"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Hver nøkkel er eksklusivt tilknyttet appen eller nettstedet den er laget for. Dermed kan du aldri logge på falske apper eller nettsteder ved et uhell. Og siden tjenerne bare har offentlige nøkler, blir det mye vanskeligere å hacke deg."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Sømløs overgang"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Vi går mot en fremtid uten passord, men passord fortsetter å være tilgjengelige ved siden av tilgangsnø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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vil du opprette en tilgangsnøkkel for <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Lagre <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> i"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Vil du opprette en tilgangsnøkkel på en annen enhet?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Vil du bruke <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> for alle pålogginger?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Dette verktøyet for passordlagring for <xliff:g id="USERNAME">%1$s</xliff:g> lagrer passord og tilgangsnøkler, så det blir lett å logge på"</string>
<string name="set_as_default" msgid="4415328591568654603">"Angi som standard"</string>
<string name="use_once" msgid="9027366575315399714">"Bruk én gang"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> passord • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> tilgangsnøkler"</string>
diff --git a/packages/CredentialManager/res/values-ne/strings.xml b/packages/CredentialManager/res/values-ne/strings.xml
index f77a372..08bd9b7 100644
--- a/packages/CredentialManager/res/values-ne/strings.xml
+++ b/packages/CredentialManager/res/values-ne/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"खाताको सुदृढ सुरक्षा"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"तपाईं कहिले पनि गल्तीले कुनै कपटपूर्ण एप वा वेबसाइटमा लग इन गर्न नसक्नुहोस् भन्नाका लागि हरेक की जुन एप वा वेबसाइटको लागि बनाइएको थियो त्यसलाई खास गरी सोही एप वा वेबसाइटसँग लिंक गरिन्छ। यसका साथै, सर्भरहरूले सार्वजनिक की मात्र राखिराख्ने भएकाले ह्याक गर्न झनै कठिन भएको छ।"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"निर्बाध ट्रान्जिसन"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"हामी पासवर्डरहित भविष्यतर्फ बढ्दै गर्दा पासकीका साथसाथै पासवर्ड पनि उपलब्ध भइरहने छन्"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> को पासकी बनाउने हो?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> यहाँ सेभ गर्नुहोस्:"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"अर्को डिभाइसमा पासकी बनाउने हो?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"तपाईंले साइन इन गर्ने सबै डिभाइसहरूमा <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> प्रयोग गर्ने हो?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"तपाईं सजिलैसँग साइन इन गर्न सक्नुहोस् भन्नाका लागि <xliff:g id="USERNAME">%1$s</xliff:g> को यो पासवर्ड म्यानेजरले तपाईंका पासवर्ड र पासकीहरू सेभ गर्छ"</string>
<string name="set_as_default" msgid="4415328591568654603">"डिफल्ट जानकारीका रूपमा सेट गर्नुहोस्"</string>
<string name="use_once" msgid="9027366575315399714">"एक पटक प्रयोग गर्नुहोस्"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> वटा पासवर्ड • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> वटा पासकी"</string>
diff --git a/packages/CredentialManager/res/values-nl/strings.xml b/packages/CredentialManager/res/values-nl/strings.xml
index c5c2a1c..f9892b0 100644
--- a/packages/CredentialManager/res/values-nl/strings.xml
+++ b/packages/CredentialManager/res/values-nl/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Verbeterde accountbeveiliging"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Elke sleutel is exclusief gekoppeld aan de app of website waarvoor deze is gemaakt. Je kunt dus nooit per ongeluk inloggen bij een bedrieglijke app of website. Bovendien bewaren servers alleen openbare sleutels, wat hacken een stuk lastiger maakt."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Naadloze overgang"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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">"Kies 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Toegangssleutel maken voor <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> opslaan in"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Toegangssleutel maken op een ander apparaat?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> elke keer gebruiken als je inlogt?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Deze wachtwoordmanager voor <xliff:g id="USERNAME">%1$s</xliff:g> slaat je wachtwoorden en toegangssleutels op zodat je makkelijk kunt inloggen"</string>
<string name="set_as_default" msgid="4415328591568654603">"Instellen als standaard"</string>
<string name="use_once" msgid="9027366575315399714">"Eén keer gebruiken"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> wachtwoorden • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> toegangssleutels"</string>
diff --git a/packages/CredentialManager/res/values-or/strings.xml b/packages/CredentialManager/res/values-or/strings.xml
index 1f5312c..f91f5a1 100644
--- a/packages/CredentialManager/res/values-or/strings.xml
+++ b/packages/CredentialManager/res/values-or/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"ଉନ୍ନତ ଆକାଉଣ୍ଟ ସୁରକ୍ଷା"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ପ୍ରତ୍ୟେକ କୀ\'କୁ ସେହି ଆପ କିମ୍ବା ୱେବସାଇଟ ସହ ଏକ୍ସକ୍ଲୁସିଭ ଭାବେ ଲିଙ୍କ କରାଯାଏ ଯେଉଁଥିପାଇଁ ଏହାକୁ ତିଆରି କରାଯାଇଛି, ଫଳରେ ଆପଣ ଭୁଲବଶତଃ କୌଣସି ପ୍ରତାରଣାମୂଳକ ଆପ କିମ୍ବା ୱେବସାଇଟରେ କେବେ ବି ସାଇନ ଇନ କରିପାରିବେ ନାହିଁ। ଏହା ସହ, କେବଳ ସର୍ଭରଗୁଡ଼ିକ ସାର୍ବଜନୀନ କୀ ରଖୁଥିବା ଯୋଗୁଁ ଏହାକୁ ହେକ କରିବା ବହୁତ କଷ୍ଟକର।"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"ବାଧାରହିତ ଟ୍ରାଞ୍ଜିସନ"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"ଆମେ ଏକ ପାସୱାର୍ଡବିହୀନ ଭବିଷ୍ୟତ ଆଡ଼କୁ ମୁଭ କରୁଥିବା ଯୋଗୁଁ ଏବେ ବି ପାସକୀଗୁଡ଼ିକ ସହିତ ପାସୱାର୍ଡ ଉପଲବ୍ଧ ହେବ"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> ପାଇଁ ପାସକୀ ତିଆରି କରିବେ?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>କୁ ଏଥିରେ ସେଭ କରନ୍ତୁ"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"ଅନ୍ୟ ଏକ ଡିଭାଇସରେ ପାସକୀ ତିଆରି କରିବେ?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"ଆପଣଙ୍କ ସମସ୍ତ ସାଇନ-ଇନ ପାଇଁ <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> ବ୍ୟବହାର କରିବେ?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"ସହଜରେ ସାଇନ ଇନ କରିବାରେ ଆପଣଙ୍କୁ ସାହାଯ୍ୟ କରିବାକୁ <xliff:g id="USERNAME">%1$s</xliff:g>ଙ୍କ ପାଇଁ ଏହି Password Manager ଆପଣଙ୍କ ପାସୱାର୍ଡ ଏବଂ ପାସକୀଗୁଡ଼ିକୁ ଷ୍ଟୋର କରିବ"</string>
<string name="set_as_default" msgid="4415328591568654603">"ଡିଫଲ୍ଟ ଭାବେ ସେଟ କରନ୍ତୁ"</string>
<string name="use_once" msgid="9027366575315399714">"ଥରେ ବ୍ୟବହାର କରନ୍ତୁ"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>ଟି ପାସୱାର୍ଡ • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>ଟି ପାସକୀ"</string>
diff --git a/packages/CredentialManager/res/values-pa/strings.xml b/packages/CredentialManager/res/values-pa/strings.xml
index 98be412..64c1149 100644
--- a/packages/CredentialManager/res/values-pa/strings.xml
+++ b/packages/CredentialManager/res/values-pa/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"ਬਿਹਤਰ ਖਾਤਾ ਸੁਰੱਖਿਆ"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ਹਰੇਕ ਕੁੰਜੀ ਖਾਸ ਤੌਰ \'ਤੇ ਉਸ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ ਨਾਲ ਲਿੰਕ ਹੁੰਦੀ ਹੈ ਜਿਸ ਲਈ ਉਹ ਬਣਾਈ ਗਈ ਸੀ, ਇਸ ਲਈ ਤੁਸੀਂ ਕਦੇ ਵੀ ਗਲਤੀ ਨਾਲ ਕਿਸੇ ਧੋਖਾਧੜੀ ਵਾਲੀ ਐਪ ਜਾਂ ਵੈੱਬਸਾਈਟ \'ਤੇ ਸਾਈਨ-ਇਨ ਨਹੀਂ ਕਰ ਸਕਦੇ। ਇਸ ਤੋਂ ਇਲਾਵਾ, ਸਿਰਫ਼ ਜਨਤਕ ਕੁੰਜੀਆਂ ਵਾਲੇ ਸਰਵਰਾਂ \'ਤੇ, ਹੈਕਿੰਗ ਕਰਨਾ ਬਹੁਤ ਔਖਾ ਹੁੰਦਾ ਹੈ।"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"ਸਹਿਜ ਪਰਿਵਰਤਨ"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"ਜਿਵੇਂ ਕਿ ਅਸੀਂ ਪਾਸਵਰਡ-ਰਹਿਤ ਭਵਿੱਖ ਵੱਲ ਵਧ ਰਹੇ ਹਾਂ, ਪਰ ਪਾਸਕੀਆਂ ਦੇ ਨਾਲ ਪਾਸਵਰਡ ਹਾਲੇ ਵੀ ਉਪਲਬਧ ਹੋਣਗੇ"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"ਕੀ <xliff:g id="APPNAME">%1$s</xliff:g> ਲਈ ਪਾਸਕੀ ਬਣਾਉਣੀ ਹੈ?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> ਨੂੰ ਇੱਥੇ ਰੱਖਿਅਤ ਕਰੋ"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"ਕੀ ਕਿਸੇ ਹੋਰ ਡੀਵਾਈਸ ਨਾਲ ਪਾਸਕੀ ਬਣਾਉਣੀ ਹੈ?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"ਕੀ ਆਪਣੇ ਸਾਰੇ ਸਾਈਨ-ਇਨਾਂ ਲਈ<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> ਦੀ ਵਰਤੋਂ ਕਰਨੀ ਹੈ?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> ਦਾ ਇਹ Password Manager ਆਸਾਨੀ ਨਾਲ ਸਾਈਨ-ਇਨ ਕਰਨ ਵਿੱਚ ਤੁਹਾਡੀ ਮਦਦ ਕਰਨ ਲਈ ਤੁਹਾਡੇ ਪਾਸਵਰਡਾਂ ਅਤੇ ਪਾਸਕੀਆਂ ਨੂੰ ਸਟੋਰ ਕਰੇਗਾ"</string>
<string name="set_as_default" msgid="4415328591568654603">"ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਵਜੋਂ ਸੈੱਟ ਕਰੋ"</string>
<string name="use_once" msgid="9027366575315399714">"ਇੱਕ ਵਾਰ ਵਰਤੋ"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ਪਾਸਵਰਡ • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ਪਾਸਕੀਆਂ"</string>
diff --git a/packages/CredentialManager/res/values-pl/strings.xml b/packages/CredentialManager/res/values-pl/strings.xml
index e3b3a8c..787a3ba 100644
--- a/packages/CredentialManager/res/values-pl/strings.xml
+++ b/packages/CredentialManager/res/values-pl/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Zwiększone bezpieczeństwo konta"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Każdy klucz jest połączony wyłącznie z aplikacją lub stroną, dla której został utworzony, więc nie zalogujesz się przypadkowo w fałszywej aplikacji ani na fałszywej stronie. Ponadto na serwerach są przechowywane wyłącznie klucze publiczne, co znacznie utrudnia hakowanie."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Płynne przechodzenie"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"W czasie przechodzenia na technologie niewymagające haseł możliwość stosowania haseł – niezależnie od kluczy – 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Utworzyć klucz dla aplikacji <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Zapisać <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> w:"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Utworzyć klucz na innym urządzeniu?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Używać usługi <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> w przypadku wszystkich danych logowania?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Menedżer haseł na koncie <xliff:g id="USERNAME">%1$s</xliff:g> będzie zapisywał Twoje hasła i klucze, aby ułatwić Ci logowanie"</string>
<string name="set_as_default" msgid="4415328591568654603">"Ustaw jako domyślną"</string>
<string name="use_once" msgid="9027366575315399714">"Użyj raz"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Hasła: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Klucze: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-pt-rBR/strings.xml b/packages/CredentialManager/res/values-pt-rBR/strings.xml
index 289cdea..3250fb0 100644
--- a/packages/CredentialManager/res/values-pt-rBR/strings.xml
+++ b/packages/CredentialManager/res/values-pt-rBR/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Mais segurança para sua conta"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Cada chave está vinculada exclusivamente ao app ou site para a qual foi criada. Isso impede que você faça login em um app ou site fraudulento por engano. Além disso, os servidores mantêm apenas chaves públicas, dificultando qualquer invasão."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transição simplificada"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Estamos avançando rumo 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Criar uma chave de acesso para o app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Salvar <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> em"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Criar chave de acesso em outro dispositivo?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Usar <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> para todos os seus logins?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Esse gerenciador vai armazenar as senhas e chaves de acesso para facilitar o processo de login de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
<string name="set_as_default" msgid="4415328591568654603">"Definir como padrão"</string>
<string name="use_once" msgid="9027366575315399714">"Usar uma vez"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> senhas • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> chaves de acesso"</string>
diff --git a/packages/CredentialManager/res/values-pt/strings.xml b/packages/CredentialManager/res/values-pt/strings.xml
index 289cdea..3250fb0 100644
--- a/packages/CredentialManager/res/values-pt/strings.xml
+++ b/packages/CredentialManager/res/values-pt/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Mais segurança para sua conta"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Cada chave está vinculada exclusivamente ao app ou site para a qual foi criada. Isso impede que você faça login em um app ou site fraudulento por engano. Além disso, os servidores mantêm apenas chaves públicas, dificultando qualquer invasão."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Transição simplificada"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Estamos avançando rumo 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Criar uma chave de acesso para o app <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Salvar <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> em"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Criar chave de acesso em outro dispositivo?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Usar <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> para todos os seus logins?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Esse gerenciador vai armazenar as senhas e chaves de acesso para facilitar o processo de login de <xliff:g id="USERNAME">%1$s</xliff:g>"</string>
<string name="set_as_default" msgid="4415328591568654603">"Definir como padrão"</string>
<string name="use_once" msgid="9027366575315399714">"Usar uma vez"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> senhas • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> chaves de acesso"</string>
diff --git a/packages/CredentialManager/res/values-ro/strings.xml b/packages/CredentialManager/res/values-ro/strings.xml
index 46147a3..96caac73 100644
--- a/packages/CredentialManager/res/values-ro/strings.xml
+++ b/packages/CredentialManager/res/values-ro/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Securitate îmbunătățită a contului"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Fiecare cheie este conectată în mod exclusiv cu aplicația sau site-ul pentru care a fost creată, prin urmare nu te poți conecta niciodată din greșeală la o aplicație sau un site fraudulos. În plus, întrucât pe servere sunt stocate doar chei publice, hackingul este mult mai dificil."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Tranziție fluidă"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Ne îndreptăm spre un viitor fără parole, în care parolele vor fi disponibile pe lângă 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Creezi o cheie de acces pentru <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Salvează <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> în"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Creezi cheia de acces pe alt dispozitiv?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Folosești <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> pentru toate conectările?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Managerul de parole pentru <xliff:g id="USERNAME">%1$s</xliff:g> îți va stoca parolele și cheile de acces, pentru a te ajuta să te conectezi cu ușurință"</string>
<string name="set_as_default" msgid="4415328591568654603">"Setează ca prestabilite"</string>
<string name="use_once" msgid="9027366575315399714">"Folosește o dată"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> parole • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> chei de acces"</string>
diff --git a/packages/CredentialManager/res/values-ru/strings.xml b/packages/CredentialManager/res/values-ru/strings.xml
index a76f79a..4e7ff7d 100644
--- a/packages/CredentialManager/res/values-ru/strings.xml
+++ b/packages/CredentialManager/res/values-ru/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Повышенная безопасность аккаунта"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Каждый ключ связан только с тем приложением или сайтом, для которого был создан, поэтому вы не сможете по ошибке войти в приложение или на сайт мошенников. Кроме того, на серверах хранятся только открытые ключи, что служит дополнительной защитой от взлома."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Плавный переход"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Хотя мы движемся к будущему без паролей, их по-прежнему можно будет использовать наряду с ключами доступа."</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Создать ключ доступа для приложения \"<xliff:g id="APPNAME">%1$s</xliff:g>\"?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Сохранить <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> в"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Создать ключ доступа на другом устройстве?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Всегда входить с помощью приложения \"<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>\"?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"В этом менеджере паролей пользователь <xliff:g id="USERNAME">%1$s</xliff:g> сможет сохранять пароли и ключи доступа для быстрого входа."</string>
<string name="set_as_default" msgid="4415328591568654603">"Использовать по умолчанию"</string>
<string name="use_once" msgid="9027366575315399714">"Использовать один раз"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Пароли (<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>) и ключи доступа (<xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>)"</string>
diff --git a/packages/CredentialManager/res/values-si/strings.xml b/packages/CredentialManager/res/values-si/strings.xml
index 9b7337b..95e326c7 100644
--- a/packages/CredentialManager/res/values-si/strings.xml
+++ b/packages/CredentialManager/res/values-si/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"වැඩිදියුණු කළ ගිණුම් ආරක්ෂාව"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"සෑම යතුරක්ම ඒවා නිර්මාණය කරන ලද යෙදුම හෝ වෙබ් අඩවිය සමග අනන්ය වශයෙන්ම සම්බන්ධ කර ඇත, එබැවින් ඔබට කිසි විටෙක වැරදීමකින් වංචනික යෙදුමකට හෝ වෙබ් අඩවියකට පුරනය විය නොහැක. ඊට අමතරව, සේවාදායකයින් පොදු යතුරු තබා ගැනීමත් සමග, අනවසරයෙන් ඇතුළුවීම වඩා දුෂ්කරය."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"බාධාවකින් තොර සංක්රමණය"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"අපි මුරපද රහිත අනාගතයක් කරා ගමන් කරන විට, මුරයතුරු සමග මුරපද තවමත් පවතිනු ඇත"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> සඳහා මුරයතුර තනන්න ද?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"වෙත <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> සුරකින්න"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"වෙනත් උපාංගයක මුරයතුර තනන්න ද?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"ඔබේ සියලු පුරනය වීම් සඳහා <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> භාවිතා කරන්න ද?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> සඳහා මෙම මුරපද කළමනාකරු ඔබට පහසුවෙන් පුරනය වීමට උදවු කිරීම සඳහා ඔබේ මුරපද සහ මුරයතුරු ගබඩා කරනු ඇත"</string>
<string name="set_as_default" msgid="4415328591568654603">"පෙරනිමි ලෙස සකසන්න"</string>
<string name="use_once" msgid="9027366575315399714">"වරක් භාවිතා කරන්න"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"මුරපද <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g>ක් • මුරයතුරු <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>ක්"</string>
diff --git a/packages/CredentialManager/res/values-sk/strings.xml b/packages/CredentialManager/res/values-sk/strings.xml
index 8d33eab..48cece1 100644
--- a/packages/CredentialManager/res/values-sk/strings.xml
+++ b/packages/CredentialManager/res/values-sk/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Lepšie zabezpečenie účtu"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Každý kľúč je výhradne prepojený s aplikáciou alebo webom, pre ktorý bol vytvorený, takže sa nikdy nemôžete omylom prihlásiť do podvodnej aplikácie alebo na podvodnom webe. Servery navyše uchovávajú iba verejné kľúče, čím podstatne sťažujú hackovanie."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Plynulý prechod"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Chcete vytvoriť prístupový kľúč pre aplikáciu <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Uložiť <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> do"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Chcete vytvoriť prístupový kľúč v inom zariadení?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Chcete pre všetky svoje prihlasovacie údaje použiť <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Tento správca hesiel poskytovateľa <xliff:g id="USERNAME">%1$s</xliff:g> uchová vaše heslá a prístupové kľúče, aby vám pomohol ľahšie sa prihlasovať"</string>
<string name="set_as_default" msgid="4415328591568654603">"Nastaviť ako predvolené"</string>
<string name="use_once" msgid="9027366575315399714">"Použiť raz"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Počet hesiel: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Počet prístupových kľúčov: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-sl/strings.xml b/packages/CredentialManager/res/values-sl/strings.xml
index 666e046..5fde9ff 100644
--- a/packages/CredentialManager/res/values-sl/strings.xml
+++ b/packages/CredentialManager/res/values-sl/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Večja varnost računov"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Vsak ključ je neločljivo povezan z aplikacijo ali spletnim mestom, za katero je bil ustvarjen, zato se nikoli ne morete pomotoma prijaviti v goljufivo aplikacijo ali spletno mesto. Poleg tega so v strežnikih shranjeni le javni ključi, zato je vdiranje v račune precej oteženo."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Prehod brez zapletov"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Želite ustvariti ključ za dostop do aplikacije <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Mesto shranjevanja: <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Želite ustvariti ključ za dostop v drugi napravi?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Želite za vse prijave uporabiti »<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>«?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"V tem upravitelju gesel za uporabnika <xliff:g id="USERNAME">%1$s</xliff:g> bodo shranjeni gesla in ključi za dostop, kar vam bo olajšalo prijavo."</string>
<string name="set_as_default" msgid="4415328591568654603">"Nastavi kot privzeto"</string>
<string name="use_once" msgid="9027366575315399714">"Uporabi enkrat"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Št. gesel: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Št. ključev za dostop: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-sq/strings.xml b/packages/CredentialManager/res/values-sq/strings.xml
index 83a4f61..957fd35 100644
--- a/packages/CredentialManager/res/values-sq/strings.xml
+++ b/packages/CredentialManager/res/values-sq/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Siguri e përmirësuar e llogarisë"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Secili çelës është i lidhur ekskluzivisht me aplikacionin ose sajtin e uebit për të cilin është krijuar, kështu që nuk do të identifikohesh asnjëherë gabimisht në një aplikacion ose sajt uebi mashtrues. Gjithashtu, me serverët që mbajnë vetëm çelësa publikë, pirateria informatike është shumë më e vështirë."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Kalim i thjeshtuar"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Të krijohet çelësi i kalimit për <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Ruaj <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> te"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Të krijohet çelës kalimi në një pajisje tjetër?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Të përdoret <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> për të gjitha identifikimet?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Ky menaxher i fjalëkalimeve për <xliff:g id="USERNAME">%1$s</xliff:g> do të ruajë fjalëkalimet dhe çelësat e kalimit për të të ndihmuar të identifikohesh me lehtësi"</string>
<string name="set_as_default" msgid="4415328591568654603">"Cakto si parazgjedhje"</string>
<string name="use_once" msgid="9027366575315399714">"Përdor një herë"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> fjalëkalime • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> çelësa kalimi"</string>
diff --git a/packages/CredentialManager/res/values-sr/strings.xml b/packages/CredentialManager/res/values-sr/strings.xml
index aa7ae11..b550c1b 100644
--- a/packages/CredentialManager/res/values-sr/strings.xml
+++ b/packages/CredentialManager/res/values-sr/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Побољшана безбедност налога"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Сваки кључ је искључиво повезан са апликацијом или веб-сајтом за које је направљен, па никад не можете грешком да се пријавите у апликацију или на веб-сајт који служе за превару. Осим тога, са серверима који чувају само јавне кључеве хаковање је много теже."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Беспрекоран прелаз"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Како се крећемо ка будућности без лозинки, лозинке ће и даље бити доступне уз приступне кодове"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Желите да направите приступни кôд за: <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Сачувај ставку <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> у"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Желите да направите приступни кôд на другом уређају?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Желите да за сва пријављивања користите: <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Овај менаџер лозинки за <xliff:g id="USERNAME">%1$s</xliff:g> ће чувати лозинке и приступне кодове да бисте се лако пријављивали"</string>
<string name="set_as_default" msgid="4415328591568654603">"Подеси као подразумевано"</string>
<string name="use_once" msgid="9027366575315399714">"Користи једном"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Лозинки: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Приступних кодова:<xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-sv/strings.xml b/packages/CredentialManager/res/values-sv/strings.xml
index 89fa783..440ee6e 100644
--- a/packages/CredentialManager/res/values-sv/strings.xml
+++ b/packages/CredentialManager/res/values-sv/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Förbättrad kontosäkerhet"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Varje nyckel är exklusivt länkad till appen eller webbplatsen den skapades för, så du kan aldrig logga in i en bedräglig app eller webbplats av misstag. Hackning blir dessutom mycket svårare eftersom servrar bara behåller offentliga nycklar."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"En sömlös övergång"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Vill du skapa en nyckel för <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Spara <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> i"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Vill du skapa en nyckel på en annan enhet?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Vill du använda <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> för alla dina inloggningar?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Den här lösenordshanteraren för <xliff:g id="USERNAME">%1$s</xliff:g> sparar dina lösenord och nycklar för att underlätta inloggning"</string>
<string name="set_as_default" msgid="4415328591568654603">"Ange som standard"</string>
<string name="use_once" msgid="9027366575315399714">"Använd en gång"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> lösenord • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> nycklar"</string>
diff --git a/packages/CredentialManager/res/values-sw/strings.xml b/packages/CredentialManager/res/values-sw/strings.xml
index e0cab52..6f71ed7 100644
--- a/packages/CredentialManager/res/values-sw/strings.xml
+++ b/packages/CredentialManager/res/values-sw/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Ulinzi wa akaunti ulioboreshwa"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Kila ufunguo umeunganishwa kwa upekee na programu au tovuti husika, kwa hivyo kamwe huwezi kuingia katika akaunti ya programu au tovuti ya kilaghai kwa bahati mbaya. Pia, kwa kuwa seva huhifadhi tu funguo za umma, udukuzi si rahisi."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Mabadiliko rahisi"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Ungependa kuunda ufunguo wa siri kwa ajili ya <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Hifadhi <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> kwenye"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Ungependa kuunda ufunguo wa siri kwenye kifaa kingine?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Ungependa kutumia <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> kwa ajili ya michakato yako yote ya kuingia katika akaunti?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Kidhibiti hiki cha manenosiri cha <xliff:g id="USERNAME">%1$s</xliff:g> kitahifadhi manenosiri na funguo zako za siri ili kukusaidia uingie katika akaunti kwa urahisi"</string>
<string name="set_as_default" msgid="4415328591568654603">"Weka iwe chaguomsingi"</string>
<string name="use_once" msgid="9027366575315399714">"Tumia mara moja"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Manenosiri <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • funguo <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> za siri"</string>
diff --git a/packages/CredentialManager/res/values-ta/strings.xml b/packages/CredentialManager/res/values-ta/strings.xml
index b340c2e..593aac32 100644
--- a/packages/CredentialManager/res/values-ta/strings.xml
+++ b/packages/CredentialManager/res/values-ta/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"மேம்படுத்தப்பட்ட கணக்குப் பாதுகாப்பு"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ஒவ்வொரு குறியீடும் எந்த ஆப்ஸ்/இணையதளத்திற்காக உருவாக்கப்பட்டதோ அதனுடன் மட்டுமே இணைக்கப்பட்டிருக்கும். இது மோசடியான ஆப்ஸ்/இணையதளத்தில் நீங்கள் தவறுதலாக உள்நுழைவதைத் தடுக்கும். அத்துடன், சேவையகங்களில் பொதுக் குறியீடுகள் மட்டுமே சேமிக்கப்படுவதால் கணக்கை ஹேக் செய்வது மிகக் கடினமாகும்."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"தடையற்ற டிரான்ஸிஷன்"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"கடவுச்சொல்லற்ற எதிர்காலத்தை நோக்கி நாம் பயணிக்கிறோம். கடவுச்சாவிகளைப் பயன்படுத்தும் இதே வேளையில் கடவுச்சொற்களையும் பயன்படுத்த முடியும்"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> ஆப்ஸுக்கான கடவுச்சாவியை உருவாக்கவா?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> ஐ இதில் சேமியுங்கள்"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"வேறொரு சாதனத்தில் கடவுச்சாவியை உருவாக்க வேண்டுமா?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"உங்கள் அனைத்து உள்நுழைவுகளுக்கும் <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>ஐப் பயன்படுத்தவா?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> என்ற மின்னஞ்சல் முகவரிக்கான இந்தக் கடவுச்சொல் நிர்வாகி உங்கள் கடவுச்சொற்களையும் கடவுச்சாவிகளையும் சேமித்து நீங்கள் எளிதாக உள்நுழைய உதவும்"</string>
<string name="set_as_default" msgid="4415328591568654603">"இயல்பானதாக அமை"</string>
<string name="use_once" msgid="9027366575315399714">"ஒருமுறை பயன்படுத்தவும்"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> கடவுச்சொற்கள் • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> கடவுச்சாவிகள்"</string>
diff --git a/packages/CredentialManager/res/values-te/strings.xml b/packages/CredentialManager/res/values-te/strings.xml
index 3b9c57f..ae6149d 100644
--- a/packages/CredentialManager/res/values-te/strings.xml
+++ b/packages/CredentialManager/res/values-te/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"మెరుగైన ఖాతా సెక్యూరిటీ"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ప్రతి కీ దానిని క్రియేట్ చేసిన యాప్ లేదా వెబ్సైట్తో ప్రత్యేకంగా లింక్ చేయబడి ఉంటుంది, కాబట్టి మీరు పొరపాటున కూడా మోసపూరిత యాప్ లేదా వెబ్సైట్కు సైన్ ఇన్ చేయలేరు. అంతే కాకుండా, సర్వర్లు పబ్లిక్ కీలను మాత్రమే స్టోర్ చేయడం వల్ల, హ్యాకింగ్ చేయడం చాలా కష్టం."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"అవాంతరాలు లేని పరివర్తన"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"మనం భవిష్యత్తులో పాస్వర్డ్ రహిత టెక్నాలజీని ఉపయోగించినా, పాస్-కీలతో పాటు పాస్వర్డ్లు కూడా అందుబాటులో ఉంటాయి"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> కోసం పాస్-కీని క్రియేట్ చేయాలా?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>లో సేవ్ చేయండి"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"మరొక పరికరంలో పాస్కీని క్రియేట్ చేయాలా?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"మీ అన్ని సైన్-ఇన్ వివరాల కోసం <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>ను ఉపయోగించాలా?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> కోసం ఈ పాస్వర్డ్ మేనేజర్ మీకు సులభంగా సైన్ ఇన్ చేయడంలో సహాయపడటానికి మీ పాస్వర్డ్లు, పాస్-కీలను స్టోర్ చేస్తుంది"</string>
<string name="set_as_default" msgid="4415328591568654603">"ఆటోమేటిక్ సెట్టింగ్గా సెట్ చేయండి"</string>
<string name="use_once" msgid="9027366575315399714">"ఒకసారి ఉపయోగించండి"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> పాస్వర్డ్లు • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> పాస్-కీలు"</string>
diff --git a/packages/CredentialManager/res/values-th/strings.xml b/packages/CredentialManager/res/values-th/strings.xml
index bc20001..894befb 100644
--- a/packages/CredentialManager/res/values-th/strings.xml
+++ b/packages/CredentialManager/res/values-th/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"ความปลอดภัยของบัญชีที่เพิ่มมากขึ้น"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"คีย์ที่สร้างขึ้นแต่ละคีย์จะลิงก์กับแอปหรือเว็บไซต์ที่ใช้งานคีย์ดังกล่าวเท่านั้น ดังนั้นจึงไม่มีการลงชื่อเข้าใช้แอปเว็บไซต์ที่เป็นการฉ้อโกงโดยไม่ตั้งใจเกิดขึ้น นอกจากนี้ เซิร์ฟเวอร์จะบันทึกเฉพาะคีย์สาธารณะ จึงทำให้แฮ็กได้ยากขึ้น"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"การเปลี่ยนผ่านอย่างราบรื่น"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"ในขณะที่เราก้าวไปสู่อนาคตที่ไม่ต้องใช้รหัสผ่านนั้น รหัสผ่านจะยังคงใช้ได้อยู่ควบคู่ไปกับการเปลี่ยนไปใช้พาสคีย์"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"สร้างพาสคีย์สำหรับ <xliff:g id="APPNAME">%1$s</xliff:g> ไหม"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"บันทึก<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>ไปยัง"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"สร้างพาสคีย์ในอุปกรณ์อื่นไหม"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"ใช้ <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> สำหรับการลงชื่อเข้าใช้ทั้งหมดใช่ไหม"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"เครื่องมือจัดการรหัสผ่านสำหรับ <xliff:g id="USERNAME">%1$s</xliff:g> นี้จะจัดเก็บรหัสผ่านและพาสคีย์ไว้เพื่อช่วยให้คุณลงชื่อเข้าใช้ได้โดยง่าย"</string>
<string name="set_as_default" msgid="4415328591568654603">"ตั้งเป็นค่าเริ่มต้น"</string>
<string name="use_once" msgid="9027366575315399714">"ใช้ครั้งเดียว"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"รหัสผ่าน <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> รายการ • พาสคีย์ <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> รายการ"</string>
diff --git a/packages/CredentialManager/res/values-tl/strings.xml b/packages/CredentialManager/res/values-tl/strings.xml
index f4814bc..27452d6 100644
--- a/packages/CredentialManager/res/values-tl/strings.xml
+++ b/packages/CredentialManager/res/values-tl/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Pinahusay na seguridad sa account"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Eksklusibong naka-link sa app o website kung para saan ginawa ang bawat key, kaya hindi ka makakapag-sign in sa isang mapanlokong app o website nang hindi sinasadya. Bukod pa rito, dahil mga pampublikong key lang ang itinatabi ng mga server, lubos na mas mahirap ang pag-hack."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Madaling transition"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Habang papalapit tayo sa panahon kung saan hindi na gagamit ng 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Gumawa ng passkey para sa <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"I-save ang <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> sa"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Gumawa ng passkey sa ibang device?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Gamitin ang <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> para sa lahat ng iyong pag-sign in?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Iso-store ng password manager na ito para sa <xliff:g id="USERNAME">%1$s</xliff:g> ang iyong mga password at passkey para madali kang makapag-sign in"</string>
<string name="set_as_default" msgid="4415328591568654603">"Itakda bilang default"</string>
<string name="use_once" msgid="9027366575315399714">"Gamitin nang isang beses"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> (na) password • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> (na) passkey"</string>
diff --git a/packages/CredentialManager/res/values-tr/strings.xml b/packages/CredentialManager/res/values-tr/strings.xml
index bc3c4e2..9ef4fc3 100644
--- a/packages/CredentialManager/res/values-tr/strings.xml
+++ b/packages/CredentialManager/res/values-tr/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Daha iyi hesap güvenliği"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Her anahtar, oluşturulduğu uygulama veya web sitesiyle özel olarak bağlantılı olduğu için sahte bir uygulamaya veya web sitesine hiçbir zaman yanlışlıkla giriş yapamazsınız. Ayrıca, sunucularda yalnızca ortak anahtarlar saklandığı için saldırıya uğramak daha zordur."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Sorunsuz geçiş"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Şifresiz bir geleceğe doğru ilerlerken şifreler, şifre 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> için şifre anahtarı oluşturulsun mu?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> kaydedileceği yeri seçin"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Başka bir cihazda şifre anahtarı oluşturulsun mu?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Tüm oturum açma işlemlerinizde <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> kullanılsın mı?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> için bu şifre yöneticisi, şifrelerinizi ve şifre anahtarlarınızı saklayarak kolayca oturum açmanıza yardımcı olur"</string>
<string name="set_as_default" msgid="4415328591568654603">"Varsayılan olarak ayarla"</string>
<string name="use_once" msgid="9027366575315399714">"Bir kez kullanın"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> şifre • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> şifre anahtarı"</string>
diff --git a/packages/CredentialManager/res/values-uk/strings.xml b/packages/CredentialManager/res/values-uk/strings.xml
index abba261..3c06556 100644
--- a/packages/CredentialManager/res/values-uk/strings.xml
+++ b/packages/CredentialManager/res/values-uk/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Підвищена безпека облікового запису"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Кожен ключ зв’язано виключно з додатком або веб-сайтом, для якого його створено, тому ви ніколи не зможете помилково ввійти в шахрайський додаток чи на шахрайський веб-сайт. Крім того, коли на серверах зберігаються лише відкриті ключі, зламати захист набагато складніше."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Плавний перехід"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"На шляху до безпарольного майбутнього паролі й надалі будуть використовуватися паралельно з ключами"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Створити ключ доступу для додатка <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Зберегти <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> в"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Створити ключ доступу на іншому пристрої?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Використовувати сервіс <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> в усіх випадках входу?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Цей менеджер паролів для користувача <xliff:g id="USERNAME">%1$s</xliff:g> зберігатиме ваші паролі й ключі доступу, щоб ви могли легко входити в облікові записи"</string>
<string name="set_as_default" msgid="4415328591568654603">"Вибрати за умовчанням"</string>
<string name="use_once" msgid="9027366575315399714">"Скористатися раз"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Кількість паролів: <xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • Кількість ключів доступу: <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/res/values-ur/strings.xml b/packages/CredentialManager/res/values-ur/strings.xml
index 12da924..34813ef 100644
--- a/packages/CredentialManager/res/values-ur/strings.xml
+++ b/packages/CredentialManager/res/values-ur/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"بہتر کردہ اکاؤنٹ کی سیکیورٹی"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"ہر کلید خصوصی طور پر اس ایپ یا ویب سائٹ سے منسلک ہے جس کے لیے اسے تخلیق کیا گیا تھا، اس لیے آپ کبھی بھی غلطی سے کسی پر فریب ایپ یا ویب سائٹ میں سائن ان نہیں کر سکتے ہیں۔ اس کے علاوہ، چونکہ سرورز صرف عوامی کلید رکھتے ہیں، اس لیے ہیکنگ بہت مشکل ہے۔"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"آسان ٹرانزیشن"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"چونکہ ہم بغیر پاس ورڈ والے مستقبل کی طرف جا رہے ہیں اس کے باوجود پاس ورڈز پاس کیز کے ساتھ ہی دستیاب ہوں گے"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> کے لیے پاس کی تخلیق کریں؟"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> کو اس میں محفوظ کریں"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"کسی دوسرے آلے میں پاس کی تخلیق کریں؟"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"اپنے سبھی سائن انز کے لیے <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> کا استعمال کریں؟"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"آسانی سے سائن ان کرنے میں آپ کی مدد کرنے کے لیے یہ پاس ورڈ مینیجر <xliff:g id="USERNAME">%1$s</xliff:g> کے لیے آپ کے پاس ورڈز اور پاس کیز کو اسٹور کرے گا"</string>
<string name="set_as_default" msgid="4415328591568654603">"بطور ڈیفالٹ سیٹ کریں"</string>
<string name="use_once" msgid="9027366575315399714">"ایک بار استعمال کریں"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> پاس ورڈز • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> پاس کیز"</string>
diff --git a/packages/CredentialManager/res/values-uz/strings.xml b/packages/CredentialManager/res/values-uz/strings.xml
index 3f177d0..8605993 100644
--- a/packages/CredentialManager/res/values-uz/strings.xml
+++ b/packages/CredentialManager/res/values-uz/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Hisob xavfsizligi yaxshilandi"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Har bir kalit faqat ular uchun yaratilgan ilova yoki veb-sayt bilan ulangan, shuning uchun siz hech qachon xatolik bilan soxta ilova yoki veb-saytga kira olmaysiz. Shuningdek, serverlar bilan faqat ochiq kalitlarni saqlagan holda, buzib kirish ancha qiyinroq boʻladi."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Uzluksiz oʻtish"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Parolsiz kelajak sari borayotganimizda, parollar kodlar 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"<xliff:g id="APPNAME">%1$s</xliff:g> uchun kod yaratilsinmi?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Bu <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>ni saqlash"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Boshqa qurilmada kod yaratilsinmi?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Hamma kirishlarda <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> ishlatilsinmi?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> uchun bu parollar menejerida hisobga oson kirishga yordam beruvchi parol va kalitlar saqlanadi"</string>
<string name="set_as_default" msgid="4415328591568654603">"Birlamchi deb belgilash"</string>
<string name="use_once" msgid="9027366575315399714">"Bir marta ishlatish"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> ta parol • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> ta kod"</string>
diff --git a/packages/CredentialManager/res/values-vi/strings.xml b/packages/CredentialManager/res/values-vi/strings.xml
index a45d37e..ab0dd59 100644
--- a/packages/CredentialManager/res/values-vi/strings.xml
+++ b/packages/CredentialManager/res/values-vi/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Cải thiện tính bảo mật của tài khoản"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Mỗi khoá được liên kết riêng với ứng dụng hoặc trang web mà khoá đó được tạo. Vì vậy, bạn sẽ không bao giờ đăng nhập nhầm vào một ứng dụng hoặc trang web lừa đảo. Ngoài ra, với các máy chủ chỉ lưu giữ khoá công khai, việc xâm nhập càng khó hơn nhiều."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Chuyển đổi liền mạch"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"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 mã xác thực"</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 trong lần tới"</string>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Tạo mã xác thực cho <xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Lưu <xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> vào"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Tạo mã xác thực trên thiết bị khác?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Dùng <xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> cho mọi thông tin đăng nhập của bạn?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Trình quản lý mật khẩu này cho <xliff:g id="USERNAME">%1$s</xliff:g> sẽ lưu trữ mật khẩu và mã xác thực để bạn dễ dàng đăng nhập"</string>
<string name="set_as_default" msgid="4415328591568654603">"Đặt làm mặc định"</string>
<string name="use_once" msgid="9027366575315399714">"Dùng một lần"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> mật khẩu • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> mã xác thực"</string>
diff --git a/packages/CredentialManager/res/values-zh-rCN/strings.xml b/packages/CredentialManager/res/values-zh-rCN/strings.xml
index 2e30de6..22944b2 100644
--- a/packages/CredentialManager/res/values-zh-rCN/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rCN/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"提升了帐号安全性"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"每个密钥都是专为特定应用或网站创建的,且仅与各自对应的网站或应用关联,因此您绝不会错误地登录任何欺诈性应用或网站。另外,由于服务器只保留公钥,黑客入侵的难度会大大增加。"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"无缝转换"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"我们正在迈向一个无密码的未来,但在此过程中,密码仍会与通行密钥并存"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"要为“<xliff:g id="APPNAME">%1$s</xliff:g>”创建通行密钥吗?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"将<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>保存到"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"在其他设备上创建通行密钥?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"将“<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>”用于您的所有登录信息?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"此 <xliff:g id="USERNAME">%1$s</xliff:g> 密码管理工具将会存储您的密码和通行密钥,帮助您轻松登录"</string>
<string name="set_as_default" msgid="4415328591568654603">"设为默认项"</string>
<string name="use_once" msgid="9027366575315399714">"使用一次"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> 个密码 • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> 个通行密钥"</string>
diff --git a/packages/CredentialManager/res/values-zh-rHK/strings.xml b/packages/CredentialManager/res/values-zh-rHK/strings.xml
index 9a11e0f..46f6bad 100644
--- a/packages/CredentialManager/res/values-zh-rHK/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rHK/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"提升帳戶安全性"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"系統會為應用程式或網站建立專用的對應金鑰,因此您不會錯誤登入欺詐的應用程式或網站。此外,伺服器上只會保留公開金鑰,因此可大幅降低駭客入侵的風險。"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"流暢轉換"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"我們將會改用無密碼技術,而密碼仍可與密鑰並行使用"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"要為「<xliff:g id="APPNAME">%1$s</xliff:g>」建立密鑰嗎?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"將<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>儲存至"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"要在其他裝置上建立密鑰嗎?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"要將「<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>」用於所有的登入資料嗎?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"此密碼管理工具將儲存「<xliff:g id="USERNAME">%1$s</xliff:g>」的密碼和密鑰,協助您輕鬆登入"</string>
<string name="set_as_default" msgid="4415328591568654603">"設定為預設"</string>
<string name="use_once" msgid="9027366575315399714">"單次使用"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> 個密碼 • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> 個密鑰"</string>
diff --git a/packages/CredentialManager/res/values-zh-rTW/strings.xml b/packages/CredentialManager/res/values-zh-rTW/strings.xml
index 1f8afa8..3a0bf80 100644
--- a/packages/CredentialManager/res/values-zh-rTW/strings.xml
+++ b/packages/CredentialManager/res/values-zh-rTW/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"提升帳戶安全性"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"系統會為應用程式或網站建立專屬的對應金鑰,因此你不會意外登入詐欺性的應用程式或網站。此外,伺服器上只存放公開金鑰,因此可大幅降低駭客入侵的風險。"</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"流暢轉換"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"即使現在已邁入無密碼時代,密碼仍可與密碼金鑰並用"</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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"要為「<xliff:g id="APPNAME">%1$s</xliff:g>」建立密碼金鑰嗎?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"選擇儲存<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g>的位置"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"要在其他裝置上建立密碼金鑰嗎?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"要將「<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g>」用於所有的登入資訊嗎?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"<xliff:g id="USERNAME">%1$s</xliff:g> 的密碼管理工具會儲存密碼和密碼金鑰,協助你輕鬆登入"</string>
<string name="set_as_default" msgid="4415328591568654603">"設為預設"</string>
<string name="use_once" msgid="9027366575315399714">"單次使用"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> 個密碼 • <xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g> 個密碼金鑰"</string>
diff --git a/packages/CredentialManager/res/values-zu/strings.xml b/packages/CredentialManager/res/values-zu/strings.xml
index 01a5b2e..b834ec0 100644
--- a/packages/CredentialManager/res/values-zu/strings.xml
+++ b/packages/CredentialManager/res/values-zu/strings.xml
@@ -20,8 +20,7 @@
<string name="improved_account_security_title" msgid="1069841917893513424">"Ukuvikeleka kwe-akhawunti okuthuthukisiwe"</string>
<string name="improved_account_security_detail" msgid="9123750251551844860">"Ukhiye ngamunye olinkwe ngokukhethekile ne-app noma iwebhusayithi usungulelwe yona, ngakho awukwazi ukungena ngemvume ku-app noma kuwebhusayithi yomgunyathi ngephutha. Futhi, ngamaseva agcina okhiye basesidlangalaleni kuphela, ukugebengu be-inthanethi bunzima kakhulu."</string>
<string name="seamless_transition_title" msgid="5335622196351371961">"Ushintsho olulula"</string>
- <!-- no translation found for seamless_transition_detail (3440478759491650823) -->
- <skip />
+ <string name="seamless_transition_detail" msgid="3440478759491650823">"Njengoba siya ekusaseni 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>
<string name="choose_create_option_passkey_title" msgid="5220979185879006862">"Sungula ukhiye wokudlula we-<xliff:g id="APPNAME">%1$s</xliff:g>?"</string>
@@ -36,8 +35,7 @@
<string name="save_credential_to_title" msgid="3172811692275634301">"Londoloza i-<xliff:g id="CREDENTIALTYPES">%1$s</xliff:g> ku-"</string>
<string name="create_passkey_in_other_device_title" msgid="9195411122362461390">"Sungula ukhiye wokudlula kwenye idivayisi?"</string>
<string name="use_provider_for_all_title" msgid="4201020195058980757">"Sebenzisa i-<xliff:g id="PROVIDERINFODISPLAYNAME">%1$s</xliff:g> kukho konke ukungena kwakho ngemvume?"</string>
- <!-- no translation found for use_provider_for_all_description (1998772715863958997) -->
- <skip />
+ <string name="use_provider_for_all_description" msgid="1998772715863958997">"Lesi siphathi sephasiwedi sika-<xliff:g id="USERNAME">%1$s</xliff:g> sizogcina amaphasiwedi akho nezikhiye zokungena ukuze zikusize ungene ngemvume kalula."</string>
<string name="set_as_default" msgid="4415328591568654603">"Setha njengokuzenzakalelayo"</string>
<string name="use_once" msgid="9027366575315399714">"Sebenzisa kanye"</string>
<string name="more_options_usage_passwords_passkeys" msgid="3470113942332934279">"Amaphasiwedi angu-<xliff:g id="PASSWORDSNUMBER">%1$s</xliff:g> • okhiye bokudlula abangu-<xliff:g id="PASSKEYSNUMBER">%2$s</xliff:g>"</string>
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
index b32fe3f..28f9453 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/CredentialManagerRepo.kt
@@ -467,19 +467,19 @@
GetCredentialRequest.Builder(
Bundle()
).addCredentialOption(
- CredentialOption(
+ CredentialOption.Builder(
passwordOption.type,
passwordOption.requestData,
passwordOption.candidateQueryData,
- passwordOption.isSystemProviderRequired
- )
+ ).setIsSystemProviderRequired(passwordOption.isSystemProviderRequired)
+ .build()
).addCredentialOption(
- CredentialOption(
+ CredentialOption.Builder(
passkeyOption.type,
passkeyOption.requestData,
passkeyOption.candidateQueryData,
- passkeyOption.isSystemProviderRequired
- )
+ ).setIsSystemProviderRequired(passkeyOption.isSystemProviderRequired)
+ .build()
).build(),
"com.google.android.youtube"
)
diff --git a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
index dd60763..5632458 100644
--- a/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
+++ b/packages/CredentialManager/src/com/android/credentialmanager/getflow/GetCredentialComponents.kt
@@ -250,7 +250,7 @@
leftButton = if (totalEntriesCount > 1) {
{
ActionButton(
- stringResource(R.string.get_dialog_use_saved_passkey_for),
+ stringResource(R.string.get_dialog_title_sign_in_options),
onMoreOptionSelected
)
}
diff --git a/packages/PackageInstaller/AndroidManifest.xml b/packages/PackageInstaller/AndroidManifest.xml
index 9ee6fbd..6ccebfd 100644
--- a/packages/PackageInstaller/AndroidManifest.xml
+++ b/packages/PackageInstaller/AndroidManifest.xml
@@ -9,6 +9,7 @@
<uses-permission android:name="android.permission.INSTALL_PACKAGES" />
<uses-permission android:name="android.permission.DELETE_PACKAGES" />
<uses-permission android:name="android.permission.READ_INSTALL_SESSIONS" />
+ <uses-permission android:name="android.permission.READ_INSTALLED_SESSION_PATHS" />
<uses-permission android:name="android.permission.RECEIVE_BOOT_COMPLETED" />
<uses-permission android:name="android.permission.HIDE_NON_SYSTEM_OVERLAY_WINDOWS" />
<uses-permission android:name="android.permission.USE_RESERVED_DISK" />
diff --git a/packages/PackageInstaller/res/values-ar/strings.xml b/packages/PackageInstaller/res/values-ar/strings.xml
index c60f950..f9df296 100644
--- a/packages/PackageInstaller/res/values-ar/strings.xml
+++ b/packages/PackageInstaller/res/values-ar/strings.xml
@@ -61,14 +61,14 @@
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"هل تريد إعادة ضبط هذا التطبيق على الإعدادات الأصلية؟ سؤدي ذلك إلى إزالة جميع البيانات، كما سيؤثر على جميع مستخدمي هذا الجهاز، بما في ذلك من لديهم ملفات شخصية للعمل."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"الاحتفاظ بـ <xliff:g id="SIZE">%1$s</xliff:g> من بيانات التطبيق."</string>
<string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"هل تريد حذف هذا التطبيق؟"</string>
- <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"هل تريد إلغاء تثبيت هذا التطبيق؟ سيتم أيضًا حذف النسخة الطبق الأصل عن \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"."</string>
+ <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"هل تريد إلغاء تثبيت هذا التطبيق؟ سيتم أيضًا حذف نسخة \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" الطبق الأصل."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"عمليات إلغاء التثبيت الجارية"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"عمليات إلغاء التثبيت غير الناجحة"</string>
<string name="uninstalling" msgid="8709566347688966845">"جارٍ إلغاء التثبيت…"</string>
<string name="uninstalling_app" msgid="8866082646836981397">"جارٍ إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="uninstall_done" msgid="439354138387969269">"تمّ إلغاء تثبيت التطبيق."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"تم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"تم حذف النسخة الطبق الأصل عن \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"."</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"تم حذف نسخة \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" الطبق الأصل."</string>
<string name="uninstall_failed" msgid="1847750968168364332">"تعذّر إلغاء تثبيت التطبيق."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"لم يتم إلغاء تثبيت <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> بنجاح."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"جارٍ حذف النسخة الطبق الأصل عن \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"يعتبر الهاتف والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث لهاتفك أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"يعتبر الجهاز اللوحي والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث للجهاز اللوحي أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"يعتبر جهاز التلفزيون والبيانات الشخصية أكثر عرضة لهجوم التطبيقات غير المعروفة. من خلال تثبيت هذا التطبيق، توافق على تحمل مسؤولية أي ضرر يحدث لجهاز التلفزيون أو فقدان البيانات الذي قد ينتج عن استخدامه."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"نسخة طبق الأصل عن \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\""</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"نسخة طبق الأصل من \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\""</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"متابعة"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"الإعدادات"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"تثبيت / إلغاء تثبيت تطبيقات Android Wear"</string>
diff --git a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
index b8dbad5..0a81ac6 100644
--- a/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
+++ b/packages/PackageInstaller/res/values-b+sr+Latn/strings.xml
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Telefon i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja telefona ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Tablet i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja tableta ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"TV i lični podaci su podložniji napadu nepoznatih aplikacija. Ako instalirate ovu aplikaciju, prihvatate da ste odgovorni za eventualna oštećenja TV-a ili gubitak podataka do kojih može da dođe zbog njenog korišćenja."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"Klon aplikaije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"Klon aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Nastavi"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Podešavanja"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Instaliranje/deinstaliranje Wear aplikac."</string>
diff --git a/packages/PackageInstaller/res/values-be/strings.xml b/packages/PackageInstaller/res/values-be/strings.xml
index 05c24ff..e828c3c 100644
--- a/packages/PackageInstaller/res/values-be/strings.xml
+++ b/packages/PackageInstaller/res/values-be/strings.xml
@@ -68,7 +68,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> выдаляецца…"</string>
<string name="uninstall_done" msgid="439354138387969269">"Выдаленне завершана."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"Выдалена: <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Выдалена копія \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\""</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Выдалены клон \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\""</string>
<string name="uninstall_failed" msgid="1847750968168364332">"Не выдалена."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"Не ўдалося выдаліць <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"Выдаленне клона \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
diff --git a/packages/PackageInstaller/res/values-bn/strings.xml b/packages/PackageInstaller/res/values-bn/strings.xml
index 16353df..e7aed0b 100644
--- a/packages/PackageInstaller/res/values-bn/strings.xml
+++ b/packages/PackageInstaller/res/values-bn/strings.xml
@@ -68,7 +68,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হচ্ছে…"</string>
<string name="uninstall_done" msgid="439354138387969269">"আনইনস্টল করা শেষ হয়েছে।"</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা হয়ে গেছে"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"ক্লোনের <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> মুছে ফেলা হয়েছে"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-এর ক্লোন মুছে ফেলা হয়েছে"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"আনইনস্টল করা যায়নি।"</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> আনইনস্টল করা যায়নি।"</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ক্লোন মুছে ফেলা হচ্ছে…"</string>
diff --git a/packages/PackageInstaller/res/values-de/strings.xml b/packages/PackageInstaller/res/values-de/strings.xml
index 669bae6..66e1e59c 100644
--- a/packages/PackageInstaller/res/values-de/strings.xml
+++ b/packages/PackageInstaller/res/values-de/strings.xml
@@ -68,7 +68,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> wird deinstalliert…"</string>
<string name="uninstall_done" msgid="439354138387969269">"Deinstallation abgeschlossen."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> deinstalliert"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Duplikat von „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ gelöscht"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klon von „<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>“ gelöscht"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"Deinstallation fehlgeschlagen."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"Deinstallation von <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> fehlgeschlagen."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-Klon wird gelöscht…"</string>
diff --git a/packages/PackageInstaller/res/values-es-rUS/strings.xml b/packages/PackageInstaller/res/values-es-rUS/strings.xml
index 07485ab..1d7b8c1 100644
--- a/packages/PackageInstaller/res/values-es-rUS/strings.xml
+++ b/packages/PackageInstaller/res/values-es-rUS/strings.xml
@@ -61,7 +61,7 @@
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"¿Deseas reemplazar esta app con la versión de fábrica? Se quitarán todos los datos. Esta acción afectará a todos los usuarios de este dispositivo, incluidos los que tengan perfiles de trabajo."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"Guardar <xliff:g id="SIZE">%1$s</xliff:g> en datos de apps"</string>
<string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"¿Quieres borrar esta app?"</string>
- <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"¿Quieres desinstalar esta app? También se borrará la clonación de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"¿Quieres desinstalar esta app? También se borrará el clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Desinstalaciones activas"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Desinstalaciones con errores"</string>
<string name="uninstalling" msgid="8709566347688966845">"Desinstalando…"</string>
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"El teléfono y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra el teléfono y de la pérdida de datos que pueda ocasionar su uso."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"La tablet y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra la tablet y de la pérdida de datos que pueda ocasionar su uso."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"La TV y tus datos personales son más vulnerables a los ataques de apps desconocidas. Si instalas esta app, serás responsable de los daños que sufra la TV y de la pérdida de datos que pueda ocasionar su uso."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"Clonación de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"Clon de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Continuar"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Configuración"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Instalando/desinstalando apps para Wear"</string>
diff --git a/packages/PackageInstaller/res/values-eu/strings.xml b/packages/PackageInstaller/res/values-eu/strings.xml
index c571020..2ca4397 100644
--- a/packages/PackageInstaller/res/values-eu/strings.xml
+++ b/packages/PackageInstaller/res/values-eu/strings.xml
@@ -68,7 +68,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> desinstalatzen…"</string>
<string name="uninstall_done" msgid="439354138387969269">"Desinstalatu da."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"Desinstalatu da <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Ezabatu da <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> paketearen klona"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Ezabatu da <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> aplikazioaren klona"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"Ezin izan da desinstalatu."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"Ezin izan da desinstalatu <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> aplikazioaren klona ezabatzen…"</string>
diff --git a/packages/PackageInstaller/res/values-fr-rCA/strings.xml b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
index c1c411c..2c5a04d 100644
--- a/packages/PackageInstaller/res/values-fr-rCA/strings.xml
+++ b/packages/PackageInstaller/res/values-fr-rCA/strings.xml
@@ -61,7 +61,7 @@
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette application par la version d\'usine? Toutes les données seront supprimées. Cela touchera tous les utilisateurs de cet appareil, y compris ceux qui utilisent un profil professionnel."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"Garder <xliff:g id="SIZE">%1$s</xliff:g> de données d\'application."</string>
<string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Voulez-vous supprimer cette application?"</string>
- <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Voulez-vous désinstaller cette application? Le clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sera aussi supprimé."</string>
+ <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Voulez-vous désinstaller cette application? Le clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sera aussi supprimé."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Désinstallations en cours…"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Désinstallations échouées"</string>
<string name="uninstalling" msgid="8709566347688966845">"Désinstallation en cours…"</string>
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données personnelles sont plus vulnérables aux attaques provenant d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de l\'utilisation de telles applications."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données personnelles sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"Clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Continuer"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Paramètres"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Installer/désinstaller applis Google Wear"</string>
diff --git a/packages/PackageInstaller/res/values-fr/strings.xml b/packages/PackageInstaller/res/values-fr/strings.xml
index 4a61196..032499d 100644
--- a/packages/PackageInstaller/res/values-fr/strings.xml
+++ b/packages/PackageInstaller/res/values-fr/strings.xml
@@ -61,7 +61,7 @@
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Remplacer cette application par la version d\'usine ? Toutes les données seront supprimées. Tous les utilisateurs de cet appareil seront affectés, y compris ceux qui ont un profil professionnel."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"Conserver <xliff:g id="SIZE">%1$s</xliff:g> de données d\'application."</string>
<string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Voulez-vous supprimer cette appli ?"</string>
- <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Voulez-vous désinstaller cette appli ? Le clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sera supprimé aussi."</string>
+ <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Voulez-vous désinstaller cette appli ? Le clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sera supprimé aussi."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Désinstallations en cours"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Échec des désinstallations"</string>
<string name="uninstalling" msgid="8709566347688966845">"Désinstallation…"</string>
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Votre téléphone et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléphone ou de toute perte de données pouvant découler de son utilisation."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Votre tablette et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre tablette ou de toute perte de données pouvant découler de son utilisation."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Votre téléviseur et vos données à caractère personnel sont plus vulnérables aux attaques d\'applications inconnues. En installant cette application, vous acceptez d\'être le seul responsable de tout dommage causé à votre téléviseur ou de toute perte de données pouvant découler de son utilisation."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"Clone <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"Clone de <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Continuer"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Paramètres"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Installer/Désinstaller les applis Wear"</string>
diff --git a/packages/PackageInstaller/res/values-hr/strings.xml b/packages/PackageInstaller/res/values-hr/strings.xml
index 8961b851..88fdbb77 100644
--- a/packages/PackageInstaller/res/values-hr/strings.xml
+++ b/packages/PackageInstaller/res/values-hr/strings.xml
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Vaš telefon i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje telefona ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Vaš tablet i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje tableta ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Vaš TV i osobni podaci podložniji su napadima nepoznatih aplikacija. Instaliranjem te aplikacije prihvaćate odgovornost za oštećenje televizora ili gubitak podataka do kojih može doći uslijed njezine upotrebe."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> – kloniranje"</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"Klon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Nastavi"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Postavke"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Instaliranje/deinstaliranje Wear apl."</string>
diff --git a/packages/PackageInstaller/res/values-hy/strings.xml b/packages/PackageInstaller/res/values-hy/strings.xml
index 211d5bc..09be03a 100644
--- a/packages/PackageInstaller/res/values-hy/strings.xml
+++ b/packages/PackageInstaller/res/values-hy/strings.xml
@@ -61,14 +61,14 @@
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Փոխարինե՞լ այս հավելվածը գործարանային տարբերակով: Բոլոր տվյալները կհեռացվեն: Դա վերաբերում է այս սարքի բոլոր օգտատերերին, այդ թվում նաև աշխատանքային պրոֆիլներ ունեցողներին:"</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"Չհեռացնել հավելվածների տվյալները (<xliff:g id="SIZE">%1$s</xliff:g>):"</string>
<string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Ջնջե՞լ այս հավելվածը"</string>
- <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Ապատեղադրե՞լ այս հավելվածը։ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ի կրկնօրինակը նույնպես կջնջվի։"</string>
+ <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Ապատեղադրե՞լ այս հավելվածը։ <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ի կլոնը նույնպես կջնջվի։"</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Ընթացիկ ապատեղադրումներ"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Ձախողված ապատեղադրումներ"</string>
<string name="uninstalling" msgid="8709566347688966845">"Ապատեղադրվում է…"</string>
<string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածն ապատեղադրվում է…"</string>
<string name="uninstall_done" msgid="439354138387969269">"Ապատեղադրվեց:"</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածն ապատեղադրվեց"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> կլոնը ջնջվել է"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"«<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>» հավելվածի կլոնը ջնջվել է"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"Չհաջողվեց ապատեղադրել:"</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"Չհաջողվեց ապատեղադրել <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> հավելվածը:"</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ի կրկնօրինակը ջնջվում է…"</string>
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Ձեր հեռախոսը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր հեռախոսին հասցված ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Ձեր պլանշետը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր պլանշետին հասցված ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Ձեր հեռուստացույցը և անձնական տվյալներն առավել խոցելի են անհայտ հավելվածների գրոհների նկատմամբ: Տեղադրելով այս հավելվածը՝ դուք ընդունում եք, որ պատասխանատվություն եք կրում հավելվածի օգտագործման հետևանքով ձեր հեռուստացույցին հասցված ցանկացած վնասի կամ տվյալների կորստի համար:"</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-ի կրկնօրինակ"</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"«<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>» հավելվածի կլոն"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Շարունակել"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Կարգավորումներ"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Wear հավելվածների տեղադրում/ապատեղադրում"</string>
diff --git a/packages/PackageInstaller/res/values-ja/strings.xml b/packages/PackageInstaller/res/values-ja/strings.xml
index fd10940..62149d1 100644
--- a/packages/PackageInstaller/res/values-ja/strings.xml
+++ b/packages/PackageInstaller/res/values-ja/strings.xml
@@ -68,7 +68,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールしています…"</string>
<string name="uninstall_done" msgid="439354138387969269">"アンインストールが完了しました。"</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールしました"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"削除された <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> のクローン"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> のクローンを削除しました"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"アンインストールできませんでした。"</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"「<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>」をアンインストールできませんでした。"</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> のクローンを削除しています…"</string>
diff --git a/packages/PackageInstaller/res/values-km/strings.xml b/packages/PackageInstaller/res/values-km/strings.xml
index 46e2914..d744ff7 100644
--- a/packages/PackageInstaller/res/values-km/strings.xml
+++ b/packages/PackageInstaller/res/values-km/strings.xml
@@ -68,7 +68,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"កំពុងលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="uninstall_done" msgid="439354138387969269">"បានបញ្ចប់ការលុប។"</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"បានលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"ក្លូន <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ដែលបានលុប"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"បានលុបក្លូន <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"មិនអាចលុបបានទេ។"</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"មិនអាចលុប <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> បានទេ។"</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"កំពុងលុបក្លូន <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-mk/strings.xml b/packages/PackageInstaller/res/values-mk/strings.xml
index 6135e65..529ea3e 100644
--- a/packages/PackageInstaller/res/values-mk/strings.xml
+++ b/packages/PackageInstaller/res/values-mk/strings.xml
@@ -68,7 +68,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"Се деинсталира <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="uninstall_done" msgid="439354138387969269">"Деинсталирањето заврши."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> се деинсталираше"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Избришан е клон на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Клонот на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> е избришан"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"Деинсталирањето е неуспешно."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"Деинсталирањето на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> е неуспешно."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"Се брише клонот на <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
diff --git a/packages/PackageInstaller/res/values-mn/strings.xml b/packages/PackageInstaller/res/values-mn/strings.xml
index 52bca70..0243931 100644
--- a/packages/PackageInstaller/res/values-mn/strings.xml
+++ b/packages/PackageInstaller/res/values-mn/strings.xml
@@ -61,14 +61,14 @@
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Энэ аппыг үйлдвэрээс ирсэн хувилбараар солих уу? Бүх өгөгдөл устах болно. Энэ нь эдгээр ажлын профайлтай бүхий энэ төхөөрөмжийн бүх хэрэглэгчид нөлөөлнө."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"Аппын өгөгдлийн <xliff:g id="SIZE">%1$s</xliff:g>-г үлдээнэ үү."</string>
<string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Та энэ аппыг устгахыг хүсэж байна уу?"</string>
- <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Та энэ аппыг устгахыг хүсэж байна уу? <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клоныг мөн устгана."</string>
+ <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Та энэ аппыг устгахыг хүсэж байна уу? <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-н хувилалыг мөн устгана."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Устгаж байна"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Устгаж чадсангүй"</string>
<string name="uninstalling" msgid="8709566347688966845">"Устгаж байна…"</string>
<string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгаж байна…"</string>
<string name="uninstall_done" msgid="439354138387969269">"Устгаж дууслаа."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгасан"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клоныг устгасан"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-н хувилалыг устгасан"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"Устгах амжилтгүй боллоо."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-г устгах амжилтгүй боллоо."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клоныг устгаж байна…"</string>
diff --git a/packages/PackageInstaller/res/values-ne/strings.xml b/packages/PackageInstaller/res/values-ne/strings.xml
index e763ae1..d6451eb 100644
--- a/packages/PackageInstaller/res/values-ne/strings.xml
+++ b/packages/PackageInstaller/res/values-ne/strings.xml
@@ -60,7 +60,7 @@
<string name="uninstall_update_text" msgid="863648314632448705">"यस एपलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइने छ।"</string>
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"यस एपलाई फ्याक्ट्रीको संस्करणले बदल्ने हो? सबै डेटा हटाइने छ। यसले यस डिभाइसका कार्य प्रोफाइल भएका लगायत सबै प्रयोगकर्ताहरूमा असर पार्छ।"</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"<xliff:g id="SIZE">%1$s</xliff:g> एपको डेटा राख्नुहोस्।"</string>
- <string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"तपाईंले यो एप मेटाउन चाहनुहुन्छ?"</string>
+ <string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"तपाईं यो एप मेटाउन चाहनुहुन्छ?"</string>
<string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"तपाईं यो एप अनइन्स्टल गर्न चाहनुहुन्छ? <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> क्लोन पनि मेटाइने छ।"</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"चलिरहेका स्थापना रद्द गर्ने कार्यहरू"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"असफल भएका स्थापना रद्द गर्ने कार्यहरू"</string>
diff --git a/packages/PackageInstaller/res/values-ru/strings.xml b/packages/PackageInstaller/res/values-ru/strings.xml
index 957f294..f70c4bc 100644
--- a/packages/PackageInstaller/res/values-ru/strings.xml
+++ b/packages/PackageInstaller/res/values-ru/strings.xml
@@ -61,14 +61,14 @@
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Установить исходную версию приложения? Его данные будут удалены из всех профилей устройства, в том числе рабочих."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"Сохранить данные приложения (<xliff:g id="SIZE">%1$s</xliff:g>)"</string>
<string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Удалить это приложение?"</string>
- <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Удалить это приложение? Клон пакета \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" также будет удален."</string>
+ <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Удалить это приложение? Клон приложения <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> также будет удален."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Активные процессы удаления"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Ошибки удаления"</string>
<string name="uninstalling" msgid="8709566347688966845">"Удаление…"</string>
<string name="uninstalling_app" msgid="8866082646836981397">"Удаление приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
<string name="uninstall_done" msgid="439354138387969269">"Удаление завершено."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"Приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" удалено."</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Клон приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\" удален."</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Клон приложения <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> удален."</string>
<string name="uninstall_failed" msgid="1847750968168364332">"При удалении произошла ошибка."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"Не удалось удалить приложение \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"Удаление клона пакета \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\"…"</string>
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Ваши персональные данные и данные телефона более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы берете на себя всю ответственность за последствия, связанные с его использованием, то есть за любой ущерб, нанесенный телефону, и возможную потерю данных."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Ваши персональные данные и данные планшета более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы берете на себя всю ответственность за последствия, связанные с его использованием, то есть за любой ущерб, нанесенный планшету, и возможную потерю данных."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Ваши персональные данные и данные телевизора более уязвимы для атак приложений из неизвестных источников. Устанавливая это приложение, вы берете на себя всю ответственность за последствия, связанные с его использованием, то есть за любой ущерб, нанесенный телевизору, и возможную потерю данных."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"Клон пакета \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\""</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"Клон приложения <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Продолжить"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Настройки"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Установка/удаление прилож. для Wear OS"</string>
diff --git a/packages/PackageInstaller/res/values-sk/strings.xml b/packages/PackageInstaller/res/values-sk/strings.xml
index f4d5631..181ff9c 100644
--- a/packages/PackageInstaller/res/values-sk/strings.xml
+++ b/packages/PackageInstaller/res/values-sk/strings.xml
@@ -68,7 +68,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"Prebieha odinštalovanie balíka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>…"</string>
<string name="uninstall_done" msgid="439354138387969269">"Odinštalovanie bolo dokončené."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"Balík <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> bol odinštalovaný"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klon balíka <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> bol odstránený"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> bol odstránený"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"Nepodarilo sa odinštalovať."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"Balík <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sa nepodarilo odinštalovať."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"Klon <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> sa odstraňuje…"</string>
diff --git a/packages/PackageInstaller/res/values-sl/strings.xml b/packages/PackageInstaller/res/values-sl/strings.xml
index f12935e..35b3fda 100644
--- a/packages/PackageInstaller/res/values-sl/strings.xml
+++ b/packages/PackageInstaller/res/values-sl/strings.xml
@@ -61,14 +61,14 @@
<string name="uninstall_update_text_multiuser" msgid="8992883151333057227">"Želite to aplikacijo nadomestiti s tovarniško različico? Odstranjeni bodo vsi podatki. To vpliva na vse uporabnike te naprave, vključno s tistimi z delovnimi profili."</string>
<string name="uninstall_keep_data" msgid="7002379587465487550">"Obdrži <xliff:g id="SIZE">%1$s</xliff:g> podatkov aplikacije."</string>
<string name="uninstall_application_text_current_user_clone_profile" msgid="835170400160011636">"Ali želite izbrisati to aplikacijo?"</string>
- <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Ali želite odmestiti to aplikacijo? Izbrisan bo tudi klonirani paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
+ <string name="uninstall_application_text_with_clone_instance" msgid="6944473334273349036">"Ali želite odmestiti to aplikacijo? Izbrisana bo tudi klonirana aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>."</string>
<string name="uninstalling_notification_channel" msgid="840153394325714653">"Odstranitve v teku"</string>
<string name="uninstall_failure_notification_channel" msgid="1136405866767576588">"Neuspele odstranitve"</string>
<string name="uninstalling" msgid="8709566347688966845">"Odstranjevanje …"</string>
<string name="uninstalling_app" msgid="8866082646836981397">"Odmeščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
<string name="uninstall_done" msgid="439354138387969269">"Odstranitev je končana."</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"Aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je bila odstranjena."</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klonirani paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je izbrisan"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"Klonirana aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> je izbrisana"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"Odstranitev ni uspela."</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"Odmeščanje aplikacije <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ni uspelo."</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"Brisanje kloniranega paketa <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> …"</string>
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Neznane aplikacije lahko resno ogrozijo varnost telefona in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v telefonu, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Neznane aplikacije lahko resno ogrozijo varnost tabličnega računalnika in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v tabličnem računalniku, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"Neznane aplikacije lahko resno ogrozijo varnost televizorja in osebnih podatkov. Z namestitvijo te aplikacije se strinjate, da ste sami odgovorni za morebitno škodo, nastalo v televizorju, ali izgubo podatkov, do katerih lahko pride zaradi uporabe te aplikacije."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"Klonirani paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"Klonirana aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Naprej"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Nastavitve"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Nameščanje/odstranjev. aplikacij za Wear"</string>
diff --git a/packages/PackageInstaller/res/values-sr/strings.xml b/packages/PackageInstaller/res/values-sr/strings.xml
index 2bfcf65..2e448ad 100644
--- a/packages/PackageInstaller/res/values-sr/strings.xml
+++ b/packages/PackageInstaller/res/values-sr/strings.xml
@@ -92,7 +92,7 @@
<string name="anonymous_source_warning" product="default" msgid="2784902545920822500">"Телефон и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења телефона или губитак података до којих може да дође због њеног коришћења."</string>
<string name="anonymous_source_warning" product="tablet" msgid="3939101621438855516">"Таблет и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења таблета или губитак података до којих може да дође због њеног коришћења."</string>
<string name="anonymous_source_warning" product="tv" msgid="5599483539528168566">"ТВ и лични подаци су подложнији нападу непознатих апликација. Ако инсталирате ову апликацију, прихватате да сте одговорни за евентуална оштећења ТВ-а или губитак података до којих може да дође због њеног коришћења."</string>
- <string name="cloned_app_label" msgid="7503612829833756160">"Клон апликаије <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_label" msgid="7503612829833756160">"Клон апликације <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
<string name="anonymous_source_continue" msgid="4375745439457209366">"Настави"</string>
<string name="external_sources_settings" msgid="4046964413071713807">"Подешавања"</string>
<string name="wear_app_channel" msgid="1960809674709107850">"Инсталирање/деинсталирање Wear апликац."</string>
diff --git a/packages/PackageInstaller/res/values-ur/strings.xml b/packages/PackageInstaller/res/values-ur/strings.xml
index ab11cd8..21f6cdf 100644
--- a/packages/PackageInstaller/res/values-ur/strings.xml
+++ b/packages/PackageInstaller/res/values-ur/strings.xml
@@ -68,7 +68,7 @@
<string name="uninstalling_app" msgid="8866082646836981397">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> ان انسٹال ہو رہا ہے…"</string>
<string name="uninstall_done" msgid="439354138387969269">"اَن انسٹال مکمل ہو گیا۔"</string>
<string name="uninstall_done_app" msgid="4588850984473605768">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> اَن انسٹال ہو گیا"</string>
- <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کا کلون حذف کر دیا گیا ہے"</string>
+ <string name="uninstall_done_clone_app" msgid="5578308154544195413">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کا کلون حذف کر دیا گیا ہے"</string>
<string name="uninstall_failed" msgid="1847750968168364332">"اَن انسٹال ناکام ہو گیا۔"</string>
<string name="uninstall_failed_app" msgid="5506028705017601412">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کو ان انسٹال کرنا ناکام ہو گیا۔"</string>
<string name="uninstalling_cloned_app" msgid="1826380164974984870">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> کلون کو حذف کیا جا رہا ہے…"</string>
diff --git a/packages/PackageInstaller/res/values/strings.xml b/packages/PackageInstaller/res/values/strings.xml
index 6669e35..a2118fa 100644
--- a/packages/PackageInstaller/res/values/strings.xml
+++ b/packages/PackageInstaller/res/values/strings.xml
@@ -37,9 +37,8 @@
<string name="install_confirm_question">Do you want to install this app?</string>
<!-- Message for updating an existing app [CHAR LIMIT=NONE] -->
<string name="install_confirm_question_update">Do you want to update this app?</string>
- <!-- TODO(b/244413073) Revise the description after getting UX input and UXR on this. -->
- <!-- Message for updating an existing app with update owner reminder [DO NOT TRANSLATE][CHAR LIMIT=NONE] -->
- <string name="install_confirm_question_update_owner_reminder">Updates to this app are currently managed by <xliff:g id="existing_update_owner">%1$s</xliff:g>.\n\nDo you want to install this update from <xliff:g id="new_update_owner">%2$s</xliff:g>?</string>
+ <!-- Message for updating an existing app with update owner reminder [CHAR LIMIT=NONE] -->
+ <string name="install_confirm_question_update_owner_reminder">Update this app from <xliff:g id="new_update_owner">%1$s</xliff:g>?\n\nThis app normally receives updates from <xliff:g id="existing_update_owner">%2$s</xliff:g>. By updating from a different source, you may receive future updates from any source on your phone. App functionality may change.</string>
<!-- [CHAR LIMIT=100] -->
<string name="install_failed">App not installed.</string>
<!-- Reason displayed when installation fails because the package was blocked
@@ -82,6 +81,8 @@
<!-- [CHAR LIMIT=15] -->
<string name="ok">OK</string>
+ <!-- [CHAR LIMIT=30] -->
+ <string name="update_anyway">Update anyway</string>
<!-- [CHAR LIMIT=15] -->
<string name="manage_applications">Manage apps</string>
<!-- [CHAR LIMIT=30] -->
diff --git a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
index d41cfbc2..3ba2acb 100644
--- a/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
+++ b/packages/PackageInstaller/src/com/android/packageinstaller/PackageInstallerActivity.java
@@ -148,10 +148,11 @@
&& mPendingUserActionReason == PackageInstaller.REASON_REMIND_OWNERSHIP) {
viewToEnable.setText(
getString(R.string.install_confirm_question_update_owner_reminder,
- existingUpdateOwnerLabel, requestedUpdateOwnerLabel));
+ requestedUpdateOwnerLabel, existingUpdateOwnerLabel));
+ mOk.setText(R.string.update_anyway);
+ } else {
+ mOk.setText(R.string.update);
}
-
- mOk.setText(R.string.update);
} else {
// This is a new application with no permissions.
viewToEnable = requireViewById(R.id.install_confirm_question);
@@ -374,16 +375,15 @@
final int sessionId = intent.getIntExtra(PackageInstaller.EXTRA_SESSION_ID,
-1 /* defaultValue */);
final SessionInfo info = mInstaller.getSessionInfo(sessionId);
- final String resolvedBaseCodePath = intent.getStringExtra(
- PackageInstaller.EXTRA_RESOLVED_BASE_PATH);
- if (info == null || !info.isSealed() || resolvedBaseCodePath == null) {
+ String resolvedPath = info.getResolvedBaseApkPath();
+ if (info == null || !info.isSealed() || resolvedPath == null) {
Log.w(TAG, "Session " + mSessionId + " in funky state; ignoring");
finish();
return;
}
mSessionId = sessionId;
- packageSource = Uri.fromFile(new File(resolvedBaseCodePath));
+ packageSource = Uri.fromFile(new File(resolvedPath));
mOriginatingURI = null;
mReferrerURI = null;
mPendingUserActionReason = info.getPendingUserActionReason();
diff --git a/packages/SettingsLib/DeviceStateRotationLock/Android.bp b/packages/SettingsLib/DeviceStateRotationLock/Android.bp
index c642bd1..103309a 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/Android.bp
+++ b/packages/SettingsLib/DeviceStateRotationLock/Android.bp
@@ -10,7 +10,10 @@
android_library {
name: "SettingsLibDeviceStateRotationLock",
- srcs: ["src/**/*.java"],
+ srcs: [
+ "src/**/*.java",
+ "src/**/*.kt",
+ ],
min_sdk_version: "21",
}
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
index 10b004e..76e1df1 100644
--- a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/DeviceStateRotationLockSettingsManager.java
@@ -57,17 +57,19 @@
private final Handler mMainHandler = new Handler(Looper.getMainLooper());
private final Set<DeviceStateRotationLockSettingsListener> mListeners = new HashSet<>();
private final SecureSettings mSecureSettings;
- private String[] mDeviceStateRotationLockDefaults;
- private SparseIntArray mDeviceStateRotationLockSettings;
- private SparseIntArray mDeviceStateDefaultRotationLockSettings;
- private SparseIntArray mDeviceStateRotationLockFallbackSettings;
+ private final PosturesHelper mPosturesHelper;
+ private String[] mPostureRotationLockDefaults;
+ private SparseIntArray mPostureRotationLockSettings;
+ private SparseIntArray mPostureDefaultRotationLockSettings;
+ private SparseIntArray mPostureRotationLockFallbackSettings;
private String mLastSettingValue;
private List<SettableDeviceState> mSettableDeviceStates;
@VisibleForTesting
DeviceStateRotationLockSettingsManager(Context context, SecureSettings secureSettings) {
- this.mSecureSettings = secureSettings;
- mDeviceStateRotationLockDefaults =
+ mSecureSettings = secureSettings;
+ mPosturesHelper = new PosturesHelper(context);
+ mPostureRotationLockDefaults =
context.getResources()
.getStringArray(R.array.config_perDeviceStateRotationLockDefaults);
loadDefaults();
@@ -134,13 +136,14 @@
/** Updates the rotation lock setting for a specified device state. */
public void updateSetting(int deviceState, boolean rotationLocked) {
- if (mDeviceStateRotationLockFallbackSettings.indexOfKey(deviceState) >= 0) {
- // The setting for this device state is IGNORED, and has a fallback device state.
- // The setting for that fallback device state should be the changed in this case.
- deviceState = mDeviceStateRotationLockFallbackSettings.get(deviceState);
+ int posture = mPosturesHelper.deviceStateToPosture(deviceState);
+ if (mPostureRotationLockFallbackSettings.indexOfKey(posture) >= 0) {
+ // The setting for this device posture is IGNORED, and has a fallback posture.
+ // The setting for that fallback posture should be the changed in this case.
+ posture = mPostureRotationLockFallbackSettings.get(posture);
}
- mDeviceStateRotationLockSettings.put(
- deviceState,
+ mPostureRotationLockSettings.put(
+ posture,
rotationLocked
? DEVICE_STATE_ROTATION_LOCK_LOCKED
: DEVICE_STATE_ROTATION_LOCK_UNLOCKED);
@@ -159,22 +162,23 @@
*/
@Settings.Secure.DeviceStateRotationLockSetting
public int getRotationLockSetting(int deviceState) {
- int rotationLockSetting = mDeviceStateRotationLockSettings.get(
- deviceState, /* valueIfKeyNotFound= */ DEVICE_STATE_ROTATION_LOCK_IGNORED);
+ int devicePosture = mPosturesHelper.deviceStateToPosture(deviceState);
+ int rotationLockSetting = mPostureRotationLockSettings.get(
+ devicePosture, /* valueIfKeyNotFound= */ DEVICE_STATE_ROTATION_LOCK_IGNORED);
if (rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_IGNORED) {
- rotationLockSetting = getFallbackRotationLockSetting(deviceState);
+ rotationLockSetting = getFallbackRotationLockSetting(devicePosture);
}
return rotationLockSetting;
}
- private int getFallbackRotationLockSetting(int deviceState) {
- int indexOfFallbackState = mDeviceStateRotationLockFallbackSettings.indexOfKey(deviceState);
- if (indexOfFallbackState < 0) {
+ private int getFallbackRotationLockSetting(int devicePosture) {
+ int indexOfFallback = mPostureRotationLockFallbackSettings.indexOfKey(devicePosture);
+ if (indexOfFallback < 0) {
Log.w(TAG, "Setting is ignored, but no fallback was specified.");
return DEVICE_STATE_ROTATION_LOCK_IGNORED;
}
- int fallbackState = mDeviceStateRotationLockFallbackSettings.valueAt(indexOfFallbackState);
- return mDeviceStateRotationLockSettings.get(fallbackState,
+ int fallbackPosture = mPostureRotationLockFallbackSettings.valueAt(indexOfFallback);
+ return mPostureRotationLockSettings.get(fallbackPosture,
/* valueIfKeyNotFound= */ DEVICE_STATE_ROTATION_LOCK_IGNORED);
}
@@ -189,8 +193,8 @@
* DEVICE_STATE_ROTATION_LOCK_UNLOCKED}.
*/
public boolean isRotationLockedForAllStates() {
- for (int i = 0; i < mDeviceStateRotationLockSettings.size(); i++) {
- if (mDeviceStateRotationLockSettings.valueAt(i)
+ for (int i = 0; i < mPostureRotationLockSettings.size(); i++) {
+ if (mPostureRotationLockSettings.valueAt(i)
== DEVICE_STATE_ROTATION_LOCK_UNLOCKED) {
return false;
}
@@ -221,7 +225,7 @@
fallbackOnDefaults();
return;
}
- mDeviceStateRotationLockSettings = new SparseIntArray(values.length / 2);
+ mPostureRotationLockSettings = new SparseIntArray(values.length / 2);
int key;
int value;
@@ -230,7 +234,7 @@
key = Integer.parseInt(values[i++]);
value = Integer.parseInt(values[i++]);
boolean isPersistedValueIgnored = value == DEVICE_STATE_ROTATION_LOCK_IGNORED;
- boolean isDefaultValueIgnored = mDeviceStateDefaultRotationLockSettings.get(key)
+ boolean isDefaultValueIgnored = mPostureDefaultRotationLockSettings.get(key)
== DEVICE_STATE_ROTATION_LOCK_IGNORED;
if (isPersistedValueIgnored != isDefaultValueIgnored) {
Log.w(TAG, "Conflict for ignored device state " + key
@@ -238,7 +242,7 @@
fallbackOnDefaults();
return;
}
- mDeviceStateRotationLockSettings.put(key, value);
+ mPostureRotationLockSettings.put(key, value);
} catch (NumberFormatException e) {
Log.wtf(TAG, "Error deserializing one of the saved settings", e);
fallbackOnDefaults();
@@ -253,7 +257,7 @@
*/
@VisibleForTesting
public void resetStateForTesting(Resources resources) {
- mDeviceStateRotationLockDefaults =
+ mPostureRotationLockDefaults =
resources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults);
fallbackOnDefaults();
}
@@ -264,23 +268,23 @@
}
private void persistSettings() {
- if (mDeviceStateRotationLockSettings.size() == 0) {
+ if (mPostureRotationLockSettings.size() == 0) {
persistSettingIfChanged(/* newSettingValue= */ "");
return;
}
StringBuilder stringBuilder = new StringBuilder();
stringBuilder
- .append(mDeviceStateRotationLockSettings.keyAt(0))
+ .append(mPostureRotationLockSettings.keyAt(0))
.append(SEPARATOR_REGEX)
- .append(mDeviceStateRotationLockSettings.valueAt(0));
+ .append(mPostureRotationLockSettings.valueAt(0));
- for (int i = 1; i < mDeviceStateRotationLockSettings.size(); i++) {
+ for (int i = 1; i < mPostureRotationLockSettings.size(); i++) {
stringBuilder
.append(SEPARATOR_REGEX)
- .append(mDeviceStateRotationLockSettings.keyAt(i))
+ .append(mPostureRotationLockSettings.keyAt(i))
.append(SEPARATOR_REGEX)
- .append(mDeviceStateRotationLockSettings.valueAt(i));
+ .append(mPostureRotationLockSettings.valueAt(i));
}
persistSettingIfChanged(stringBuilder.toString());
}
@@ -300,22 +304,20 @@
}
private void loadDefaults() {
- mSettableDeviceStates = new ArrayList<>(mDeviceStateRotationLockDefaults.length);
- mDeviceStateDefaultRotationLockSettings = new SparseIntArray(
- mDeviceStateRotationLockDefaults.length);
- mDeviceStateRotationLockSettings = new SparseIntArray(
- mDeviceStateRotationLockDefaults.length);
- mDeviceStateRotationLockFallbackSettings = new SparseIntArray(1);
- for (String entry : mDeviceStateRotationLockDefaults) {
+ mSettableDeviceStates = new ArrayList<>(mPostureRotationLockDefaults.length);
+ mPostureDefaultRotationLockSettings = new SparseIntArray(
+ mPostureRotationLockDefaults.length);
+ mPostureRotationLockSettings = new SparseIntArray(mPostureRotationLockDefaults.length);
+ mPostureRotationLockFallbackSettings = new SparseIntArray(1);
+ for (String entry : mPostureRotationLockDefaults) {
String[] values = entry.split(SEPARATOR_REGEX);
try {
- int deviceState = Integer.parseInt(values[0]);
+ int posture = Integer.parseInt(values[0]);
int rotationLockSetting = Integer.parseInt(values[1]);
if (rotationLockSetting == DEVICE_STATE_ROTATION_LOCK_IGNORED) {
if (values.length == 3) {
- int fallbackDeviceState = Integer.parseInt(values[2]);
- mDeviceStateRotationLockFallbackSettings.put(deviceState,
- fallbackDeviceState);
+ int fallbackPosture = Integer.parseInt(values[2]);
+ mPostureRotationLockFallbackSettings.put(posture, fallbackPosture);
} else {
Log.w(TAG,
"Rotation lock setting is IGNORED, but values have unexpected "
@@ -324,9 +326,14 @@
}
}
boolean isSettable = rotationLockSetting != DEVICE_STATE_ROTATION_LOCK_IGNORED;
- mSettableDeviceStates.add(new SettableDeviceState(deviceState, isSettable));
- mDeviceStateRotationLockSettings.put(deviceState, rotationLockSetting);
- mDeviceStateDefaultRotationLockSettings.put(deviceState, rotationLockSetting);
+ Integer deviceState = mPosturesHelper.postureToDeviceState(posture);
+ if (deviceState != null) {
+ mSettableDeviceStates.add(new SettableDeviceState(deviceState, isSettable));
+ } else {
+ Log.wtf(TAG, "No matching device state for posture: " + posture);
+ }
+ mPostureRotationLockSettings.put(posture, rotationLockSetting);
+ mPostureDefaultRotationLockSettings.put(posture, rotationLockSetting);
} catch (NumberFormatException e) {
Log.wtf(TAG, "Error parsing settings entry. Entry was: " + entry, e);
return;
@@ -338,13 +345,11 @@
public void dump(IndentingPrintWriter pw) {
pw.println("DeviceStateRotationLockSettingsManager");
pw.increaseIndent();
- pw.println("mDeviceStateRotationLockDefaults: " + Arrays.toString(
- mDeviceStateRotationLockDefaults));
- pw.println("mDeviceStateDefaultRotationLockSettings: "
- + mDeviceStateDefaultRotationLockSettings);
- pw.println("mDeviceStateRotationLockSettings: " + mDeviceStateRotationLockSettings);
- pw.println("mDeviceStateRotationLockFallbackSettings: "
- + mDeviceStateRotationLockFallbackSettings);
+ pw.println("mPostureRotationLockDefaults: "
+ + Arrays.toString(mPostureRotationLockDefaults));
+ pw.println("mPostureDefaultRotationLockSettings: " + mPostureDefaultRotationLockSettings);
+ pw.println("mDeviceStateRotationLockSettings: " + mPostureRotationLockSettings);
+ pw.println("mPostureRotationLockFallbackSettings: " + mPostureRotationLockFallbackSettings);
pw.println("mSettableDeviceStates: " + mSettableDeviceStates);
pw.println("mLastSettingValue: " + mLastSettingValue);
pw.decreaseIndent();
diff --git a/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt
new file mode 100644
index 0000000..9c70be9
--- /dev/null
+++ b/packages/SettingsLib/DeviceStateRotationLock/src/com.android.settingslib.devicestate/PosturesHelper.kt
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.settingslib.devicestate
+
+import android.content.Context
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_HALF_FOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNFOLDED
+import android.provider.Settings.Secure.DEVICE_STATE_ROTATION_KEY_UNKNOWN
+import android.provider.Settings.Secure.DeviceStateRotationLockKey
+import com.android.internal.R
+
+/** Helps to convert between device state and posture. */
+class PosturesHelper(context: Context) {
+
+ private val foldedDeviceStates =
+ context.resources.getIntArray(R.array.config_foldedDeviceStates)
+ private val halfFoldedDeviceStates =
+ context.resources.getIntArray(R.array.config_halfFoldedDeviceStates)
+ private val unfoldedDeviceStates =
+ context.resources.getIntArray(R.array.config_openDeviceStates)
+
+ @DeviceStateRotationLockKey
+ fun deviceStateToPosture(deviceState: Int): Int {
+ return when (deviceState) {
+ in foldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_FOLDED
+ in halfFoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_HALF_FOLDED
+ in unfoldedDeviceStates -> DEVICE_STATE_ROTATION_KEY_UNFOLDED
+ else -> DEVICE_STATE_ROTATION_KEY_UNKNOWN
+ }
+ }
+
+ fun postureToDeviceState(@DeviceStateRotationLockKey posture: Int): Int? {
+ return when (posture) {
+ DEVICE_STATE_ROTATION_KEY_FOLDED -> foldedDeviceStates.firstOrNull()
+ DEVICE_STATE_ROTATION_KEY_HALF_FOLDED -> halfFoldedDeviceStates.firstOrNull()
+ DEVICE_STATE_ROTATION_KEY_UNFOLDED -> unfoldedDeviceStates.firstOrNull()
+ else -> null
+ }
+ }
+}
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaLogger.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaLogger.kt
index ca88f8d..215f6b9 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaLogger.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/framework/common/SpaLogger.kt
@@ -16,7 +16,6 @@
package com.android.settingslib.spa.framework.common
-import android.app.settings.SettingsEnums
import android.os.Bundle
// Defines the category of the log, for quick filter
@@ -32,14 +31,14 @@
}
// Defines the log events in Spa.
-enum class LogEvent(val action: Int) {
+enum class LogEvent {
// Page related events.
- PAGE_ENTER(SettingsEnums.PAGE_VISIBLE),
- PAGE_LEAVE(SettingsEnums.PAGE_HIDE),
+ PAGE_ENTER,
+ PAGE_LEAVE,
// Entry related events.
- ENTRY_CLICK(SettingsEnums.ACTION_SETTINGS_TILE_CLICK),
- ENTRY_SWITCH(SettingsEnums.ACTION_SETTINGS_PREFERENCE_CHANGE),
+ ENTRY_CLICK,
+ ENTRY_SWITCH,
}
internal const val LOG_DATA_DISPLAY_NAME = "name"
diff --git a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
index f6bb3cc..47ac2df 100644
--- a/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
+++ b/packages/SettingsLib/Spa/spa/src/com/android/settingslib/spa/widget/scaffold/CustomizedAppBar.kt
@@ -109,7 +109,7 @@
scrollBehavior: TopAppBarScrollBehavior? = null,
) {
TwoRowsTopAppBar(
- title = { Title(title = title, maxLines = 2) },
+ title = { Title(title = title, maxLines = 3) },
titleTextStyle = MaterialTheme.typography.displaySmall,
smallTitleTextStyle = MaterialTheme.typography.titleMedium,
titleBottomPadding = LargeTitleBottomPadding,
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-el/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-el/strings.xml
index ac4106a..8ac56d4 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-el/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-el/strings.xml
@@ -23,5 +23,5 @@
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"Επιτρέπεται"</string>
<string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Δεν επιτρέπεται"</string>
<string name="version_text" msgid="4001669804596458577">"έκδοση <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
- <string name="cloned_app_info_label" msgid="1765651167024478391">"Κλώνος <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_info_label" msgid="1765651167024478391">"Διπλότυπο <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-et/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-et/strings.xml
index a216abc..4bfc25f 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-et/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-et/strings.xml
@@ -23,5 +23,5 @@
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"Lubatud"</string>
<string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Pole lubatud"</string>
<string name="version_text" msgid="4001669804596458577">"versioon <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
- <string name="cloned_app_info_label" msgid="1765651167024478391">"Üksuse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kloon"</string>
+ <string name="cloned_app_info_label" msgid="1765651167024478391">"Rakenduse <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> kloon"</string>
</resources>
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-fa/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-fa/strings.xml
index 8654c64..30ed347 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-fa/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-fa/strings.xml
@@ -23,5 +23,5 @@
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"مجاز"</string>
<string name="app_permission_summary_not_allowed" msgid="58396132188553920">"غیرمجاز"</string>
<string name="version_text" msgid="4001669804596458577">"نسخه <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
- <string name="cloned_app_info_label" msgid="1765651167024478391">"همتای <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_info_label" msgid="1765651167024478391">"همسانه <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-fi/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-fi/strings.xml
index 8f42d50..b7895e2 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-fi/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-fi/strings.xml
@@ -23,5 +23,5 @@
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"Sallittu"</string>
<string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Ei sallittu"</string>
<string name="version_text" msgid="4001669804596458577">"versio <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
- <string name="cloned_app_info_label" msgid="1765651167024478391">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> klooni"</string>
+ <string name="cloned_app_info_label" msgid="1765651167024478391">"Klooni: <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-mn/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-mn/strings.xml
index 2074222..9150424 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-mn/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-mn/strings.xml
@@ -23,5 +23,5 @@
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"Зөвшөөрсөн"</string>
<string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Зөвшөөрөөгүй"</string>
<string name="version_text" msgid="4001669804596458577">"хувилбар <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
- <string name="cloned_app_info_label" msgid="1765651167024478391">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g> клон"</string>
+ <string name="cloned_app_info_label" msgid="1765651167024478391">"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>-н хувилал"</string>
</resources>
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-pl/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-pl/strings.xml
index c947a66..b0fd2bf 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-pl/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-pl/strings.xml
@@ -23,5 +23,5 @@
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"Dozwolone"</string>
<string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Niedozwolone"</string>
<string name="version_text" msgid="4001669804596458577">"wersja <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
- <string name="cloned_app_info_label" msgid="1765651167024478391">"Klonuj: <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_info_label" msgid="1765651167024478391">"Klon aplikacji <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-ru/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-ru/strings.xml
index 3507bc7..960d94f 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-ru/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-ru/strings.xml
@@ -23,5 +23,5 @@
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"Разрешено"</string>
<string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Запрещено"</string>
<string name="version_text" msgid="4001669804596458577">"версия <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
- <string name="cloned_app_info_label" msgid="1765651167024478391">"Клон приложения \"<xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>\""</string>
+ <string name="cloned_app_info_label" msgid="1765651167024478391">"Клон приложения <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/SpaPrivileged/res/values-sl/strings.xml b/packages/SettingsLib/SpaPrivileged/res/values-sl/strings.xml
index 74b3ffd..2451d61 100644
--- a/packages/SettingsLib/SpaPrivileged/res/values-sl/strings.xml
+++ b/packages/SettingsLib/SpaPrivileged/res/values-sl/strings.xml
@@ -23,5 +23,5 @@
<string name="app_permission_summary_allowed" msgid="6115213465364138103">"Dovoljeno"</string>
<string name="app_permission_summary_not_allowed" msgid="58396132188553920">"Ni dovoljeno"</string>
<string name="version_text" msgid="4001669804596458577">"različica <xliff:g id="VERSION_NUM">%1$s</xliff:g>"</string>
- <string name="cloned_app_info_label" msgid="1765651167024478391">"Klonirani paket <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
+ <string name="cloned_app_info_label" msgid="1765651167024478391">"Klonirana aplikacija <xliff:g id="PACKAGE_LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
index c609004..9f33fcb 100644
--- a/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
+++ b/packages/SettingsLib/SpaPrivileged/src/com/android/settingslib/spaprivileged/model/app/AppOpsController.kt
@@ -62,10 +62,12 @@
}
val permission = AppOpsManager.opToPermission(op)
- packageManager.updatePermissionFlags(permission, app.packageName,
- PackageManager.FLAG_PERMISSION_USER_SET, PackageManager.FLAG_PERMISSION_USER_SET,
- UserHandle.getUserHandleForUid(app.uid))
-
+ if (permission != null) {
+ packageManager.updatePermissionFlags(permission, app.packageName,
+ PackageManager.FLAG_PERMISSION_USER_SET,
+ PackageManager.FLAG_PERMISSION_USER_SET,
+ UserHandle.getUserHandleForUid(app.uid))
+ }
_mode.postValue(mode)
}
diff --git a/packages/SettingsLib/res/values-af/arrays.xml b/packages/SettingsLib/res/values-af/arrays.xml
index 28f7c50..41499b0 100644
--- a/packages/SettingsLib/res/values-af/arrays.xml
+++ b/packages/SettingsLib/res/values-af/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Het gefiltreer geaktiveer"</item>
<item msgid="2779123106632690576">"Geaktiveer"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Los slegs ACL-opskrifte"</item>
+ <item msgid="2776218217644557831">"Filtreer A2DP-mediapakkette"</item>
+ <item msgid="8163235976612675092">"Filtreer RFCOMM-kanaal"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Deaktiveer"</item>
+ <item msgid="2505973306504851132">"Vul met string karakters"</item>
+ <item msgid="5883011000629613855">"Los slegs opskrif"</item>
+ <item msgid="1051534112762023603">"Verwyder heeltemal"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (verstek)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-af/strings.xml b/packages/SettingsLib/res/values-af/strings.xml
index 3de581e..f44b301 100644
--- a/packages/SettingsLib/res/values-af/strings.xml
+++ b/packages/SettingsLib/res/values-af/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Wys snitgrense, kantlyne, ens."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Dwing RTL-uitlegrigting"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Dwing skermuitlegrigting na RTL vir alle locales"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Deursigtige navigasiebalk"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Maak navigasiebalk se agtergrondkleur by verstek deursigtig"</string>
<string name="window_blurs" msgid="6831008984828425106">"Laat venstervlakwasighede toe"</string>
<string name="force_msaa" msgid="4081288296137775550">"Dwing 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Aktiveer 4x MSAA in OpenGL ES 2.0-programme"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Skuif regs"</item>
<item msgid="324200556467459329">"Skuif op"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-am/arrays.xml b/packages/SettingsLib/res/values-am/arrays.xml
index c423d3c..e8e404f 100644
--- a/packages/SettingsLib/res/values-am/arrays.xml
+++ b/packages/SettingsLib/res/values-am/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"ማጣሪያን አንቃ"</item>
<item msgid="2779123106632690576">"ነቅቷል"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL ራስጌዎችን ብቻ ይተዉ"</item>
+ <item msgid="2776218217644557831">"A2DP ሚዲያ ፓኬቶችን ያጣሩ"</item>
+ <item msgid="8163235976612675092">"የRFCOMM ሰርጥን ያጣሩ"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"ያሰናክሉ"</item>
+ <item msgid="2505973306504851132">"በቁምፊዎች ሕብረቁምፊ ሙላ"</item>
+ <item msgid="5883011000629613855">"ራስጌ ብቻ ይተዉ"</item>
+ <item msgid="1051534112762023603">"በሙሉ ያስወግዱ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ነባሪ)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-am/strings.xml b/packages/SettingsLib/res/values-am/strings.xml
index b9117ee..492e294 100644
--- a/packages/SettingsLib/res/values-am/strings.xml
+++ b/packages/SettingsLib/res/values-am/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"የቅንጥብ ገደቦች፣ ጠርዞች፣ ወዘተ አሳይ"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"የቀኝ-ወደ-ግራ አቀማመጥ አቅጣጫ አስገድድ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ለሁሉም አካባቢዎች የማያ ገጽ አቀማመጥ ከቀኝ-ወደ-ግራ እንዲሆን አስገድድ"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"የግልፅነት የአሰሳ አሞሌ"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"የአሰሳ አሞሌ የዳራ ቀለምን በነባሪ ግልጽ አድርግ"</string>
<string name="window_blurs" msgid="6831008984828425106">"የመስኮት ደረጃ ብዥታዎችን ፍቀድ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA አስገድድ"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"4x MSAA በ OpenGL ES 2.0 መተግበሪያዎች ውስጥ ያንቁ"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"ወደ ቀኝ ውሰድ"</item>
<item msgid="324200556467459329">"ወደ ላይ ውሰድ"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ar/arrays.xml b/packages/SettingsLib/res/values-ar/arrays.xml
index cf46a8f..cb1ec38 100644
--- a/packages/SettingsLib/res/values-ar/arrays.xml
+++ b/packages/SettingsLib/res/values-ar/arrays.xml
@@ -60,16 +60,20 @@
</string-array>
<string-array name="bt_hci_snoop_log_entries">
<item msgid="695678520785580527">"غير مفعّل"</item>
- <item msgid="6336372935919715515">"تمّ تفعيل التصفية"</item>
+ <item msgid="6336372935919715515">"تمّ تفعيل الفلترة"</item>
<item msgid="2779123106632690576">"مفعّل"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ترك رؤوس ACL فقط"</item>
+ <item msgid="2776218217644557831">"فلترة حُزم وسائط A2DP"</item>
+ <item msgid="8163235976612675092">"فلترة قناة بروتوكول RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"إيقاف"</item>
+ <item msgid="2505973306504851132">"الملء بسلسلة من الأحرف"</item>
+ <item msgid="5883011000629613855">"ترك الرأس فقط"</item>
+ <item msgid="1051534112762023603">"الإزالة بالكامل"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (تلقائي)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ar/strings.xml b/packages/SettingsLib/res/values-ar/strings.xml
index ef7bf08..c3408cf 100644
--- a/packages/SettingsLib/res/values-ar/strings.xml
+++ b/packages/SettingsLib/res/values-ar/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"عرض حدود وهوامش المقطع وما إلى ذلك"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"فرض اتجاه التنسيق ليكون من اليمين إلى اليسار"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"فرض اتجاه تنسيق الشاشة ليكون من اليمين إلى اليسار لجميع اللغات"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"شريط تنقّل شفاف"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"جعل لون خلفية شريط التنقّل شفافًا بشكل تلقائي"</string>
<string name="window_blurs" msgid="6831008984828425106">"السماح بعمليات التعتيم على مستوى النافذة"</string>
<string name="force_msaa" msgid="4081288296137775550">"فرض 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"تفعيل 4x MSAA في تطبيقات OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"نقل لليمين"</item>
<item msgid="324200556467459329">"نقل للأعلى"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-as/arrays.xml b/packages/SettingsLib/res/values-as/arrays.xml
index 284ca12..539b8a6 100644
--- a/packages/SettingsLib/res/values-as/arrays.xml
+++ b/packages/SettingsLib/res/values-as/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"সক্ষম কৰাবিলাক ফিল্টাৰ কৰা হৈছে"</item>
<item msgid="2779123106632690576">"সক্ষম কৰা আছে"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"কেৱল ACL হেডাৰ এৰক"</item>
+ <item msgid="2776218217644557831">"A2DP মিডিয়াৰ পেকেট ফিল্টাৰ কৰক"</item>
+ <item msgid="8163235976612675092">"RFCOMM চেনেল ফিল্টাৰ কৰক"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"অক্ষম কৰক"</item>
+ <item msgid="2505973306504851132">"বৰ্ণৰ ষ্ট্ৰীঙেৰে পূৰ কৰক"</item>
+ <item msgid="5883011000629613855">"কেৱল হেডাৰ এৰক"</item>
+ <item msgid="1051534112762023603">"সম্পূৰ্ণকৈ আঁতৰাওক"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ডিফ’ল্ট)"</item>
<item msgid="1637054408779685086">"AVRCP ১.৩"</item>
diff --git a/packages/SettingsLib/res/values-as/strings.xml b/packages/SettingsLib/res/values-as/strings.xml
index 67b18da..ef1f3bf 100644
--- a/packages/SettingsLib/res/values-as/strings.xml
+++ b/packages/SettingsLib/res/values-as/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ক্লিপ বাউণ্ড, মাৰ্জিন আদিসমূহ দেখুৱাওক"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"আৰটিএল চানেকিৰ দিশ বলেৰে সলনি কৰক"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"আটাইবোৰ ভাষাৰ বাবে স্ক্ৰীনৰ চানেকিৰ দিশ RTLলৈ বলেৰে সলনি কৰক"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"স্বচ্ছ নেভিগেশ্বন বাৰ"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ডিফ’ল্ট হিচাপে নেভিগেশ্বন বাৰ পটভূমিৰ ৰং স্বচ্ছ কৰক"</string>
<string name="window_blurs" msgid="6831008984828425106">"ৱিণ্ড’ স্তৰত অস্পষ্ট কৰাৰ অনুমতি দিয়ক"</string>
<string name="force_msaa" msgid="4081288296137775550">"বল ৪গুণ MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 এপত ৪গুণ MSAA সক্ষম কৰক"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"সোঁফাললৈ নিয়ক"</item>
<item msgid="324200556467459329">"ওপৰলৈ নিয়ক"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-az/arrays.xml b/packages/SettingsLib/res/values-az/arrays.xml
index ff0054b..f01def0 100644
--- a/packages/SettingsLib/res/values-az/arrays.xml
+++ b/packages/SettingsLib/res/values-az/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtrləmə aktivdir"</item>
<item msgid="2779123106632690576">"Aktivdir"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Yalnız ACL başlıqlarını saxlayın"</item>
+ <item msgid="2776218217644557831">"A2DP media paketlərini filtrləyin"</item>
+ <item msgid="8163235976612675092">"RFCOMM kanalını filtrləyin"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Deaktiv edin"</item>
+ <item msgid="2505973306504851132">"Simvollar sətri ilə doldurun"</item>
+ <item msgid="5883011000629613855">"Yalnız başlığı saxlayın"</item>
+ <item msgid="1051534112762023603">"Tam silin"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Defolt)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-az/strings.xml b/packages/SettingsLib/res/values-az/strings.xml
index 000fd1b..cb476e2 100644
--- a/packages/SettingsLib/res/values-az/strings.xml
+++ b/packages/SettingsLib/res/values-az/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Kəsim sərhəddi, sahəsi və digər şeyləri göstərilsin"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL düzən istiqamətinə məcbur edin"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Ekran düzən istiqamətini RTL üzərinə bütün yerli variantlar üçün məcbur edin"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Şəffaf naviqasiya paneli"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Naviqasiya panelinin arxa fon rəngini defolt olaraq şəffaf edin"</string>
<string name="window_blurs" msgid="6831008984828425106">"Pəncərə səviyyəsində bulanıqlığa icazə verin"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA aktiv edilsin"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 tətbiqlərində 4x MSAA aktiv edilsin"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Sağa köçürün"</item>
<item msgid="324200556467459329">"Yuxarı köçürün"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
index 32071e5..772c339 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Omogućeno filtrirano"</item>
<item msgid="2779123106632690576">"Omogućeno"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Zadržite samo ACL zaglavlja"</item>
+ <item msgid="2776218217644557831">"Filtrirajte A2DP medijske pakete"</item>
+ <item msgid="8163235976612675092">"Filtrirajte RFCOMM kanal"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Onemogućite"</item>
+ <item msgid="2505973306504851132">"Ispunite stringom znakova"</item>
+ <item msgid="5883011000629613855">"Zadržite samo zaglavlje"</item>
+ <item msgid="1051534112762023603">"Uklonite u potpunosti"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (podrazumevano)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
index 6a9ba8a..c87f8aa 100644
--- a/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
+++ b/packages/SettingsLib/res/values-b+sr+Latn/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Prikazuje granice klipa, margine itd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Nametni smer rasporeda zdesna nalevo"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Nameće smer rasporeda ekrana zdesna nalevo za sve lokalitete"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Prozirna traka za navigaciju"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Neka boja pozadine trake za navigaciju bude podrazumevano prozirna"</string>
<string name="window_blurs" msgid="6831008984828425106">"Dozvoli zamagljenja prozora"</string>
<string name="force_msaa" msgid="4081288296137775550">"Nametni 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Omogućava 4x MSAA u OpenGL ES 2.0 aplikacijama"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Pomerite nadesno"</item>
<item msgid="324200556467459329">"Pomerite nagore"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-be/arrays.xml b/packages/SettingsLib/res/values-be/arrays.xml
index a60d354..d253725 100644
--- a/packages/SettingsLib/res/values-be/arrays.xml
+++ b/packages/SettingsLib/res/values-be/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Уключана з фільтрацыяй"</item>
<item msgid="2779123106632690576">"Уключана"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Пакінуць толькі загалоўкі ACL"</item>
+ <item msgid="2776218217644557831">"Адфільтраваць пакеты мультымедыя A2DP"</item>
+ <item msgid="8163235976612675092">"Адфільтраваць канал RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Адключыць"</item>
+ <item msgid="2505973306504851132">"Увесці радок сімвалаў"</item>
+ <item msgid="5883011000629613855">"Пакінуць толькі загаловак"</item>
+ <item msgid="1051534112762023603">"Цалкам выдаліць"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (стандартная)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-be/strings.xml b/packages/SettingsLib/res/values-be/strings.xml
index f93ca4b..3e9bbb0 100644
--- a/packages/SettingsLib/res/values-be/strings.xml
+++ b/packages/SettingsLib/res/values-be/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Паказаць межы абрэзкі, палі і г. д."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Прымусовая раскладка справа налева"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Прымусовая раскладка экрана справа налева для ўсіх рэгіянальных налад"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Празрыстая панэль навігацыі"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Стандартна зрабіць фонавы колер панэлі навігацыі празрыстым"</string>
<string name="window_blurs" msgid="6831008984828425106">"Размываць на ўзроўні акна"</string>
<string name="force_msaa" msgid="4081288296137775550">"Прымусовае выкананне 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Уключыць 4x MSAA у праграмах з OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Перамясціць управа"</item>
<item msgid="324200556467459329">"Перамясціць уверх"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bg/arrays.xml b/packages/SettingsLib/res/values-bg/arrays.xml
index d778ca2..6be8827 100644
--- a/packages/SettingsLib/res/values-bg/arrays.xml
+++ b/packages/SettingsLib/res/values-bg/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Филтрирането е активирано"</item>
<item msgid="2779123106632690576">"Активирано"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Запазване само на ACL заглавките"</item>
+ <item msgid="2776218217644557831">"Филтриране на мултимедийните пакети A2DP"</item>
+ <item msgid="8163235976612675092">"Филтриране на канала RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Деактивиране"</item>
+ <item msgid="2505973306504851132">"Попълване с низ от знаци"</item>
+ <item msgid="5883011000629613855">"Запазване само на заглавката"</item>
+ <item msgid="1051534112762023603">"Пълно премахване"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (основно)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-bg/strings.xml b/packages/SettingsLib/res/values-bg/strings.xml
index 650f405..9f425a88 100644
--- a/packages/SettingsLib/res/values-bg/strings.xml
+++ b/packages/SettingsLib/res/values-bg/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Показв. на границите на изрязване, полетата и др."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Принуд. оформл. от дясно наляво"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Принудително оформление на екрана от дясно наляво за всички локали"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Прозрачна лента за навигация"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Задаване на прозрачен фон по подразбиране за лентата за навигация"</string>
<string name="window_blurs" msgid="6831008984828425106">"Замъгл. на ниво прозорец"</string>
<string name="force_msaa" msgid="4081288296137775550">"Задаване на 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Активиране на 4x MSAA в прилож. с OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Преместване надясно"</item>
<item msgid="324200556467459329">"Преместване нагоре"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bn/arrays.xml b/packages/SettingsLib/res/values-bn/arrays.xml
index dbb738c..b0a1c29 100644
--- a/packages/SettingsLib/res/values-bn/arrays.xml
+++ b/packages/SettingsLib/res/values-bn/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"ফিল্টার করা চালু আছে"</item>
<item msgid="2779123106632690576">"চালু করা আছে"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"শুধু ACL হেডার রাখুন"</item>
+ <item msgid="2776218217644557831">"A2DP মিডিয়া প্যাকেট ফিল্টার করুন"</item>
+ <item msgid="8163235976612675092">"RFCOMM চ্যানেল ফিল্টার করুন"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"বন্ধ করুন"</item>
+ <item msgid="2505973306504851132">"অক্ষরের স্ট্রিং ব্যবহার করে পূরণ করুন"</item>
+ <item msgid="5883011000629613855">"শুধু হেডার রেখে দিন"</item>
+ <item msgid="1051534112762023603">"সম্পূর্ণভাবে সরান"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ডিফল্ট)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-bn/strings.xml b/packages/SettingsLib/res/values-bn/strings.xml
index 1faee6a..1a353d7 100644
--- a/packages/SettingsLib/res/values-bn/strings.xml
+++ b/packages/SettingsLib/res/values-bn/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ক্লিপ বাউন্ড, মার্জিন ইত্যাদি দেখান"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL লেআউট দিকনির্দেশ জোর দিন"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"সমস্ত স্থানের জন্য RTL এ স্ক্রিন লেআউট দিকনির্দেশে জোর দেয়"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"স্বচ্ছ নেভিগেশন বার"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ডিফল্ট হিসেবে, নেভিগেশন বারের ব্যাকগ্রাউন্ড কালার স্বচ্ছ রাখুন"</string>
<string name="window_blurs" msgid="6831008984828425106">"উইন্ডো-লেভেল অস্পষ্ট করার সুবিধা চালু করুন"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA-এ জোর দিন"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 অ্যাপের মধ্যে 4x MSAA চালু করুন"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"ডানদিকে সরান"</item>
<item msgid="324200556467459329">"উপরে সরান"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-bs/arrays.xml b/packages/SettingsLib/res/values-bs/arrays.xml
index 740e704..77d9a20 100644
--- a/packages/SettingsLib/res/values-bs/arrays.xml
+++ b/packages/SettingsLib/res/values-bs/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Omogućeno filtrirano"</item>
<item msgid="2779123106632690576">"Omogućeno"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Ostavi samo ACL zaglavlja"</item>
+ <item msgid="2776218217644557831">"Filtriraj A2DP medijske pakete"</item>
+ <item msgid="8163235976612675092">"Filtriraj RFCOMM kanal"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Onemogući"</item>
+ <item msgid="2505973306504851132">"Ispuni nizom znakova"</item>
+ <item msgid="5883011000629613855">"Ostavi samo zaglavlje"</item>
+ <item msgid="1051534112762023603">"Potpuno ukloni"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (zadano)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-bs/strings.xml b/packages/SettingsLib/res/values-bs/strings.xml
index 1aa8ff3..8139dc3 100644
--- a/packages/SettingsLib/res/values-bs/strings.xml
+++ b/packages/SettingsLib/res/values-bs/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Prikaz granica isječka, margina itd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Prisilno postavi raspored s desna ulijevo"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Prisilno postavljanje rasporeda ekrana s desna ulijevo za sve regije"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Providna navigacijska traka"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Postavite boju pozadine navigacijske trake na providno prema zadanim postavkama"</string>
<string name="window_blurs" msgid="6831008984828425106">"Dozvoli zamućenja prozora"</string>
<string name="force_msaa" msgid="4081288296137775550">"Prinudno primijeni 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Omogućava 4x MSAA u OpenGL ES 2.0 aplikacijama"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Pomjeranje udesno"</item>
<item msgid="324200556467459329">"Pomjeranje nagore"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ca/arrays.xml b/packages/SettingsLib/res/values-ca/arrays.xml
index 4e437ba..f50f9b2 100644
--- a/packages/SettingsLib/res/values-ca/arrays.xml
+++ b/packages/SettingsLib/res/values-ca/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Activat amb filtres"</item>
<item msgid="2779123106632690576">"Activat"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Deixa només les capçaleres d\'ACL"</item>
+ <item msgid="2776218217644557831">"Filtra els paquets multimèdia A2DP"</item>
+ <item msgid="8163235976612675092">"Filtra el canal RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Desactiva"</item>
+ <item msgid="2505973306504851132">"Emplena amb una cadena de caràcters"</item>
+ <item msgid="5883011000629613855">"Deixa només la capçalera"</item>
+ <item msgid="1051534112762023603">"Suprimeix completament"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (predeterminada)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ca/strings.xml b/packages/SettingsLib/res/values-ca/strings.xml
index f14befd..36a7c30 100644
--- a/packages/SettingsLib/res/values-ca/strings.xml
+++ b/packages/SettingsLib/res/values-ca/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostra els límits de clips, els marges, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Força direcció dreta-esquerra"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Força direcció de pantalla dreta-esquerra en totes les llengües"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barra de navegació transparent"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Fes que el color de fons de la barra de navegació sigui transparent de manera predeterminada"</string>
<string name="window_blurs" msgid="6831008984828425106">"Permet desenfoc. finestra"</string>
<string name="force_msaa" msgid="4081288296137775550">"Força MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activa MSAA 4x en aplicacions d\'OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Mou cap a la dreta"</item>
<item msgid="324200556467459329">"Mou cap amunt"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-cs/arrays.xml b/packages/SettingsLib/res/values-cs/arrays.xml
index e1a5aef..034a133 100644
--- a/packages/SettingsLib/res/values-cs/arrays.xml
+++ b/packages/SettingsLib/res/values-cs/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Povolit filtrované"</item>
<item msgid="2779123106632690576">"Zapnuto"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Nechat pouze záhlaví ACL"</item>
+ <item msgid="2776218217644557831">"Filtrovat mediální pakety A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrovat kanál RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Deaktivovat"</item>
+ <item msgid="2505973306504851132">"Vyplnit řetězcem znaků"</item>
+ <item msgid="5883011000629613855">"Nechat pouze záhlaví"</item>
+ <item msgid="1051534112762023603">"Zcela odstranit"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (výchozí)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-cs/strings.xml b/packages/SettingsLib/res/values-cs/strings.xml
index e511f04..b695dfc 100644
--- a/packages/SettingsLib/res/values-cs/strings.xml
+++ b/packages/SettingsLib/res/values-cs/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"U výstřižku zobrazit ohraničení, okraje atd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Vynutit rozvržení zprava doleva"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Vynutit ve všech jazycích rozvržení obrazovky zprava doleva"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Průhledný navigační panel"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Nastavit ve výchozím nastavení barvu navigačního panelu na průhlednou"</string>
<string name="window_blurs" msgid="6831008984828425106">"Povolit rozmazávání oken"</string>
<string name="force_msaa" msgid="4081288296137775550">"Vynutit 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Povolit 4x MSAA v aplikacích OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Přesunout doprava"</item>
<item msgid="324200556467459329">"Přesunout nahoru"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-da/arrays.xml b/packages/SettingsLib/res/values-da/arrays.xml
index 03cab20..9f3db17 100644
--- a/packages/SettingsLib/res/values-da/arrays.xml
+++ b/packages/SettingsLib/res/values-da/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtreret er aktiveret"</item>
<item msgid="2779123106632690576">"Aktiveret"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Udfyld alt pånær ACL-headere"</item>
+ <item msgid="2776218217644557831">"Filtrér A2DP-mediepakker"</item>
+ <item msgid="8163235976612675092">"Filtrér RFCOMM-kanal"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Deaktiver"</item>
+ <item msgid="2505973306504851132">"Udfyld med streng af tegn"</item>
+ <item msgid="5883011000629613855">"Udfyld alt pånær header"</item>
+ <item msgid="1051534112762023603">"Fjern helt"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (standard)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index c52c661..d61ee26 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Vis grænser for klip, margener osv."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Tving læsning mod venstre"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Gennemtving højre mod venstre-layout for alle sprog"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Gennemsigtig navigationslinje"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Gør navigationslinjens baggrundsfarve gennemsigtig som standard"</string>
<string name="window_blurs" msgid="6831008984828425106">"Tillad vinduessløring"</string>
<string name="force_msaa" msgid="4081288296137775550">"Gennemtving 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Aktivér 4x MSAA i apps med OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Flyt til højre"</item>
<item msgid="324200556467459329">"Flyt op"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-de/arrays.xml b/packages/SettingsLib/res/values-de/arrays.xml
index c5dcc10..05c4630 100644
--- a/packages/SettingsLib/res/values-de/arrays.xml
+++ b/packages/SettingsLib/res/values-de/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filter aktiviert"</item>
<item msgid="2779123106632690576">"Aktiviert"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Nur ACL-Header belassen"</item>
+ <item msgid="2776218217644557831">"A2DP-Medienpakete filtern"</item>
+ <item msgid="8163235976612675092">"RFCOMM-Kanal filtern"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Deaktivieren"</item>
+ <item msgid="2505973306504851132">"Mit Zeichen-String füllen"</item>
+ <item msgid="5883011000629613855">"Nur Header belassen"</item>
+ <item msgid="1051534112762023603">"Vollständig entfernen"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Standard)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-de/strings.xml b/packages/SettingsLib/res/values-de/strings.xml
index dd677c9..2cc048b 100644
--- a/packages/SettingsLib/res/values-de/strings.xml
+++ b/packages/SettingsLib/res/values-de/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Zuschnittbegrenzungen, Ränder usw. anzeigen"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Linksläufiges Layout erzwingen"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Für alle Sprachen wird das linksläufige Bildschirmlayout verwendet"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Transparente Navigationsleiste"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Hintergrundfarbe der Navigationsleiste standardmäßig transparent machen"</string>
<string name="window_blurs" msgid="6831008984828425106">"Weichzeichnen auf Fensterebene zulassen"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA erzwingen"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"In OpenGL ES 2.0-Apps 4x MSAA aktivieren"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Nach rechts"</item>
<item msgid="324200556467459329">"Nach oben"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-el/arrays.xml b/packages/SettingsLib/res/values-el/arrays.xml
index 6486b3d..4e8736c 100644
--- a/packages/SettingsLib/res/values-el/arrays.xml
+++ b/packages/SettingsLib/res/values-el/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Ενεργοποιήθηκε το φιλτράρισμα"</item>
<item msgid="2779123106632690576">"Ενεργοποιήθηκε"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Διατήρηση μόνο κεφαλίδων ACL"</item>
+ <item msgid="2776218217644557831">"Φιλτράρισμα πακέτων μέσων A2DP"</item>
+ <item msgid="8163235976612675092">"Φιλτράρισμα καναλιού RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Απενεργοποίηση"</item>
+ <item msgid="2505973306504851132">"Συμπλήρωση με συμβολοσειρά χαρακτήρων"</item>
+ <item msgid="5883011000629613855">"Διατήρηση μόνο κεφαλίδας"</item>
+ <item msgid="1051534112762023603">"Πλήρης κατάργηση"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Προεπιλογή)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-el/strings.xml b/packages/SettingsLib/res/values-el/strings.xml
index 1e11424..71a5492 100644
--- a/packages/SettingsLib/res/values-el/strings.xml
+++ b/packages/SettingsLib/res/values-el/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Εμφάνιση ορίων κλιπ, περιθωρίων, κλπ."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Επιβολή κατ. διάταξης RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Επιβολή διάταξης οθόν. RTL για όλες τις τοπ. ρυθμ."</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Διαφανής γραμμή πλοήγησης"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Να είναι το χρώμα του φόντου της γραμμής πλοήγησης διαφανές από προεπιλογή"</string>
<string name="window_blurs" msgid="6831008984828425106">"Θάμπωμα σε επίπεδο παραθ."</string>
<string name="force_msaa" msgid="4081288296137775550">"Αναγκαστικά 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ενεργοποίηση 4x MSAA σε εφαρμογές OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Μετακίνηση δεξιά"</item>
<item msgid="324200556467459329">"Μετακίνηση προς τα επάνω"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rAU/arrays.xml b/packages/SettingsLib/res/values-en-rAU/arrays.xml
index 9a7390e..df643cd 100644
--- a/packages/SettingsLib/res/values-en-rAU/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rAU/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Enabled Filtered"</item>
<item msgid="2779123106632690576">"Enabled"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Leave only ACL headers"</item>
+ <item msgid="2776218217644557831">"Filter A2DP media packets"</item>
+ <item msgid="8163235976612675092">"Filter RFCOMM channel"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Disable"</item>
+ <item msgid="2505973306504851132">"Fill with string of characters"</item>
+ <item msgid="5883011000629613855">"Leave only header"</item>
+ <item msgid="1051534112762023603">"Fully remove"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Default)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-en-rAU/strings.xml b/packages/SettingsLib/res/values-en-rAU/strings.xml
index fa40a7b..19dbc53 100644
--- a/packages/SettingsLib/res/values-en-rAU/strings.xml
+++ b/packages/SettingsLib/res/values-en-rAU/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Show clip bounds, margins, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Force RTL layout direction"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Force screen layout direction to RTL for all locales"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Transparent navigation bar"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Make navigation bar background colour transparent by default"</string>
<string name="window_blurs" msgid="6831008984828425106">"Allow window-level blurs"</string>
<string name="force_msaa" msgid="4081288296137775550">"Force 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Enable 4x MSAA in OpenGL ES 2.0 apps"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Move right"</item>
<item msgid="324200556467459329">"Move up"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rCA/strings.xml b/packages/SettingsLib/res/values-en-rCA/strings.xml
index 1ed09ef..7c14c1a 100644
--- a/packages/SettingsLib/res/values-en-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-en-rCA/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Show clip bounds, margins, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Force RTL layout direction"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Force screen layout direction to RTL for all locales"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Transparent navigation bar"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Make navigation bar background color transparent by default"</string>
<string name="window_blurs" msgid="6831008984828425106">"Allow window-level blurs"</string>
<string name="force_msaa" msgid="4081288296137775550">"Force 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Enable 4x MSAA in OpenGL ES 2.0 apps"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Move right"</item>
<item msgid="324200556467459329">"Move up"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rGB/arrays.xml b/packages/SettingsLib/res/values-en-rGB/arrays.xml
index 9a7390e..df643cd 100644
--- a/packages/SettingsLib/res/values-en-rGB/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rGB/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Enabled Filtered"</item>
<item msgid="2779123106632690576">"Enabled"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Leave only ACL headers"</item>
+ <item msgid="2776218217644557831">"Filter A2DP media packets"</item>
+ <item msgid="8163235976612675092">"Filter RFCOMM channel"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Disable"</item>
+ <item msgid="2505973306504851132">"Fill with string of characters"</item>
+ <item msgid="5883011000629613855">"Leave only header"</item>
+ <item msgid="1051534112762023603">"Fully remove"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Default)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-en-rGB/strings.xml b/packages/SettingsLib/res/values-en-rGB/strings.xml
index fa40a7b..19dbc53 100644
--- a/packages/SettingsLib/res/values-en-rGB/strings.xml
+++ b/packages/SettingsLib/res/values-en-rGB/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Show clip bounds, margins, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Force RTL layout direction"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Force screen layout direction to RTL for all locales"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Transparent navigation bar"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Make navigation bar background colour transparent by default"</string>
<string name="window_blurs" msgid="6831008984828425106">"Allow window-level blurs"</string>
<string name="force_msaa" msgid="4081288296137775550">"Force 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Enable 4x MSAA in OpenGL ES 2.0 apps"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Move right"</item>
<item msgid="324200556467459329">"Move up"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rIN/arrays.xml b/packages/SettingsLib/res/values-en-rIN/arrays.xml
index 9a7390e..df643cd 100644
--- a/packages/SettingsLib/res/values-en-rIN/arrays.xml
+++ b/packages/SettingsLib/res/values-en-rIN/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Enabled Filtered"</item>
<item msgid="2779123106632690576">"Enabled"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Leave only ACL headers"</item>
+ <item msgid="2776218217644557831">"Filter A2DP media packets"</item>
+ <item msgid="8163235976612675092">"Filter RFCOMM channel"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Disable"</item>
+ <item msgid="2505973306504851132">"Fill with string of characters"</item>
+ <item msgid="5883011000629613855">"Leave only header"</item>
+ <item msgid="1051534112762023603">"Fully remove"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Default)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-en-rIN/strings.xml b/packages/SettingsLib/res/values-en-rIN/strings.xml
index fa40a7b..19dbc53 100644
--- a/packages/SettingsLib/res/values-en-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-en-rIN/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Show clip bounds, margins, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Force RTL layout direction"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Force screen layout direction to RTL for all locales"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Transparent navigation bar"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Make navigation bar background colour transparent by default"</string>
<string name="window_blurs" msgid="6831008984828425106">"Allow window-level blurs"</string>
<string name="force_msaa" msgid="4081288296137775550">"Force 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Enable 4x MSAA in OpenGL ES 2.0 apps"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Move right"</item>
<item msgid="324200556467459329">"Move up"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-en-rXC/strings.xml b/packages/SettingsLib/res/values-en-rXC/strings.xml
index 11797d5..af7a1cb 100644
--- a/packages/SettingsLib/res/values-en-rXC/strings.xml
+++ b/packages/SettingsLib/res/values-en-rXC/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Show clip bounds, margins, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Force RTL layout direction"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Force screen layout direction to RTL for all locales"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Transparent navigation bar"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Make navigation bar background color transparent by default"</string>
<string name="window_blurs" msgid="6831008984828425106">"Allow window-level blurs"</string>
<string name="force_msaa" msgid="4081288296137775550">"Force 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Enable 4x MSAA in OpenGL ES 2.0 apps"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Move right"</item>
<item msgid="324200556467459329">"Move up"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es-rUS/arrays.xml b/packages/SettingsLib/res/values-es-rUS/arrays.xml
index 771690d..b1b1b2e 100644
--- a/packages/SettingsLib/res/values-es-rUS/arrays.xml
+++ b/packages/SettingsLib/res/values-es-rUS/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtrado habilitado"</item>
<item msgid="2779123106632690576">"Habilitado"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Dejar solo los encabezados de LCA"</item>
+ <item msgid="2776218217644557831">"Filtrar los paquetes multimedia A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrar el canal RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Inhabilitar"</item>
+ <item msgid="2505973306504851132">"Completar con una cadena de caracteres"</item>
+ <item msgid="5883011000629613855">"Dejar solo el encabezado"</item>
+ <item msgid="1051534112762023603">"Quitar por completo"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (predeterminado)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-es-rUS/strings.xml b/packages/SettingsLib/res/values-es-rUS/strings.xml
index fcb454a..9e35c9e 100644
--- a/packages/SettingsLib/res/values-es-rUS/strings.xml
+++ b/packages/SettingsLib/res/values-es-rUS/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostrar límites de recortes, márgenes, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forzar diseño der. a izq."</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forzar diseño de pantalla de derecha a izquierda para todos los idiomas"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barra de navegación transparente"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Hace que el color de fondo de la barra de navegación sea transparente de forma predeterminada"</string>
<string name="window_blurs" msgid="6831008984828425106">"Permitir difuminación en ventana"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forzar MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activar MSAA 4x en aplicaciones OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Mover hacia la derecha"</item>
<item msgid="324200556467459329">"Mover hacia arriba"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-es/arrays.xml b/packages/SettingsLib/res/values-es/arrays.xml
index e07f9dc..626f2ea 100644
--- a/packages/SettingsLib/res/values-es/arrays.xml
+++ b/packages/SettingsLib/res/values-es/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Habilitado con filtros"</item>
<item msgid="2779123106632690576">"Habilitado"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Dejar solo los encabezados de LCA"</item>
+ <item msgid="2776218217644557831">"Filtrar paquetes multimedia A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrar canal RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Inhabilitar"</item>
+ <item msgid="2505973306504851132">"Rellenar con cadena de caracteres"</item>
+ <item msgid="5883011000629613855">"Dejar solo el encabezado"</item>
+ <item msgid="1051534112762023603">"Quitar por completo"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (predeterminado)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-es/strings.xml b/packages/SettingsLib/res/values-es/strings.xml
index a7109fe..01e3961 100644
--- a/packages/SettingsLib/res/values-es/strings.xml
+++ b/packages/SettingsLib/res/values-es/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Muestra límites de vídeo, márgenes, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forzar dirección RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Fuerza la dirección RTL para todos los idiomas"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barra de navegación transparente"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Haz que el color de fondo de la barra de navegación sea transparente de forma predeterminada"</string>
<string name="window_blurs" msgid="6831008984828425106">"Difuminar ventanas"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forzar MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Habilita MSAA 4x en aplicaciones de OpenGL ES 2.0"</string>
@@ -466,7 +468,7 @@
<string name="power_remaining_duration_shutdown_imminent" product="device" msgid="4374784375644214578">"Es posible que el dispositivo se apague pronto (<xliff:g id="LEVEL">%1$s</xliff:g>)"</string>
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> hasta la carga completa"</string>
- <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g>: <xliff:g id="TIME">%2$s</xliff:g> hasta la carga completa"</string>
+ <string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> hasta la carga completa"</string>
<string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga optimizada"</string>
<string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Carga optimizada"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Desconocido"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Muévete hacia la derecha"</item>
<item msgid="324200556467459329">"Muévete hacia arriba"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-et/arrays.xml b/packages/SettingsLib/res/values-et/arrays.xml
index 34448a7..bbfca7d 100644
--- a/packages/SettingsLib/res/values-et/arrays.xml
+++ b/packages/SettingsLib/res/values-et/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Luba filtreeritud"</item>
<item msgid="2779123106632690576">"Lubatud"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Ainult ACL-i päiste allesjätmine"</item>
+ <item msgid="2776218217644557831">"A2DP meediapakettide filtreerimine"</item>
+ <item msgid="8163235976612675092">"RFCOMM-i kanali filtreerimine"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Keelamine"</item>
+ <item msgid="2505973306504851132">"Tähemärkide stringiga täitmine"</item>
+ <item msgid="5883011000629613855">"Ainult päise allesjätmine"</item>
+ <item msgid="1051534112762023603">"Täielikult eemaldamine"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (vaikeseade)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-et/strings.xml b/packages/SettingsLib/res/values-et/strings.xml
index fd9bcd6..4b8db97 100644
--- a/packages/SettingsLib/res/values-et/strings.xml
+++ b/packages/SettingsLib/res/values-et/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Kuva klipi piirid, veerised jms"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Jõusta paremalt vasakule paigutus"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Jõusta kõikides lokaatides paremalt vasakule ekraanipaigutus"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Läbipaistev navigeerimisriba"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Muuda navigeerimisriba taustavärv vaikimisi läbipaistvaks"</string>
<string name="window_blurs" msgid="6831008984828425106">"Luba akna tasemel hägust."</string>
<string name="force_msaa" msgid="4081288296137775550">"Jõusta 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Luba 4x MSAA OpenGL ES 2.0 rakendustes"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Liiguta paremale"</item>
<item msgid="324200556467459329">"Liiguta üles"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-eu/arrays.xml b/packages/SettingsLib/res/values-eu/arrays.xml
index eb678ff..e2867c2 100644
--- a/packages/SettingsLib/res/values-eu/arrays.xml
+++ b/packages/SettingsLib/res/values-eu/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Gaituta baina iragazita"</item>
<item msgid="2779123106632690576">"Gaituta"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Utzi ACL goiburuak soilik"</item>
+ <item msgid="2776218217644557831">"Iragazi A2DP darabilten multimedia-paketeak"</item>
+ <item msgid="8163235976612675092">"Iragazi RFCOMM kanala"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Desgaitu"</item>
+ <item msgid="2505973306504851132">"Bete karaktere-kate batekin"</item>
+ <item msgid="5883011000629613855">"Utzi goiburua soilik"</item>
+ <item msgid="1051534112762023603">"Kendu guztiz"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (lehenetsia)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-eu/strings.xml b/packages/SettingsLib/res/values-eu/strings.xml
index 02ab192..35cbafc7 100644
--- a/packages/SettingsLib/res/values-eu/strings.xml
+++ b/packages/SettingsLib/res/values-eu/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Erakutsi kliparen mugak, marjinak, etab."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Eskuinetik ezkerrerako norabidea"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Behartu pantaila-diseinuaren norabidea eskuin-ezker izatera lurraldeko ezarpen guztiekin"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Nabigazio-barra gardena"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Ezarri nabigazio-barraren atzeko planoko kolorea garden gisa modu lehenetsian"</string>
<string name="window_blurs" msgid="6831008984828425106">"Gaitu leiho-lausotzeak"</string>
<string name="force_msaa" msgid="4081288296137775550">"Behartu 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Gaitu 4x MSAA, OpenGL ES 2.0 aplikazioetan"</string>
@@ -467,8 +469,8 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"<xliff:g id="TIME">%1$s</xliff:g> guztiz kargatu arte"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="TIME">%2$s</xliff:g> guztiz kargatu arte"</string>
- <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kargatze optimizatua"</string>
- <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kargatze optimizatua"</string>
+ <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kargatzeko modu optimizatua"</string>
+ <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - Kargatzeko modu optimizatua"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Ezezaguna"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Kargatzen"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"Bizkor kargatzen"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Eraman eskuinera"</item>
<item msgid="324200556467459329">"Eraman gora"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fa/arrays.xml b/packages/SettingsLib/res/values-fa/arrays.xml
index 2d9be31..7feef70 100644
--- a/packages/SettingsLib/res/values-fa/arrays.xml
+++ b/packages/SettingsLib/res/values-fa/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"فیلترشده فعال شده است"</item>
<item msgid="2779123106632690576">"فعال"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"نگه داشتن فقط سرایند ACL"</item>
+ <item msgid="2776218217644557831">"فیلتر کردن بستههای رسانه A2DP"</item>
+ <item msgid="8163235976612675092">"فیلتر کردن کانال RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"غیرفعال کردن"</item>
+ <item msgid="2505973306504851132">"پر کردن با رشتهای از نویسهها"</item>
+ <item msgid="5883011000629613855">"نگه داشتن فقط سرایند"</item>
+ <item msgid="1051534112762023603">"برداشتن کامل"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP نسخه ۱.۵ (پیشفرض)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-fa/strings.xml b/packages/SettingsLib/res/values-fa/strings.xml
index 0732fcf..8fa6b33 100644
--- a/packages/SettingsLib/res/values-fa/strings.xml
+++ b/packages/SettingsLib/res/values-fa/strings.xml
@@ -268,7 +268,7 @@
<string name="mock_location_app_set" msgid="4706722469342913843">"برنامه موقعیت مکانی ساختگی: <xliff:g id="APP_NAME">%1$s</xliff:g>"</string>
<string name="debug_networking_category" msgid="6829757985772659599">"شبکه"</string>
<string name="wifi_display_certification" msgid="1805579519992520381">"گواهینامه نمایش بیسیم"</string>
- <string name="wifi_verbose_logging" msgid="1785910450009679371">"فعال کردن گزارشگیری طولانی Wi‑Fi"</string>
+ <string name="wifi_verbose_logging" msgid="1785910450009679371">"فعال کردن گزارشگیری مفصل Wi‑Fi"</string>
<string name="wifi_scan_throttling" msgid="2985624788509913617">"محدود کردن اسکن کردن Wi‑Fi"</string>
<string name="wifi_non_persistent_mac_randomization" msgid="7482769677894247316">"تصادفیسازی MAC غیرپایای Wi-Fi"</string>
<string name="mobile_data_always_on" msgid="8275958101875563572">"داده تلفن همراه همیشه فعال باشد"</string>
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"نمایش مرزها، حاشیهها و ویژگیهای دیگر کلیپ."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"اجباری کردن چیدمان راستچین"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"اجباری کردن چیدمان راستچین صفحه برای همه زبانها"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"نوار پیمایش شفاف"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"رنگ پسزمینه نوار پیمایش را بهطور پیشفرض شفاف میکند"</string>
<string name="window_blurs" msgid="6831008984828425106">"محو کردن در سطح پنجره"</string>
<string name="force_msaa" msgid="4081288296137775550">"اجبار 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"فعال کردن 4X MSAA در برنامههای OpenGL ES 2.0"</string>
@@ -378,7 +380,7 @@
<string name="track_frame_time" msgid="522674651937771106">"پرداز زدن HWUI نمایه"</string>
<string name="enable_gpu_debug_layers" msgid="4986675516188740397">"فعال کردن لایههای اشکالزدایی GPU"</string>
<string name="enable_gpu_debug_layers_summary" msgid="4921521407377170481">"مجاز کردن بارگیری لایههای اشکالزدایی GPU برای برنامههای اشکالزدایی"</string>
- <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"فعال کردن گزارش طولانی فروشنده"</string>
+ <string name="enable_verbose_vendor_logging" msgid="1196698788267682072">"فعال کردن گزارشگیری مفصل فروشنده"</string>
<string name="enable_verbose_vendor_logging_summary" msgid="5426292185780393708">"شامل گزارشات اشکال تکمیلی ورود به سیستم فروشنده ویژه دستگاه میشود که ممکن است دربرگیرنده اطلاعات خصوصی، استفاده بیشتر از باتری، و/یا استفاده بیشتر از فضای ذخیرهسازی باشد."</string>
<string name="window_animation_scale_title" msgid="5236381298376812508">"مقیاس پویانمایی پنجره"</string>
<string name="transition_animation_scale_title" msgid="1278477690695439337">"مقیاس پویانمایی انتقالی"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"انتقال بهراست"</item>
<item msgid="324200556467459329">"انتقال بهبالا"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>٪"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fi/arrays.xml b/packages/SettingsLib/res/values-fi/arrays.xml
index d6f002f..5a1dc18 100644
--- a/packages/SettingsLib/res/values-fi/arrays.xml
+++ b/packages/SettingsLib/res/values-fi/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Suodatus käytössä"</item>
<item msgid="2779123106632690576">"Päällä"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Jätä pelkät ACL-otsikot"</item>
+ <item msgid="2776218217644557831">"Suodata A2DP-mediapaketit"</item>
+ <item msgid="8163235976612675092">"Suodata RFCOMM-kanava"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Poista käytöstä"</item>
+ <item msgid="2505973306504851132">"Täytä merkkijonolla"</item>
+ <item msgid="5883011000629613855">"Jätä pelkkä otsikko"</item>
+ <item msgid="1051534112762023603">"Poista kokonaan"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (oletus)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-fi/strings.xml b/packages/SettingsLib/res/values-fi/strings.xml
index 089fa42..0af656d 100644
--- a/packages/SettingsLib/res/values-fi/strings.xml
+++ b/packages/SettingsLib/res/values-fi/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Näytä leikkeiden rajat, marginaalit jne."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Pakota RTL-ulkoasun suunta"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Pakota kaikkien kielten näytön ulkoasun suunnaksi RTL"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Läpinäkyvä siirtymispalkki"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Muuta siirtymispalkin taustaväri oletuksena läpinäkyväksi"</string>
<string name="window_blurs" msgid="6831008984828425106">"Salli ikkunoiden sumennus"</string>
<string name="force_msaa" msgid="4081288296137775550">"Pakota 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ota käyttöön 4x MSAA OpenGL ES 2.0 -sovelluksissa"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Siirrä oikealle"</item>
<item msgid="324200556467459329">"Siirrä ylös"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fr-rCA/arrays.xml b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
index 6657aa1..06a703f 100644
--- a/packages/SettingsLib/res/values-fr-rCA/arrays.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtres activés"</item>
<item msgid="2779123106632690576">"Activé"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Garder uniquement les en-têtes ACL"</item>
+ <item msgid="2776218217644557831">"Filtrer les paquets multimédias A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrer le canal RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Désactiver"</item>
+ <item msgid="2505973306504851132">"Remplir avec une chaîne de caractères"</item>
+ <item msgid="5883011000629613855">"Garder uniquement l\'en-tête"</item>
+ <item msgid="1051534112762023603">"Retirer complètement"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (par défaut)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-fr-rCA/strings.xml b/packages/SettingsLib/res/values-fr-rCA/strings.xml
index 489bea1c..5596e70 100644
--- a/packages/SettingsLib/res/values-fr-rCA/strings.xml
+++ b/packages/SettingsLib/res/values-fr-rCA/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Afficher les limites, les marges de clip, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forcer droite à gauche"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forcer l\'orientation de droite à gauche (toutes langues)"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barre de navigation transparente"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Rendre la couleur d\'arrière-plan de la barre de navigation transparente par défaut"</string>
<string name="window_blurs" msgid="6831008984828425106">"Autoriser le flou au niveau des fenêtres"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forcer MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activer MSAA 4x dans les applications OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Déplacez vers la droite"</item>
<item msgid="324200556467459329">"Déplacez vers le haut"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-fr/arrays.xml b/packages/SettingsLib/res/values-fr/arrays.xml
index 869d88a..6377160 100644
--- a/packages/SettingsLib/res/values-fr/arrays.xml
+++ b/packages/SettingsLib/res/values-fr/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Activé et filtré"</item>
<item msgid="2779123106632690576">"Activé"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Ne laisser que les en-têtes LCA"</item>
+ <item msgid="2776218217644557831">"Filtrer les paquets multimédias A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrer le canal RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Désactiver"</item>
+ <item msgid="2505973306504851132">"Saisir une chaîne de caractères"</item>
+ <item msgid="5883011000629613855">"Ne laisser que l\'en-tête"</item>
+ <item msgid="1051534112762023603">"Supprimer complètement"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (par défaut)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-fr/strings.xml b/packages/SettingsLib/res/values-fr/strings.xml
index a4d5f20..12ba2c3 100644
--- a/packages/SettingsLib/res/values-fr/strings.xml
+++ b/packages/SettingsLib/res/values-fr/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Afficher les limites de coupe, les marges, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forcer écriture droite à gauche"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forcer l\'orientation du texte de droite à gauche pour toutes les langues"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barre de navigation transparente"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Rendre la couleur d\'arrière-plan de la barre de navigation transparente par défaut"</string>
<string name="window_blurs" msgid="6831008984828425106">"Autor. floutage fenêtre"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forcer MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activer MSAA 4x dans les applications OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Déplacer vers la droite"</item>
<item msgid="324200556467459329">"Déplacer vers le haut"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-gl/arrays.xml b/packages/SettingsLib/res/values-gl/arrays.xml
index 3cd7b4b..797f84b 100644
--- a/packages/SettingsLib/res/values-gl/arrays.xml
+++ b/packages/SettingsLib/res/values-gl/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Está activado o filtrado"</item>
<item msgid="2779123106632690576">"Activada"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Deixar só as cabeceiras de ACL"</item>
+ <item msgid="2776218217644557831">"Filtrar paquetes multimedia A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrar canle RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Desactivar"</item>
+ <item msgid="2505973306504851132">"Completar cunha cadea de caracteres"</item>
+ <item msgid="5883011000629613855">"Deixar só a cabeceira"</item>
+ <item msgid="1051534112762023603">"Quitar por completo"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (predeterminado)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-gl/strings.xml b/packages/SettingsLib/res/values-gl/strings.xml
index 8aa4d62..7577cd5 100644
--- a/packages/SettingsLib/res/values-gl/strings.xml
+++ b/packages/SettingsLib/res/values-gl/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostra os límites dos clips, as marxes etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forzar dirección do deseño RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forza a dirección de pantalla de dereita a esquerda para todas as opcións de configuración rexionais"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barra de navegación transparente"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Cambia a cor de fondo da barra de navegación a transparente de forma predeterminada"</string>
<string name="window_blurs" msgid="6831008984828425106">"Permitir desenfoque de ventás"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forzar MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activa MSAA 4x en aplicacións OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Mover cara á dereita"</item>
<item msgid="324200556467459329">"Mover cara arriba"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-gu/arrays.xml b/packages/SettingsLib/res/values-gu/arrays.xml
index f559b80..93d3432 100644
--- a/packages/SettingsLib/res/values-gu/arrays.xml
+++ b/packages/SettingsLib/res/values-gu/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"ફિલ્ટર કરેલ ચાલુ છે"</item>
<item msgid="2779123106632690576">"ચાલુ છે"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"માત્ર ACL હેડર છોડી દો"</item>
+ <item msgid="2776218217644557831">"A2DP મીડિયા પૅકેટ ફિલ્ટર કરો"</item>
+ <item msgid="8163235976612675092">"RFCOMM ચૅનલ ફિલ્ટર કરો"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"બંધ કરો"</item>
+ <item msgid="2505973306504851132">"અક્ષરોની સ્ટ્રિંગથી ભરો"</item>
+ <item msgid="5883011000629613855">"માત્ર હેડર છોડી દો"</item>
+ <item msgid="1051534112762023603">"સંપૂર્ણપણે કાઢી નાખવું"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ડિફૉલ્ટ)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-gu/strings.xml b/packages/SettingsLib/res/values-gu/strings.xml
index e253bbf..1696f81a 100644
--- a/packages/SettingsLib/res/values-gu/strings.xml
+++ b/packages/SettingsLib/res/values-gu/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ક્લિપ બાઉન્ડ, હાંસિયાં વગેરે બતાવો."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL લેઆઉટ દિશાનિર્દેશની ફરજ પાડો"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"તમામ લોકેલ માટે સ્ક્રીન લેઆઉટ દિશાનિર્દેશને RTLની ફરજ પાડો"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"પારદર્શક નૅવિગેશન બાર"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"નૅવિગેશન બારના બૅકગ્રાઉન્ડના રંગને ડિફૉલ્ટ તરીકે પારદર્શક બનાવો"</string>
<string name="window_blurs" msgid="6831008984828425106">"વિન્ડો-લેવલને બ્લર કરવાની સુવિધા ચાલુ કરો"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAAને ફરજ પાડો"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ઍપમાં 4x MSAA ચાલુ કરો"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"જમણે ખસેડો"</item>
<item msgid="324200556467459329">"ઉપર ખસેડો"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hi/arrays.xml b/packages/SettingsLib/res/values-hi/arrays.xml
index be88620..24efe28 100644
--- a/packages/SettingsLib/res/values-hi/arrays.xml
+++ b/packages/SettingsLib/res/values-hi/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"चालू और फ़िल्टर किया गया"</item>
<item msgid="2779123106632690576">"चालू है"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"सिर्फ़ ACL हेडर छोड़ दें"</item>
+ <item msgid="2776218217644557831">"A2DP मीडिया पैकेट फ़िल्टर करें"</item>
+ <item msgid="8163235976612675092">"RFCOMM चैनल फ़िल्टर करें"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"बंद करें"</item>
+ <item msgid="2505973306504851132">"कैरेक्टर स्ट्रिंग डालें"</item>
+ <item msgid="5883011000629613855">"सिर्फ़ हेडर छोड़ दें"</item>
+ <item msgid="1051534112762023603">"पूरी तरह से हटाएं"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (डिफ़ॉल्ट)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-hi/strings.xml b/packages/SettingsLib/res/values-hi/strings.xml
index adf09d7..04c225c 100644
--- a/packages/SettingsLib/res/values-hi/strings.xml
+++ b/packages/SettingsLib/res/values-hi/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"क्लिप सीमाएं, मार्जिन वगैरह दिखाएं."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"लेआउट की दिशा दाएं से बाएं करें"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"सभी भाषाओं के लिए स्क्रीन लेआउट की दिशा दाएं से बाएं रखें"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"पारदर्शी बैकग्राउंड वाला नेविगेशन बार"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"नेविगेशन बार के बैकग्राउंड के रंग को डिफ़ॉल्ट रूप से पारदर्शी के तौर पर सेट करें"</string>
<string name="window_blurs" msgid="6831008984828425106">"विंडो को धुंधला करने की सुविधा चालू करें"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA को हर हाल में चालू करें"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ऐप में 4x MSAA को चालू करें"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"दाईं ओर ले जाएं"</item>
<item msgid="324200556467459329">"ऊपर की ओर ले जाएं"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hr/arrays.xml b/packages/SettingsLib/res/values-hr/arrays.xml
index 5c73ebb..fbe62a0 100644
--- a/packages/SettingsLib/res/values-hr/arrays.xml
+++ b/packages/SettingsLib/res/values-hr/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Omogućeno filtrirano"</item>
<item msgid="2779123106632690576">"Omogućeno"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Zadrži samo ACL zaglavlja"</item>
+ <item msgid="2776218217644557831">"Filtriraj A2DP medijske pakete"</item>
+ <item msgid="8163235976612675092">"Filtriraj RFCOMM kanal"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Onemogući"</item>
+ <item msgid="2505973306504851132">"Ispunite nizom znakova"</item>
+ <item msgid="5883011000629613855">"Zadržite samo zaglavlje"</item>
+ <item msgid="1051534112762023603">"Uklonite u potpunosti"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (zadano)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 9489d6e..06fe6f2 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Prikazuju se obrubi, margine itd. isječaka"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Nametni zdesna ulijevo"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Nametni smjer zdesna ulijevo za sve zemlje/jezike"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Prozirna navigacijska traka"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Neka boja pozadine navigacijske trake bude prozirna prema zadanim postavkama"</string>
<string name="window_blurs" msgid="6831008984828425106">"Dopusti zamućenja na razini prozora"</string>
<string name="force_msaa" msgid="4081288296137775550">"Nametni 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Omogući 4x MSAA u aplikacijama OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Pomicanje udesno"</item>
<item msgid="324200556467459329">"Pomicanje prema gore"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hu/arrays.xml b/packages/SettingsLib/res/values-hu/arrays.xml
index 500b9fd..ee1ace0 100644
--- a/packages/SettingsLib/res/values-hu/arrays.xml
+++ b/packages/SettingsLib/res/values-hu/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Szűrtek engedélyezve"</item>
<item msgid="2779123106632690576">"Engedélyezve"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Csak ACL-fejlécek maradjanak"</item>
+ <item msgid="2776218217644557831">"A2DP-médiacsomagok szűrése"</item>
+ <item msgid="8163235976612675092">"RFCOMM-csatorna szűrése"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Kikapcsolás"</item>
+ <item msgid="2505973306504851132">"Kitöltés karakterláncokkal"</item>
+ <item msgid="5883011000629613855">"Csak fejléc maradjon"</item>
+ <item msgid="1051534112762023603">"Teljes eltávolítás"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (alapértelmezett)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index 0d4d09d..5d25572 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Kliphatárok, margók stb. megjelenítése."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Elrendezés jobbról balra"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Elrendezés jobbról balra minden nyelvnél"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Átlátszó navigációs sáv"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"A navigációs sáv alapértelmezett háttérszínének beállítása átlátszóra"</string>
<string name="window_blurs" msgid="6831008984828425106">"Ablakszintű homályosítás"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA kényszerítése"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"A 4x MSAA engedélyezése az OpenGL ES 2.0-nál"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Mozgatás jobbra"</item>
<item msgid="324200556467459329">"Mozgatás felfelé"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-hy/arrays.xml b/packages/SettingsLib/res/values-hy/arrays.xml
index 6fd6893..01b97a8 100644
--- a/packages/SettingsLib/res/values-hy/arrays.xml
+++ b/packages/SettingsLib/res/values-hy/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Միացված է զտիչներով"</item>
<item msgid="2779123106632690576">"Միացված է"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Թողնել միայն ACL վերնագրերը"</item>
+ <item msgid="2776218217644557831">"Զտել A2DP մուլտիմեդիա փաթեթները"</item>
+ <item msgid="8163235976612675092">"Զտել RFCOMM կապուղին"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Անջատել"</item>
+ <item msgid="2505973306504851132">"Լրացնել նիշերի տողով"</item>
+ <item msgid="5883011000629613855">"Թողնել միայն վերնագիրը"</item>
+ <item msgid="1051534112762023603">"Ամբողջությամբ հեռացնել"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (կանխադրված)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-hy/strings.xml b/packages/SettingsLib/res/values-hy/strings.xml
index 0a3161b..69e57cc 100644
--- a/packages/SettingsLib/res/values-hy/strings.xml
+++ b/packages/SettingsLib/res/values-hy/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Ցույց տալ կտրվածքի սահմանները, լուսանցքները և այլն"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Ուղղությունը դարձնել RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Բոլոր լեզուների համար էկրանի տեքստի ուղղությունը դարձնել աջից ձախ"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Նավիգացիայի թափանցիկ գոտի"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Նավիգացիայի գոտին դարձնել թափանցիկ ըստ կանխադրման"</string>
<string name="window_blurs" msgid="6831008984828425106">"Շաղում պատուհանի մակարդակում"</string>
<string name="force_msaa" msgid="4081288296137775550">"Ստիպել 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Միացնել 4x MSAA-ը OpenGL ES 2.0 հավելվածներում"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Տեղափոխել աջ"</item>
<item msgid="324200556467459329">"Տեղափոխել վերև"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-in/arrays.xml b/packages/SettingsLib/res/values-in/arrays.xml
index 8257d0e..d445d9c 100644
--- a/packages/SettingsLib/res/values-in/arrays.xml
+++ b/packages/SettingsLib/res/values-in/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Diaktifkan Difilter"</item>
<item msgid="2779123106632690576">"Diaktifkan"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Hanya biarkan header ACL"</item>
+ <item msgid="2776218217644557831">"Filter paket media A2DP"</item>
+ <item msgid="8163235976612675092">"Filter saluran RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Nonaktifkan"</item>
+ <item msgid="2505973306504851132">"Isi dengan string karakter"</item>
+ <item msgid="5883011000629613855">"Hanya biarkan header"</item>
+ <item msgid="1051534112762023603">"Hapus sepenuhnya"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Default)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-in/strings.xml b/packages/SettingsLib/res/values-in/strings.xml
index 2ee096b..d174c75 100644
--- a/packages/SettingsLib/res/values-in/strings.xml
+++ b/packages/SettingsLib/res/values-in/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Menampilkan batas klip, margin, dll."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Paksa arah tata letak RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Memaksa arah tata letak layar RTL untuk semua lokalitas"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Menu navigasi transparan"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Buat warna latar belakang menu navigasi menjadi transparan secara default"</string>
<string name="window_blurs" msgid="6831008984828425106">"Izinkan buram level jendela"</string>
<string name="force_msaa" msgid="4081288296137775550">"Paksa 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Mengaktifkan 4x MSAA dalam aplikasi OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Pindahkan ke kanan"</item>
<item msgid="324200556467459329">"Pindahkan ke atas"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-is/arrays.xml b/packages/SettingsLib/res/values-is/arrays.xml
index 1b114ee..01ce83f 100644
--- a/packages/SettingsLib/res/values-is/arrays.xml
+++ b/packages/SettingsLib/res/values-is/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Kveikt á síuðu"</item>
<item msgid="2779123106632690576">"Kveikt"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Skilja aðeins eftir ACL-hausa"</item>
+ <item msgid="2776218217644557831">"Sía A2DP-efnispakka"</item>
+ <item msgid="8163235976612675092">"Sía RFCOMM-rás"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Slökkva"</item>
+ <item msgid="2505973306504851132">"Fylla með streng með stöfum"</item>
+ <item msgid="5883011000629613855">"Skilja aðeins eftir haus"</item>
+ <item msgid="1051534112762023603">"Fjarlægja í heild sinni"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (sjálfgefið)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-is/strings.xml b/packages/SettingsLib/res/values-is/strings.xml
index 95dc268..d97a001 100644
--- a/packages/SettingsLib/res/values-is/strings.xml
+++ b/packages/SettingsLib/res/values-is/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Sýna skurðlínur, spássíur o.s.frv."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Þvinga umbrot frá hægri til vinstri"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Þvinga umbrot skjás frá hægri til vinstri fyrir alla tungumálskóða"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Gagnsæ yfirlitsstika"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Stilla gagnsæjan bakgrunnslit yfirlitsstiku sem sjálfgefinn"</string>
<string name="window_blurs" msgid="6831008984828425106">"Leyfa að gera glugga ósk."</string>
<string name="force_msaa" msgid="4081288296137775550">"Þvinga 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Virkja 4x MSAA í OpenGL ES 2.0 forritum"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Færa til hægri"</item>
<item msgid="324200556467459329">"Færa upp"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-it/arrays.xml b/packages/SettingsLib/res/values-it/arrays.xml
index 50eca93..be718db 100644
--- a/packages/SettingsLib/res/values-it/arrays.xml
+++ b/packages/SettingsLib/res/values-it/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtro attivo"</item>
<item msgid="2779123106632690576">"Attiva"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Lascia solo le intestazioni ACL"</item>
+ <item msgid="2776218217644557831">"Filtra pacchetti multimediali A2DP"</item>
+ <item msgid="8163235976612675092">"Filtra canale RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Disattiva"</item>
+ <item msgid="2505973306504851132">"Inserisci stringa di caratteri"</item>
+ <item msgid="5883011000629613855">"Lascia solo l\'intestazione"</item>
+ <item msgid="1051534112762023603">"Rimuovi completamente"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (versione predefinita)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-it/strings.xml b/packages/SettingsLib/res/values-it/strings.xml
index dc96364..17d9edb 100644
--- a/packages/SettingsLib/res/values-it/strings.xml
+++ b/packages/SettingsLib/res/values-it/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostra limiti, margini dei clip e così via"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forza direzione layout RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Direzione layout schermo RTL per tutte le lingue"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barra di navigazione trasparente"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Rendi trasparente il colore di sfondo della barra di navigazione per impostazione predefinita"</string>
<string name="window_blurs" msgid="6831008984828425106">"Consenti sfocature finestre"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forza MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Attiva MSAA 4x in applicazioni OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Sposta a destra"</item>
<item msgid="324200556467459329">"Sposta in alto"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-iw/arrays.xml b/packages/SettingsLib/res/values-iw/arrays.xml
index 02b7751..2600d9c 100644
--- a/packages/SettingsLib/res/values-iw/arrays.xml
+++ b/packages/SettingsLib/res/values-iw/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"המסננים המופעלים"</item>
<item msgid="2779123106632690576">"מופעל"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"השארת כותרות ACL בלבד"</item>
+ <item msgid="2776218217644557831">"סינון של מנות מדיה A2DP"</item>
+ <item msgid="8163235976612675092">"סינון של ערוץ RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"השבתה"</item>
+ <item msgid="2505973306504851132">"מילוי עם מחרוזת של תווים"</item>
+ <item msgid="5883011000629613855">"השארת הכותרת בלבד"</item>
+ <item msgid="1051534112762023603">"הסרה מלאה"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ברירת המחדל)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-iw/strings.xml b/packages/SettingsLib/res/values-iw/strings.xml
index 5c54d62..c38111a 100644
--- a/packages/SettingsLib/res/values-iw/strings.xml
+++ b/packages/SettingsLib/res/values-iw/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"הצגת גבולות אזור, שוליים וכדומה"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"אילוץ כיוון פריסה מימין לשמאל"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"אילוץ של כיוון פריסת מסך מימין לשמאל עבור כל השפות בכל המקומות"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"סרגל ניווט שקוף"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"צבע הרקע של סרגל הניווט יהיה שקוף כברירת מחדל"</string>
<string name="window_blurs" msgid="6831008984828425106">"אישור טשטושים ברמת החלון"</string>
<string name="force_msaa" msgid="4081288296137775550">"אילוץ הפעלת 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"הפעלת 4x MSAA ביישומי OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"הזזה ימינה"</item>
<item msgid="324200556467459329">"הזזה למעלה"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"%% <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ja/arrays.xml b/packages/SettingsLib/res/values-ja/arrays.xml
index 869fd997..ab84488 100644
--- a/packages/SettingsLib/res/values-ja/arrays.xml
+++ b/packages/SettingsLib/res/values-ja/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"有効(フィルタ済み)"</item>
<item msgid="2779123106632690576">"有効"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL ヘッダーのみを残す"</item>
+ <item msgid="2776218217644557831">"A2DP メディア パケットをフィルタ"</item>
+ <item msgid="8163235976612675092">"RFCOMM チャネルをフィルタ"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"無効にする"</item>
+ <item msgid="2505973306504851132">"文字列を入力"</item>
+ <item msgid="5883011000629613855">"ヘッダーのみを残す"</item>
+ <item msgid="1051534112762023603">"完全に削除"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5(デフォルト)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ja/strings.xml b/packages/SettingsLib/res/values-ja/strings.xml
index 09984c2..a7635c7 100644
--- a/packages/SettingsLib/res/values-ja/strings.xml
+++ b/packages/SettingsLib/res/values-ja/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"クリップの境界線、マージンなどを表示"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL レイアウト方向を使用"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"すべての言語/地域で画面レイアウト方向を RTL に設定"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"透明なナビゲーション バー"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ナビゲーション バーの背景色をデフォルトで透明にします"</string>
<string name="window_blurs" msgid="6831008984828425106">"ウィンドウ レベルでのぼかしを許可"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA を適用"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 アプリで 4x MSAA を有効にする"</string>
@@ -467,8 +469,8 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"完了まであと <xliff:g id="TIME">%1$s</xliff:g>"</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> - 完了まであと <xliff:g id="TIME">%2$s</xliff:g>"</string>
- <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電最適化済み"</string>
- <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電最適化済み"</string>
+ <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電が最適化されています"</string>
+ <string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> - 充電が最適化されています"</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"不明"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"充電中"</string>
<string name="battery_info_status_charging_fast" msgid="8027559755902954885">"急速充電中"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"右に移動"</item>
<item msgid="324200556467459329">"上に移動"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ka/arrays.xml b/packages/SettingsLib/res/values-ka/arrays.xml
index 71a283c..be44038 100644
--- a/packages/SettingsLib/res/values-ka/arrays.xml
+++ b/packages/SettingsLib/res/values-ka/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"გაფილტრულის ჩართვა"</item>
<item msgid="2779123106632690576">"ჩართულია"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"მხოლოდ ACL სათაურების დატოვება"</item>
+ <item msgid="2776218217644557831">"A2DP მედია პაკეტების გაფილტვრა"</item>
+ <item msgid="8163235976612675092">"RFCOMM არხის გაფილტვრა"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"გათიშვა"</item>
+ <item msgid="2505973306504851132">"სიმბოლოების სტრიქონით შევსება"</item>
+ <item msgid="5883011000629613855">"მხოლოდ სათაურის დატოვება"</item>
+ <item msgid="1051534112762023603">"სრულად ამოშლა"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ნაგულისხმევი)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ka/strings.xml b/packages/SettingsLib/res/values-ka/strings.xml
index 2abd85a..568d061 100644
--- a/packages/SettingsLib/res/values-ka/strings.xml
+++ b/packages/SettingsLib/res/values-ka/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"კლიპის საზღვრების, მინდვრების ჩვენება და ა.შ."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"მარჯვნიდან მარცხნივ განლაგების მიმართულების იძულება"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ეკრანის RTL მიმართულებაზე იძულება ყველა ლოკალისათვის"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"გამჭვირვალე ნავიგაციის ზოლი"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ნავიგაციის ზოლის ფონის ფერის გამჭვირვალედ ჩვენება ნაგულისხმევად"</string>
<string name="window_blurs" msgid="6831008984828425106">"ფანჯრის დონეზე გაბუნდოვნების დაშვება"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA-ს ჩართვა"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"4x MSAA-ის ჩართვა OpenGL ES 2.0 აპში."</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"მარჯვნივ გადატანა"</item>
<item msgid="324200556467459329">"ზემოთ გადატანა"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-kk/arrays.xml b/packages/SettingsLib/res/values-kk/arrays.xml
index ab5e107..7d71699 100644
--- a/packages/SettingsLib/res/values-kk/arrays.xml
+++ b/packages/SettingsLib/res/values-kk/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Сүзгіленгендері қосулы"</item>
<item msgid="2779123106632690576">"Қосулы"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Тек ACL жоғарғы деректемелерін қалдыру"</item>
+ <item msgid="2776218217644557831">"A2DP медиапакеттерін іріктеу"</item>
+ <item msgid="8163235976612675092">"RFCOMM арнасын іріктеу"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Өшіру"</item>
+ <item msgid="2505973306504851132">"Таңбалар жолын енгізу"</item>
+ <item msgid="5883011000629613855">"Тек жоғарғы деректемені қалдыру"</item>
+ <item msgid="1051534112762023603">"Толық өшіру"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (әдепкі)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-kk/strings.xml b/packages/SettingsLib/res/values-kk/strings.xml
index ba68253..414ad01 100644
--- a/packages/SettingsLib/res/values-kk/strings.xml
+++ b/packages/SettingsLib/res/values-kk/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Қию шегін, шеттерді, т.б. көрсету"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Оңнан солға орналастыру"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Экранның орналасу бағытын барлық тілдер үшін оңнан солға қарату"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Мөлдір навигация жолағы"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Навигация жолағының фондық түсін әдепкісінше мөлдір қылу"</string>
<string name="window_blurs" msgid="6831008984828425106">"Терезе деңгейіндегі бұлдырлар"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA қолдану"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"4x MSAA функциясын OpenGL ES 2.0 қолданбаларында іске қосу"</string>
@@ -467,7 +469,7 @@
<string name="power_charging" msgid="6727132649743436802">"<xliff:g id="LEVEL">%1$s</xliff:g> - <xliff:g id="STATE">%2$s</xliff:g>"</string>
<string name="power_remaining_charging_duration_only" msgid="8085099012811384899">"Толық зарядталғанға дейін <xliff:g id="TIME">%1$s</xliff:g> қалды."</string>
<string name="power_charging_duration" msgid="6127154952524919719">"<xliff:g id="LEVEL">%1$s</xliff:g> – толық зарядталғанға дейін <xliff:g id="TIME">%2$s</xliff:g> қалды."</string>
- <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядтау оңтайландырылды."</string>
+ <string name="power_charging_limited" msgid="8202147604844938236">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядтау оңтайландырылды"</string>
<string name="power_charging_future_paused" msgid="4730177778538118032">"<xliff:g id="LEVEL">%1$s</xliff:g> – зарядтау оңтайландырылды."</string>
<string name="battery_info_status_unknown" msgid="268625384868401114">"Белгісіз"</string>
<string name="battery_info_status_charging" msgid="4279958015430387405">"Зарядталуда"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Оңға жылжыту"</item>
<item msgid="324200556467459329">"Жоғары жылжыту"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-km/arrays.xml b/packages/SettingsLib/res/values-km/arrays.xml
index bfc9834..548e2d6 100644
--- a/packages/SettingsLib/res/values-km/arrays.xml
+++ b/packages/SettingsLib/res/values-km/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"បានបើកការត្រង"</item>
<item msgid="2779123106632690576">"បានបើក"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ទុកតែក្បាល ACL ប៉ុណ្ណោះ"</item>
+ <item msgid="2776218217644557831">"ត្រងកញ្ចប់មេឌៀ A2DP"</item>
+ <item msgid="8163235976612675092">"ត្រងបណ្ដាញ RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"បិទ"</item>
+ <item msgid="2505973306504851132">"បំពេញដោយជួរអក្សរ"</item>
+ <item msgid="5883011000629613855">"ទុកតែក្បាលប៉ុណ្ណោះ"</item>
+ <item msgid="1051534112762023603">"ដកចេញទាំងស្រុង"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (លំនាំដើម)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-km/strings.xml b/packages/SettingsLib/res/values-km/strings.xml
index 2e33159..1cbf245 100644
--- a/packages/SettingsLib/res/values-km/strings.xml
+++ b/packages/SettingsLib/res/values-km/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"បង្ហាញការភ្ជាប់អត្ថបទសម្រង់ រឹម ។ល។"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"បង្ខំទិសប្លង់ RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ប្តូរទិសប្លង់អេក្រង់ទៅជា RTL សម្រាប់គ្រប់ភាសាទាំងអស់"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"របាររុករកដែលថ្លា"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ធ្វើឱ្យពណ៌ផ្ទៃខាងក្រោយនៃរបាររុករកថ្លាតាមលំនាំដើម"</string>
<string name="window_blurs" msgid="6831008984828425106">"អនុញ្ញាតភាពព្រាលកម្រិតវិនដូ"</string>
<string name="force_msaa" msgid="4081288296137775550">"បង្ខំ 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"បើក 4x MSAA ក្នុងកម្មវិធី OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"ផ្លាស់ទីទៅស្តាំ"</item>
<item msgid="324200556467459329">"ផ្លាស់ទីឡើងលើ"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-kn/arrays.xml b/packages/SettingsLib/res/values-kn/arrays.xml
index 61e2791..aa29850 100644
--- a/packages/SettingsLib/res/values-kn/arrays.xml
+++ b/packages/SettingsLib/res/values-kn/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"ಫಿಲ್ಟರ್ ಮಾಡುವುದನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</item>
<item msgid="2779123106632690576">"ಸಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL ಶೀರ್ಷಿಕೆಗಳನ್ನು ಮಾತ್ರ ಬಿಡಿ"</item>
+ <item msgid="2776218217644557831">"A2DP ಮಾಧ್ಯಮ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ"</item>
+ <item msgid="8163235976612675092">"RFCOMM ಚಾನಲ್ ಅನ್ನು ಫಿಲ್ಟರ್ ಮಾಡಿ"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</item>
+ <item msgid="2505973306504851132">"ಅಕ್ಷರಗಳ ಸ್ಟ್ರಿಂಗ್ನೊಂದಿಗೆ ಭರ್ತಿ ಮಾಡಿ"</item>
+ <item msgid="5883011000629613855">"ಶೀರ್ಷಿಕೆಯನ್ನು ಮಾತ್ರ ಬಿಡಿ"</item>
+ <item msgid="1051534112762023603">"ಸಂಪೂರ್ಣವಾಗಿ ತೆಗೆದುಹಾಕಿ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ಡೀಫಾಲ್ಟ್)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-kn/strings.xml b/packages/SettingsLib/res/values-kn/strings.xml
index a3ce673..353c7cc7 100644
--- a/packages/SettingsLib/res/values-kn/strings.xml
+++ b/packages/SettingsLib/res/values-kn/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ಕ್ಲಿಪ್ನ ಗಡಿಗಳು, ಅಂಚುಗಳು, ಇತ್ಯಾದಿ ತೋರಿಸು."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL ಲೇಔಟ್ ಡೈರೆಕ್ಷನ್ ಫೋರ್ಸ್ ಮಾಡುವಿಕೆ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ಎಲ್ಲ ಭಾಷೆಗಳಿಗಾಗಿ, RTL ಗೆ ಸ್ಕ್ರೀನ್ ಲೇಔಟ್ ಡೈರೆಕ್ಷನ್ ಅನ್ನು ಫೋರ್ಸ್ ಮಾಡಿ"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"ಪಾರದರ್ಶಕ ನ್ಯಾವಿಗೇಶನ್ ಬಾರ್"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ನ್ಯಾವಿಗೇಶನ್ ಬಾರ್ನ ಹಿನ್ನೆಲೆಯ ಬಣ್ಣವನ್ನು ಡೀಫಾಲ್ಟ್ ಆಗಿ ಪಾರದರ್ಶಕವಾಗಿಸಿ"</string>
<string name="window_blurs" msgid="6831008984828425106">"ವಿಂಡೋ-ಮಟ್ಟ ಬ್ಲರ್ ಅನುಮತಿಸಿ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ಫೋರ್ಸ್ ಮಾಡಿ"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ಅಪ್ಲಿಕೇಶನ್ಗಳಲ್ಲಿ 4x MSAA ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"ಬಲಕ್ಕೆ ಸರಿಸಿ"</item>
<item msgid="324200556467459329">"ಮೇಲಕ್ಕೆ ಸರಿಸಿ"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ko/arrays.xml b/packages/SettingsLib/res/values-ko/arrays.xml
index b4a035a..bc739b9 100644
--- a/packages/SettingsLib/res/values-ko/arrays.xml
+++ b/packages/SettingsLib/res/values-ko/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"필터링 사용 설정됨"</item>
<item msgid="2779123106632690576">"사용 설정됨"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL 헤더만 남김"</item>
+ <item msgid="2776218217644557831">"A2DP 미디어 패킷 필터링"</item>
+ <item msgid="8163235976612675092">"RFCOMM 채널 필터링"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"사용 중지"</item>
+ <item msgid="2505973306504851132">"문자열로 채움"</item>
+ <item msgid="5883011000629613855">"헤더만 남김"</item>
+ <item msgid="1051534112762023603">"완전히 삭제"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5(기본값)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ko/strings.xml b/packages/SettingsLib/res/values-ko/strings.xml
index 27c5a70..ad71c09 100644
--- a/packages/SettingsLib/res/values-ko/strings.xml
+++ b/packages/SettingsLib/res/values-ko/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"클립 경계, 여백 등을 표시"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL 레이아웃 방향 강제 적용"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"모든 언어에 대해 화면 레이아웃 방향을 RTL로 강제 적용"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"탐색 메뉴 투명하게 하기"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"기본적으로 탐색 메뉴의 배경 색상을 투명하게 하기"</string>
<string name="window_blurs" msgid="6831008984828425106">"창 수준 블러 허용"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA 강제 사용"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 앱에서 4x MSAA 사용"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"오른쪽으로 이동"</item>
<item msgid="324200556467459329">"위로 이동"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ky/arrays.xml b/packages/SettingsLib/res/values-ky/arrays.xml
index 657e63e..71e10da 100644
--- a/packages/SettingsLib/res/values-ky/arrays.xml
+++ b/packages/SettingsLib/res/values-ky/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Чыпкалар иштетилди"</item>
<item msgid="2779123106632690576">"Иштетилди"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL аталыштарын гана калтыруу"</item>
+ <item msgid="2776218217644557831">"A2DP медиа топтомдорун чыпкалоо"</item>
+ <item msgid="8163235976612675092">"RFCOMM каналын чыпкалоо"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Өчүрүү"</item>
+ <item msgid="2505973306504851132">"Символдордун сабы менен толтуруу"</item>
+ <item msgid="5883011000629613855">"Аталышын гана калтыруу"</item>
+ <item msgid="1051534112762023603">"Толугу менен өчүрүү"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Демейки)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ky/strings.xml b/packages/SettingsLib/res/values-ky/strings.xml
index 604731a..704f0cd 100644
--- a/packages/SettingsLib/res/values-ky/strings.xml
+++ b/packages/SettingsLib/res/values-ky/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Кесилген нерсенин чектери жана жээктери көрүнөт"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Интерфейсти чагылдыруу"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Интерфейстин элементтери бардык тилдерде оңдон солго карай жайгашат"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Тунук чабыттоо тилкеси"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Чабыттоо тилкесинин фонунун түсүн демейки боюнча тунук кылуу"</string>
<string name="window_blurs" msgid="6831008984828425106">"Терезенин деңгээлинде бүдөмүктөтүүгө уруксат берүү"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA иштетүү"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 колдонмолорунда 4x MSAA иштетилет"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Оңго жылдыруу"</item>
<item msgid="324200556467459329">"Жогору жылдыруу"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lo/arrays.xml b/packages/SettingsLib/res/values-lo/arrays.xml
index 11688d4..79cdd6f 100644
--- a/packages/SettingsLib/res/values-lo/arrays.xml
+++ b/packages/SettingsLib/res/values-lo/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"ເປີດການກັ່ນຕອງແລ້ວ"</item>
<item msgid="2779123106632690576">"ເປີດໃຊ້ແລ້ວ"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ປະໄວ້ພຽງສ່ວນຫົວ ACL ເທົ່ານັ້ນ"</item>
+ <item msgid="2776218217644557831">"ກັ່ນຕອງແພັກເກດສື່ A2DP"</item>
+ <item msgid="8163235976612675092">"ກັ່ນຕອງຊ່ອງ RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"ປິດການນຳໃຊ້"</item>
+ <item msgid="2505973306504851132">"ຕື່ມດ້ວຍສະຕຣິງຂອງຕົວອັກສອນ"</item>
+ <item msgid="5883011000629613855">"ປະໄວ້ພຽງສ່ວນຫົວເທົ່ານັ້ນ"</item>
+ <item msgid="1051534112762023603">"ລຶບອອກໝົດ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ຄ່າເລີ່ມຕົ້ນ)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-lo/strings.xml b/packages/SettingsLib/res/values-lo/strings.xml
index 5722f4f..242c855 100644
--- a/packages/SettingsLib/res/values-lo/strings.xml
+++ b/packages/SettingsLib/res/values-lo/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ສະແດງໜ້າປົກຄລິບ, ຂອບ ແລະ ອື່ນໆ."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"ບັງຄັບໃຫ້ຮູບຮ່າງຂຽນຈາກຂວາຫາຊ້າຍ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ບັງຄັບໃຫ້ຮູບຮ່າງໜ້າຈໍ ຂຽນຈາກຂວາໄປຊ້າຍ ສຳລັບທຸກພາສາ"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"ແຖບການນຳທາງແບບໂປ່ງໃສ"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ເຮັດໃຫ້ສີພື້ນຫຼັງແຖບການນຳທາງມີຄວາມໂປ່ງໃສແບບເລີ່ມຕົ້ນ"</string>
<string name="window_blurs" msgid="6831008984828425106">"ອະນຸຍາດການມົວໃນລະດັບໜ້າຈໍ"</string>
<string name="force_msaa" msgid="4081288296137775550">"ບັງຄັບໃຊ້ 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"ເປິດໃຊ້ 4x MSAA ໃນແອັບ OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"ຍ້າຍໄປຂວາ"</item>
<item msgid="324200556467459329">"ຍ້າຍຂຶ້ນ"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lt/arrays.xml b/packages/SettingsLib/res/values-lt/arrays.xml
index 6718660..8e9fe85 100644
--- a/packages/SettingsLib/res/values-lt/arrays.xml
+++ b/packages/SettingsLib/res/values-lt/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Įgalinta filtruota"</item>
<item msgid="2779123106632690576">"Įgalinta"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Palikti tik ACL antraštes"</item>
+ <item msgid="2776218217644557831">"Filtruoti A2DP medijos paketus"</item>
+ <item msgid="8163235976612675092">"Filtruoti RFCOMM kanalą"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Išjungti"</item>
+ <item msgid="2505973306504851132">"Užpildyti simbolių eilute"</item>
+ <item msgid="5883011000629613855">"Palikti tik antraštę"</item>
+ <item msgid="1051534112762023603">"Visiškai pašalinti"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (numatytoji)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-lt/strings.xml b/packages/SettingsLib/res/values-lt/strings.xml
index 949a865..7a8aff5 100644
--- a/packages/SettingsLib/res/values-lt/strings.xml
+++ b/packages/SettingsLib/res/values-lt/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Rodyti iškarpų ribas, kraštines ir t. t."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Išdėst. iš dešin. į kairę"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Nust. visų lokalių ekran. išdėst. iš deš. į kairę"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Skaidri naršymo juosta"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Padaryti naršymo juostos foną skaidrų pagal numatytuosius nustatymus"</string>
<string name="window_blurs" msgid="6831008984828425106">"Leisti lango suliejimus"</string>
<string name="force_msaa" msgid="4081288296137775550">"Priverst. vykdyti 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Įgalinti 4x MSAA „OpenGL ES 2.0“ programose"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Perkelti dešinėn"</item>
<item msgid="324200556467459329">"Perkelti aukštyn"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-lv/arrays.xml b/packages/SettingsLib/res/values-lv/arrays.xml
index 3e1869a..af62148 100644
--- a/packages/SettingsLib/res/values-lv/arrays.xml
+++ b/packages/SettingsLib/res/values-lv/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Iespējot filtrētos"</item>
<item msgid="2779123106632690576">"Iespējots"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Atstāt tikai ACL galvenes"</item>
+ <item msgid="2776218217644557831">"Filtrēt A2DP multivides paketes"</item>
+ <item msgid="8163235976612675092">"Filtrēt RFCOMM kanālu"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Atspējot"</item>
+ <item msgid="2505973306504851132">"Aizpildīt ar rakstzīmju virkni"</item>
+ <item msgid="5883011000629613855">"Atstāt tikai galveni"</item>
+ <item msgid="1051534112762023603">"Pilnīgi noņemt"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (noklusējums)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-lv/strings.xml b/packages/SettingsLib/res/values-lv/strings.xml
index 0e23cee..6425e16 100644
--- a/packages/SettingsLib/res/values-lv/strings.xml
+++ b/packages/SettingsLib/res/values-lv/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Rādīt klipu robežas, malas utt."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Virziens no labās uz kreiso (Obligāts) WL: 295"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Obl. izkārt. virz. no labās uz kr. pusi visām lok."</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Caurspīdīga navigācijas josla"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Pēc noklusējuma iestatīt navigācijas joslai caurspīdīgu fona krāsu"</string>
<string name="window_blurs" msgid="6831008984828425106">"Atļaut logu aizmiglošanu"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA piespiedu palaiš."</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Iespējot 4x MSAA OpenGL ES 2.0 lietotnēs"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Pārvietojiet pirkstu pa labi"</item>
<item msgid="324200556467459329">"Pārvietojiet pirkstu augšup"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mk/arrays.xml b/packages/SettingsLib/res/values-mk/arrays.xml
index ebf387b..3684edb 100644
--- a/packages/SettingsLib/res/values-mk/arrays.xml
+++ b/packages/SettingsLib/res/values-mk/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Овозможено е филтрирано"</item>
<item msgid="2779123106632690576">"Овозможено"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Оставете само ACL-заглавија"</item>
+ <item msgid="2776218217644557831">"Филтрирај ги A2DP-аудиовизуелните пакети"</item>
+ <item msgid="8163235976612675092">"Филтрирај го RFCOMM-каналот"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Оневозможи"</item>
+ <item msgid="2505973306504851132">"Пополнете со низа знаци"</item>
+ <item msgid="5883011000629613855">"Оставете само заглавие"</item>
+ <item msgid="1051534112762023603">"Целосно отстранете"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Стандардна)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-mk/strings.xml b/packages/SettingsLib/res/values-mk/strings.xml
index f57412c..558b1a3 100644
--- a/packages/SettingsLib/res/values-mk/strings.xml
+++ b/packages/SettingsLib/res/values-mk/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Прикажи граници на клип, маргини итн."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Принудно користи RTL за насока"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Принудно постави насока на распоред на екранот во RTL за сите локални стандарди"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Проѕирна лента за навигација"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Направете ја заднината на лентата за навигација стандардно проѕирна"</string>
<string name="window_blurs" msgid="6831008984828425106">"Дозволи замаглување прозорец"</string>
<string name="force_msaa" msgid="4081288296137775550">"Принудно користи 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Овозможи 4x MSAA за апликации OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Преместете надесно"</item>
<item msgid="324200556467459329">"Преместете нагоре"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ml/arrays.xml b/packages/SettingsLib/res/values-ml/arrays.xml
index 30adb57..29c4a55 100644
--- a/packages/SettingsLib/res/values-ml/arrays.xml
+++ b/packages/SettingsLib/res/values-ml/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"ഫിൽട്ടറിംഗ് പ്രവർത്തനക്ഷമമാക്കി"</item>
<item msgid="2779123106632690576">"പ്രവർത്തനക്ഷമമാക്കി"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL ഹെഡ്ഡറുകൾ മാത്രം വിടുക"</item>
+ <item msgid="2776218217644557831">"A2DP മീഡിയാ പാക്കറ്റുകൾ ഫിൽട്ടർ ചെയ്യുക"</item>
+ <item msgid="8163235976612675092">"RFCOMM ചാനൽ ഫിൽട്ടർ ചെയ്യുക"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"പ്രവർത്തനരഹിതമാക്കുക"</item>
+ <item msgid="2505973306504851132">"പ്രതീകങ്ങളുടെ സ്ട്രിംഗ് ഉപയോഗിച്ച് പൂരിപ്പിക്കുക"</item>
+ <item msgid="5883011000629613855">"ഹെഡ്ഡർ മാത്രം വിടുക"</item>
+ <item msgid="1051534112762023603">"പൂർണ്ണമായും നീക്കം ചെയ്യുക"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ഡിഫോൾട്ട്)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ml/strings.xml b/packages/SettingsLib/res/values-ml/strings.xml
index 6d39bc2..75f9037 100644
--- a/packages/SettingsLib/res/values-ml/strings.xml
+++ b/packages/SettingsLib/res/values-ml/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ക്ലിപ്പ് ബൗണ്ടുകൾ, മാർജിനുകൾ തുടങ്ങിയവ ദൃശ്യമാക്കുക"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL ലേഔട്ട് ഡയറക്ഷൻ നിർബന്ധമാക്കുക"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"എല്ലാ ഭാഷകൾക്കുമായി സ്ക്രീൻ ലേഔട്ട് ഡയറക്ഷൻ RTL-ലേക്ക് നിർബന്ധമാക്കുക"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"സുതാര്യമായ നാവിഗേഷൻ ബാർ"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"നാവിഗേഷൻ ബാറിന്റെ പശ്ചാത്തല നിറം ഡിഫോൾട്ട് ആയി സുതാര്യമാക്കുക"</string>
<string name="window_blurs" msgid="6831008984828425106">"വിൻഡോ-ലെവൽ മങ്ങിക്കൽ അനുവദിക്കൂ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA നിർബന്ധമാക്കുക"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ആപ്പുകളിൽ 4x MSAA പ്രവർത്തനക്ഷമമാക്കൂ"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"വലത്തേക്ക് നീക്കുക"</item>
<item msgid="324200556467459329">"മുകളിലേക്ക് നീക്കുക"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mn/arrays.xml b/packages/SettingsLib/res/values-mn/arrays.xml
index d03fcd6..b96edd9 100644
--- a/packages/SettingsLib/res/values-mn/arrays.xml
+++ b/packages/SettingsLib/res/values-mn/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Идэвхжүүлсэн Шүүсэн"</item>
<item msgid="2779123106632690576">"Идэвхжүүлсэн"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Зөвхөн ACL толгой хэсгийг үлдээх"</item>
+ <item msgid="2776218217644557831">"A2DP медиа пакетыг шүүх"</item>
+ <item msgid="8163235976612675092">"RFCOMM сувгийг шүүх"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Идэвхгүй болгох"</item>
+ <item msgid="2505973306504851132">"Тэмдэгтийн мөрөөр дүүргэх"</item>
+ <item msgid="5883011000629613855">"Зөвхөн толгой хэсгийг үлдээх"</item>
+ <item msgid="1051534112762023603">"Бүрэн хасах"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Өгөгдмөл)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-mn/strings.xml b/packages/SettingsLib/res/values-mn/strings.xml
index b1c25f5..e53992a 100644
--- a/packages/SettingsLib/res/values-mn/strings.xml
+++ b/packages/SettingsLib/res/values-mn/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Клипийн зах, хязгаар зэргийг харуулах"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL байрлалын чиглэлийг хүчээр тогтоох"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Бүх локалын хувьд дэлгэцийн байрлалын чиглэлийг хүчээр RTL болгох"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Навигацын нэвт харагдах самбар"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Навигацын самбарын дэвсгэр өнгийг өгөгдмөлөөр нэвт харагддаг болгоно"</string>
<string name="window_blurs" msgid="6831008984828425106">"Цонхны түвшний бүдгэрүүлэлтийг зөвшөөрөх"</string>
<string name="force_msaa" msgid="4081288296137775550">"Хүчээр 4x MSAA ашиглах"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 апп-уудад 4x MSAA-г идэвхжүүлэх"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Баруун тийш зөөх"</item>
<item msgid="324200556467459329">"Дээш зөөх"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-mr/arrays.xml b/packages/SettingsLib/res/values-mr/arrays.xml
index 68eff75..db0f56a 100644
--- a/packages/SettingsLib/res/values-mr/arrays.xml
+++ b/packages/SettingsLib/res/values-mr/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"फिल्टर केलेले सुरू केले"</item>
<item msgid="2779123106632690576">"सुरू केले"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"फक्त ACL हेडरमधून बाहेर पडा"</item>
+ <item msgid="2776218217644557831">"A2DP मीडिया पॅकेट फिल्टर करा"</item>
+ <item msgid="8163235976612675092">"RFCOMM चॅनल फिल्टर करा"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"बंद करा"</item>
+ <item msgid="2505973306504851132">"वर्णांची स्ट्रिंग वापरून भरा"</item>
+ <item msgid="5883011000629613855">"फक्त हेडरमधून बाहेर पडा"</item>
+ <item msgid="1051534112762023603">"पूर्णपणे काढून टाका"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (डीफॉल्ट)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-mr/strings.xml b/packages/SettingsLib/res/values-mr/strings.xml
index b015ba8..aa2eae4 100644
--- a/packages/SettingsLib/res/values-mr/strings.xml
+++ b/packages/SettingsLib/res/values-mr/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"क्लिप सीमा, समास इत्यादी दर्शवा."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL लेआउट दिशानिर्देशाची सक्ती करा"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"सर्व लोकॅलसाठी RTL स्क्रीन लेआउट दिशानिर्देशाची सक्ती करा"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"पारदर्शक नेव्हिगेशन बार"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"नेव्हिगेशन बार बॅकग्राउंडचा रंग बाय डीफॉल्ट पारदर्शक करा"</string>
<string name="window_blurs" msgid="6831008984828425106">"विंडो पातळीवरील ब्लरना अनुमती द्या"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ची सक्ती करा"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ॲप्समध्ये 4x MSAA सुरू करा"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"उजवीकडे हलवा"</item>
<item msgid="324200556467459329">"वरती हलवा"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ms/arrays.xml b/packages/SettingsLib/res/values-ms/arrays.xml
index efdd879..3ee7131 100644
--- a/packages/SettingsLib/res/values-ms/arrays.xml
+++ b/packages/SettingsLib/res/values-ms/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Didayakan Ditapis"</item>
<item msgid="2779123106632690576">"Didayakan"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Tinggalkan pengepala ACL sahaja"</item>
+ <item msgid="2776218217644557831">"Tapis paket media A2DP"</item>
+ <item msgid="8163235976612675092">"Tapis saluran RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Lumpuhkan"</item>
+ <item msgid="2505973306504851132">"Isi dengan rentetan aksara"</item>
+ <item msgid="5883011000629613855">"Tinggalkan pengepala sahaja"</item>
+ <item msgid="1051534112762023603">"Alih keluar sepenuhnya"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Lalai)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ms/strings.xml b/packages/SettingsLib/res/values-ms/strings.xml
index c557bfd..78f5121 100644
--- a/packages/SettingsLib/res/values-ms/strings.xml
+++ b/packages/SettingsLib/res/values-ms/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Tunjukkan batas klip, margin dll."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Paksa arah reka letak RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Paksa arah reka letak skrin RTL bagi semua tempat peristiwa"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Bar navigasi lut sinar"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Tukarkan warna latar bar navigasi kepada lut sinar secara lalai"</string>
<string name="window_blurs" msgid="6831008984828425106">"Benarkan kabur tahap tetingkap"</string>
<string name="force_msaa" msgid="4081288296137775550">"Paksa 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Dayakan 4x MSAA dalam apl OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Alih ke kanan"</item>
<item msgid="324200556467459329">"Alih ke atas"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-my/arrays.xml b/packages/SettingsLib/res/values-my/arrays.xml
index 4d0b792..9c5ee69 100644
--- a/packages/SettingsLib/res/values-my/arrays.xml
+++ b/packages/SettingsLib/res/values-my/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"စစ်ထုတ်ထားသည်များကို ဖွင့်ထားသည်"</item>
<item msgid="2779123106632690576">"ဖွင့်ထားသည်"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL ခေါင်းစီးများသာ ချန်ထားခြင်း"</item>
+ <item msgid="2776218217644557831">"A2DP မီဒီယာဒေတာများ စစ်ထုတ်ခြင်း"</item>
+ <item msgid="8163235976612675092">"RFCOMM ချန်နယ် စစ်ထုတ်ခြင်း"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"ပိတ်ရန်"</item>
+ <item msgid="2505973306504851132">"အက္ခရာတွဲဖြင့် ဖြည့်ရန်"</item>
+ <item msgid="5883011000629613855">"ခေါင်းစီးသာ ချန်ထားရန်"</item>
+ <item msgid="1051534112762023603">"အပြည့်ဖယ်ရှားရန်"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (မူလ)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-my/strings.xml b/packages/SettingsLib/res/values-my/strings.xml
index dc013d5..ee27607 100644
--- a/packages/SettingsLib/res/values-my/strings.xml
+++ b/packages/SettingsLib/res/values-my/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ဖြတ်ပိုင်းအနားသတ်များ၊ အနားများ စသဖြင့် ပြပါ။"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL အပြင်အဆင်အတိုင်း ဖြစ်စေခြင်း"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ဘာသာစကားအားလုံးအတွက် RTL အပြင်အဆင်အတိုင်း ဖြစ်စေသည်"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"လမ်းညွှန်ဘား အကြည်"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"လမ်းညွှန်ဘား၏ နောက်ခံအရောင်ကို မူရင်းအားဖြင့် အကြည်ဖြစ်အောင် လုပ်သည်"</string>
<string name="window_blurs" msgid="6831008984828425106">"ဝင်းဒိုးအဆင့် မှုန်ဝါးမှု ခွင့်ပြုရန်"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA မဖြစ်မနေဖွင့်ခြင်း"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 အက်ပ်များတွင် 4x MSAA ဖွင့်သည်"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"ညာသို့ရွှေ့ရန်"</item>
<item msgid="324200556467459329">"အပေါ်သို့ရွှေ့ရန်"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-nb/arrays.xml b/packages/SettingsLib/res/values-nb/arrays.xml
index 9293bdad..3029329 100644
--- a/packages/SettingsLib/res/values-nb/arrays.xml
+++ b/packages/SettingsLib/res/values-nb/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtrering er slått på"</item>
<item msgid="2779123106632690576">"Slått på"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"La bare ACL-hoder være igjen"</item>
+ <item msgid="2776218217644557831">"Filtrer A2DP-mediepakker"</item>
+ <item msgid="8163235976612675092">"Filtrer RFCOMM-kanalen"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Deaktiver"</item>
+ <item msgid="2505973306504851132">"Fyll med en streng med tegn"</item>
+ <item msgid="5883011000629613855">"La bare hodet være igjen"</item>
+ <item msgid="1051534112762023603">"Fjern fullstendig"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (standard)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-nb/strings.xml b/packages/SettingsLib/res/values-nb/strings.xml
index 2a14766..241d6d5 100644
--- a/packages/SettingsLib/res/values-nb/strings.xml
+++ b/packages/SettingsLib/res/values-nb/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Vis kanter, marger osv."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Tvungen RTL-layout"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Tving RTL-retning på skjermen for alle språk"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Gjennomsiktig navigasjonsrad"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Gjør bakgrunnsfargen på navigasjonsraden gjennomsiktig som standard"</string>
<string name="window_blurs" msgid="6831008984828425106">"Tillat uskarphet i vindu"</string>
<string name="force_msaa" msgid="4081288296137775550">"Tving 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Slå på 4x MSAA i OpenGL ES 2.0-apper"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Flytt til høyre"</item>
<item msgid="324200556467459329">"Flytt opp"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ne/arrays.xml b/packages/SettingsLib/res/values-ne/arrays.xml
index 29a7c60..451f198 100644
--- a/packages/SettingsLib/res/values-ne/arrays.xml
+++ b/packages/SettingsLib/res/values-ne/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"फिल्टर सक्षम पारियो"</item>
<item msgid="2779123106632690576">"सक्षम पारिएको छ"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL हेडर मात्र छाड्नुहोस्"</item>
+ <item msgid="2776218217644557831">"A2DP मिडिया प्याकेटहरू फिल्टर गर्नुहोस्"</item>
+ <item msgid="8163235976612675092">"RFCOMM च्यानल फिल्टर गर्नुहोस्"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"अफ गर्नुहोस्"</item>
+ <item msgid="2505973306504851132">"वर्णको स्ट्रिङ हाल्नुहोस्"</item>
+ <item msgid="5883011000629613855">"हेडर मात्र छाड्नुहोस्"</item>
+ <item msgid="1051534112762023603">"पूरै हटाउनुहोस्"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP १.५ (डिफल्ट)"</item>
<item msgid="1637054408779685086">"AVRCP १.३"</item>
diff --git a/packages/SettingsLib/res/values-ne/strings.xml b/packages/SettingsLib/res/values-ne/strings.xml
index 831ed2f..140fdcb 100644
--- a/packages/SettingsLib/res/values-ne/strings.xml
+++ b/packages/SettingsLib/res/values-ne/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"क्लिप सीमा, मार्जिन, इत्यादि देखाइयोस्।"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL लेआउट बलपूर्वक प्रयोग गरियोस्"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"सबै लोकेलमा RTLमा स्क्रिन लेआउट बलपूर्वक प्रयोग गरियोस्"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"पारदर्शी नेभिगेसन बार"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"नेभिगेसन बारको ब्याकग्राउन्डको रङ स्वतः पारदर्शी बनाउनुहोस्"</string>
<string name="window_blurs" msgid="6831008984828425106">"विन्डो ब्लर गरियोस्"</string>
<string name="force_msaa" msgid="4081288296137775550">"बलपूर्वक 4x MSAA प्रयोग गरियोस्"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES २.० एपमा ४x MSAA अन गरियोस्"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"दायाँतिर सार्नुहोस्"</item>
<item msgid="324200556467459329">"माथितिर सार्नुहोस्"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-nl/arrays.xml b/packages/SettingsLib/res/values-nl/arrays.xml
index 460302c..f40eec1 100644
--- a/packages/SettingsLib/res/values-nl/arrays.xml
+++ b/packages/SettingsLib/res/values-nl/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Gefilterd staat aan"</item>
<item msgid="2779123106632690576">"Aangezet"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Alleen ACL-headers laten staan"</item>
+ <item msgid="2776218217644557831">"A2DP-mediapakketten filteren"</item>
+ <item msgid="8163235976612675092">"RFCOMM-kanaal filteren"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Uitzetten"</item>
+ <item msgid="2505973306504851132">"Vullen met tekenreeks"</item>
+ <item msgid="5883011000629613855">"Alleen header laten staan"</item>
+ <item msgid="1051534112762023603">"Helemaal verwijderen"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (standaard)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-nl/strings.xml b/packages/SettingsLib/res/values-nl/strings.xml
index 55852d2..64ee7ede 100644
--- a/packages/SettingsLib/res/values-nl/strings.xml
+++ b/packages/SettingsLib/res/values-nl/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Toon clipgrenzen, marges en meer"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"V.r.n.l.-indelingsrichting afdwingen"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Stel de schermindelingsrichting geforceerd in op v.r.n.l. voor alle talen"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Doorzichtige navigatiebalk"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Maak de achtergrondkleur van de navigatiebalk standaard doorzichtig"</string>
<string name="window_blurs" msgid="6831008984828425106">"Vervagen op vensterniveau toestaan"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA forceren"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Zet 4x MSAA aan in OpenGL ES 2.0-apps"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Naar rechts verplaatsen"</item>
<item msgid="324200556467459329">"Omhoog verplaatsen"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-or/arrays.xml b/packages/SettingsLib/res/values-or/arrays.xml
index 439bd72..8c5589c 100644
--- a/packages/SettingsLib/res/values-or/arrays.xml
+++ b/packages/SettingsLib/res/values-or/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"ଫିଲ୍ଟର୍କୁ ସକ୍ଷମ କରାଯାଇଛି"</item>
<item msgid="2779123106632690576">"ସକ୍ଷମ କରାଯାଇଛି"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"କେବଳ ACL ହେଡରଗୁଡ଼ିକୁ ଛାଡ଼ି ଦିଅନ୍ତୁ"</item>
+ <item msgid="2776218217644557831">"A2DP ମିଡିଆ ପେକେଟଗୁଡ଼ିକୁ ଫିଲ୍ଟର କରନ୍ତୁ"</item>
+ <item msgid="8163235976612675092">"RFCOMM ଚେନେଲକୁ ଫିଲ୍ଟର କରନ୍ତୁ"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"ଅକ୍ଷମ କରନ୍ତୁ"</item>
+ <item msgid="2505973306504851132">"କେରେକ୍ଟରଗୁଡ଼ିକର ଷ୍ଟ୍ରିଂ ସହ ପୂରଣ କରନ୍ତୁ"</item>
+ <item msgid="5883011000629613855">"କେବଳ ହେଡରକୁ ଛାଡ଼ି ଦିଅନ୍ତୁ"</item>
+ <item msgid="1051534112762023603">"ସମ୍ପୂର୍ଣ୍ଣ ଭାବେ କାଢ଼ି ଦିଅନ୍ତୁ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ଡିଫଲ୍ଟ)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-or/strings.xml b/packages/SettingsLib/res/values-or/strings.xml
index 1e61b24..b68c1f0 100644
--- a/packages/SettingsLib/res/values-or/strings.xml
+++ b/packages/SettingsLib/res/values-or/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"କ୍ଲିପ୍ ବାଉଣ୍ଡ, ମାର୍ଜିନ୍ ଆଦି ଦେଖନ୍ତୁ"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL ଲେଆଉଟ୍ ଦିଗ ବାଧ୍ୟ କରନ୍ତୁ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ସମସ୍ତ ଲୋକେଲ୍ ସକାଶେ ସ୍କ୍ରୀନ୍ ଲେଆଉଟ୍ ଦିଗ RTL ପାଇଁ ବାଧ୍ୟ କରନ୍ତୁ"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"ଟ୍ରାନ୍ସପରେଣ୍ଟ ନାଭିଗେସନ ବାର"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ଡିଫଲ୍ଟ ଭାବେ ନାଭିଗେସନ ବାର ପୃଷ୍ଠପଟ ରଙ୍ଗକୁ ଟ୍ରାନ୍ସପରେଣ୍ଟ କରନ୍ତୁ"</string>
<string name="window_blurs" msgid="6831008984828425106">"ୱିଣ୍ଡୋ-ଲେଭେଲରେ ବ୍ଲରକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ବାଧ୍ୟ କରନ୍ତୁ"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ଆପ୍ରେ 4x MSAA ସକ୍ଷମ କରନ୍ତୁ"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"ଡାହାଣକୁ ମୁଭ କରନ୍ତୁ"</item>
<item msgid="324200556467459329">"ଉପରକୁ ମୁଭ କରନ୍ତୁ"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pa/arrays.xml b/packages/SettingsLib/res/values-pa/arrays.xml
index f4bfcd1..533788a 100644
--- a/packages/SettingsLib/res/values-pa/arrays.xml
+++ b/packages/SettingsLib/res/values-pa/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"ਫਿਲਟਰ ਕੀਤਿਆਂ ਨੂੰ ਚਾਲੂ ਕੀਤਾ ਗਿਆ"</item>
<item msgid="2779123106632690576">"ਚਾਲੂ"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ਸਿਰਫ਼ ACL ਸਿਰਲੇਖਾਂ ਨੂੰ ਛੱਡੋ"</item>
+ <item msgid="2776218217644557831">"A2DP ਮੀਡੀਆ ਪੈਕੇਟਾਂ ਨੂੰ ਫਿਲਟਰ ਕਰੋ"</item>
+ <item msgid="8163235976612675092">"RFCOMM ਚੈਨਲ ਨੂੰ ਫਿਲਟਰ ਕਰੋ"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"ਬੰਦ ਕਰੋ"</item>
+ <item msgid="2505973306504851132">"ਅੱਖਰ-ਚਿੰਨ੍ਹਾਂ ਦੀ ਸਤਰ ਨਾਲ ਭਰੋ"</item>
+ <item msgid="5883011000629613855">"ਸਿਰਫ਼ ਸਿਰਲੇਖ ਨੂੰ ਛੱਡੋ"</item>
+ <item msgid="1051534112762023603">"ਪੂਰੀ ਤਰ੍ਹਾਂ ਹਟਾਓ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ਪੂਰਵ-ਨਿਰਧਾਰਿਤ)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-pa/strings.xml b/packages/SettingsLib/res/values-pa/strings.xml
index d4b7632..08b0787 100644
--- a/packages/SettingsLib/res/values-pa/strings.xml
+++ b/packages/SettingsLib/res/values-pa/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ਕਲਿੱਪ ਸੀਮਾਵਾਂ, ਹਾਸ਼ੀਏ ਆਦਿ ਦਿਖਾਓ"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"ਸੱਜੇ ਤੋਂ ਖੱਬੇ ਵਾਲਾ ਖਾਕਾ ਲਾਗੂ ਕਰੋ"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"ਸਾਰੀਆਂ ਭਾਸ਼ਾਵਾਂ ਲਈ ਸਕ੍ਰੀਨ \'ਤੇ ਸੱਜੇ ਤੋਂ ਖੱਬੇ ਵਾਲਾ ਖਾਕਾ ਲਾਗੂ ਕਰੋ"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"ਪਾਰਦਰਸ਼ੀ ਨੈਵੀਗੇਸ਼ਨ ਵਾਲੀ ਪੱਟੀ"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ਨੈਵੀਗੇਸ਼ਨ ਵਾਲੀ ਪੱਟੀ ਦੇ ਬੈਕਗ੍ਰਾਊਂਡ ਰੰਗ ਨੂੰ ਪੂਰਵ-ਨਿਰਧਾਰਿਤ ਤੌਰ \'ਤੇ ਪਾਰਦਰਸ਼ੀ ਬਣਾਓ"</string>
<string name="window_blurs" msgid="6831008984828425106">"ਵਿੰਡੋ-ਪੱਧਰ \'ਤੇ ਧੁੰਦਲਾ ਕਰਨ ਦਿਓ"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ਜ਼ਬਰਦਸਤੀ ਲਾਗੂ ਕਰੋ"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ਐਪਾਂ ਵਿੱਚ 4x MSAA ਨੂੰ ਚਾਲੂ ਕਰੋ"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"ਸੱਜੇ ਲਿਜਾਓ"</item>
<item msgid="324200556467459329">"ਉੱਪਰ ਲਿਜਾਓ"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pl/arrays.xml b/packages/SettingsLib/res/values-pl/arrays.xml
index a305a65..f665850 100644
--- a/packages/SettingsLib/res/values-pl/arrays.xml
+++ b/packages/SettingsLib/res/values-pl/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtrowanie włączone"</item>
<item msgid="2779123106632690576">"Włączono"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Zostaw wyłącznie nagłówki listy kontroli dostępu"</item>
+ <item msgid="2776218217644557831">"Filtruj pakiety multimediów A2DP"</item>
+ <item msgid="8163235976612675092">"Filtruj kanały RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Wyłącz"</item>
+ <item msgid="2505973306504851132">"Uzupełnij ciągiem znaków"</item>
+ <item msgid="5883011000629613855">"Zostaw wyłącznie nagłówek"</item>
+ <item msgid="1051534112762023603">"Usuń w całości"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (domyślnie)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-pl/strings.xml b/packages/SettingsLib/res/values-pl/strings.xml
index ddff92c..089bc2d 100644
--- a/packages/SettingsLib/res/values-pl/strings.xml
+++ b/packages/SettingsLib/res/values-pl/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Pokazuj granice przycięcia, marginesy itd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Układ od prawej do lewej"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Wymuszaj układ ekranu od prawej do lewej dla wszystkich języków"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Przezroczysty pasek nawigacyjny"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Ustaw domyślnie przezroczyste tło paska nawigacyjnego"</string>
<string name="window_blurs" msgid="6831008984828425106">"Zezwalaj na rozmycie na poziomie okna"</string>
<string name="force_msaa" msgid="4081288296137775550">"Wymuszaj 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Włączaj 4x MSAA w aplikacjach OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Przenieś w prawo"</item>
<item msgid="324200556467459329">"Przenieś w górę"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rBR/arrays.xml b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
index eff0922..3b61e1a 100644
--- a/packages/SettingsLib/res/values-pt-rBR/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtro ativado"</item>
<item msgid="2779123106632690576">"Ativado"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Deixar apenas cabeçalhos da Access Control List"</item>
+ <item msgid="2776218217644557831">"Filtrar pacotes de mídia A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrar canal RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Desativar"</item>
+ <item msgid="2505973306504851132">"Preencher com string de caracteres"</item>
+ <item msgid="5883011000629613855">"Deixar apenas o cabeçalho"</item>
+ <item msgid="1051534112762023603">"Remover totalmente"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (padrão)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-pt-rBR/strings.xml b/packages/SettingsLib/res/values-pt-rBR/strings.xml
index 3a48c3d..44110c2 100644
--- a/packages/SettingsLib/res/values-pt-rBR/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rBR/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostrar limites de corte, margens, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forçar layout da direita p/ esquerda"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forçar a direção do layout da direita para a esquerda para todas as localidades"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barra de navegação transparente"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Deixar o plano de fundo da barra de navegação transparente por padrão"</string>
<string name="window_blurs" msgid="6831008984828425106">"Permitir desfoques de janela"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forçar 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ativar 4x MSAA em apps OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Mover para direita"</item>
<item msgid="324200556467459329">"Mover para cima"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt-rPT/arrays.xml b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
index 0553aac..9b472dd 100644
--- a/packages/SettingsLib/res/values-pt-rPT/arrays.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/arrays.xml
@@ -55,7 +55,7 @@
</string-array>
<string-array name="hdcp_checking_summaries">
<item msgid="4045840870658484038">"Nunca utilizar a verificação HDCP"</item>
- <item msgid="8254225038262324761">"Utilizar a verificação HDCP para conteúdo DRM apenas"</item>
+ <item msgid="8254225038262324761">"Usar a verificação HDCP para conteúdo DRM apenas"</item>
<item msgid="6421717003037072581">"Usar sempre a verificação HDCP"</item>
</string-array>
<string-array name="bt_hci_snoop_log_entries">
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtrado ativado"</item>
<item msgid="2779123106632690576">"Ativado"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Deixe apenas cabeçalhos de LCA (Lista de controlo de acesso)"</item>
+ <item msgid="2776218217644557831">"Filtre pacotes de multimédia A2DP"</item>
+ <item msgid="8163235976612675092">"Filtre o canal RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Desativar"</item>
+ <item msgid="2505973306504851132">"Preencha com uma string de carateres"</item>
+ <item msgid="5883011000629613855">"Deixe apenas o cabeçalho"</item>
+ <item msgid="1051534112762023603">"Remova totalmente"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (predefinição)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
@@ -93,7 +97,7 @@
<item msgid="8147982633566548515">"map14"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_titles">
- <item msgid="2494959071796102843">"Utilizar seleção do sistema (predefinido)"</item>
+ <item msgid="2494959071796102843">"Usar seleção do sistema (predefinido)"</item>
<item msgid="4055460186095649420">"SBC"</item>
<item msgid="720249083677397051">"AAC"</item>
<item msgid="1049450003868150455">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
@@ -103,7 +107,7 @@
<item msgid="506175145534048710">"Opus"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_summaries">
- <item msgid="8868109554557331312">"Utilizar seleção do sistema (predefinido)"</item>
+ <item msgid="8868109554557331312">"Usar seleção do sistema (predefinido)"</item>
<item msgid="9024885861221697796">"SBC"</item>
<item msgid="4688890470703790013">"AAC"</item>
<item msgid="8627333814413492563">"Áudio <xliff:g id="QUALCOMM">Qualcomm®</xliff:g> <xliff:g id="APTX">aptX™</xliff:g>"</item>
@@ -113,38 +117,38 @@
<item msgid="7940970833006181407">"Opus"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_titles">
- <item msgid="926809261293414607">"Utilizar seleção do sistema (predefinido)"</item>
+ <item msgid="926809261293414607">"Usar seleção do sistema (predefinido)"</item>
<item msgid="8003118270854840095">"44,1 kHz"</item>
<item msgid="3208896645474529394">"48,0 kHz"</item>
<item msgid="8420261949134022577">"88,2 kHz"</item>
<item msgid="8887519571067543785">"96,0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_sample_rate_summaries">
- <item msgid="2284090879080331090">"Utilizar seleção do sistema (predefinido)"</item>
+ <item msgid="2284090879080331090">"Usar seleção do sistema (predefinido)"</item>
<item msgid="1872276250541651186">"44,1 kHz"</item>
<item msgid="8736780630001704004">"48,0 kHz"</item>
<item msgid="7698585706868856888">"88,2 kHz"</item>
<item msgid="8946330945963372966">"96,0 kHz"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_titles">
- <item msgid="2574107108483219051">"Utilizar seleção do sistema (predefinido)"</item>
+ <item msgid="2574107108483219051">"Usar seleção do sistema (predefinido)"</item>
<item msgid="4671992321419011165">"16 bits/amostra"</item>
<item msgid="1933898806184763940">"24 bits/amostra"</item>
<item msgid="1212577207279552119">"32 bits/amostra"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_bits_per_sample_summaries">
- <item msgid="9196208128729063711">"Utilizar seleção do sistema (predefinido)"</item>
+ <item msgid="9196208128729063711">"Usar seleção do sistema (predefinido)"</item>
<item msgid="1084497364516370912">"16 bits/amostra"</item>
<item msgid="2077889391457961734">"24 bits/amostra"</item>
<item msgid="3836844909491316925">"32 bits/amostra"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_titles">
- <item msgid="3014194562841654656">"Utilizar seleção do sistema (predefinido)"</item>
+ <item msgid="3014194562841654656">"Usar seleção do sistema (predefinido)"</item>
<item msgid="5982952342181788248">"Mono"</item>
<item msgid="927546067692441494">"Estéreo"</item>
</string-array>
<string-array name="bluetooth_a2dp_codec_channel_mode_summaries">
- <item msgid="1997302811102880485">"Utilizar seleção do sistema (predefinido)"</item>
+ <item msgid="1997302811102880485">"Usar seleção do sistema (predefinido)"</item>
<item msgid="8005696114958453588">"Mono"</item>
<item msgid="1333279807604675720">"Estéreo"</item>
</string-array>
diff --git a/packages/SettingsLib/res/values-pt-rPT/strings.xml b/packages/SettingsLib/res/values-pt-rPT/strings.xml
index 499477e..893964b 100644
--- a/packages/SettingsLib/res/values-pt-rPT/strings.xml
+++ b/packages/SettingsLib/res/values-pt-rPT/strings.xml
@@ -127,15 +127,15 @@
<string name="bluetooth_hid_profile_summary_connected" msgid="3923653977051684833">"Ligado a um dispositivo de entrada"</string>
<string name="bluetooth_pan_user_profile_summary_connected" msgid="380469653827505727">"Lig. ao disposit. p/ acesso à Internet"</string>
<string name="bluetooth_pan_nap_profile_summary_connected" msgid="3744773111299503493">"A partilhar lig. à Internet local c/ dispos."</string>
- <string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Utilizar para acesso à Internet"</string>
- <string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Utilizar para o mapa"</string>
- <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Utilizar para acesso ao SIM"</string>
- <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Utilizar para áudio de multimédia"</string>
- <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Utilizar para áudio do telefone"</string>
- <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Utilizar para transferência de ficheiros"</string>
- <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Utilizar para entrada"</string>
- <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Utilizar para aparelhos auditivos"</string>
- <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Utilizar para LE_AUDIO"</string>
+ <string name="bluetooth_pan_profile_summary_use_for" msgid="7422039765025340313">"Usar para acesso à Internet"</string>
+ <string name="bluetooth_map_profile_summary_use_for" msgid="4453622103977592583">"Usar para o mapa"</string>
+ <string name="bluetooth_sap_profile_summary_use_for" msgid="6204902866176714046">"Usar para acesso ao SIM"</string>
+ <string name="bluetooth_a2dp_profile_summary_use_for" msgid="7324694226276491807">"Usar para áudio de multimédia"</string>
+ <string name="bluetooth_headset_profile_summary_use_for" msgid="808970643123744170">"Usar para áudio do telefone"</string>
+ <string name="bluetooth_opp_profile_summary_use_for" msgid="461981154387015457">"Usar para transferência de ficheiros"</string>
+ <string name="bluetooth_hid_profile_summary_use_for" msgid="4289460627406490952">"Usar para entrada"</string>
+ <string name="bluetooth_hearing_aid_profile_summary_use_for" msgid="7689393730163320483">"Usar para aparelhos auditivos"</string>
+ <string name="bluetooth_le_audio_profile_summary_use_for" msgid="2778318636027348572">"Usar para LE_AUDIO"</string>
<string name="bluetooth_pairing_accept" msgid="2054232610815498004">"Sincr."</string>
<string name="bluetooth_pairing_accept_all_caps" msgid="2734383073450506220">"SINCRONIZAR"</string>
<string name="bluetooth_pairing_decline" msgid="6483118841204885890">"Cancelar"</string>
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Apresentar limites de clipes, margens, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forçar direção do esquema RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forçar dir. do esq. do ecrã p. RTL tds os locais"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barra de navegação transparente"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Torne a cor de fundo da barra de navegação transparente por predefinição"</string>
<string name="window_blurs" msgid="6831008984828425106">"Permitir esbater janelas"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forçar 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ativar o 4x MSAA em aplicações OpenGL ES 2.0"</string>
@@ -432,7 +434,7 @@
<string name="select_webview_provider_dialog_title" msgid="2444261109877277714">"Definir implementação WebView"</string>
<string name="select_webview_provider_toast_text" msgid="8512254949169359848">"Esta opção já não é válida. Tente novamente."</string>
<string name="picture_color_mode" msgid="1013807330552931903">"Modo de cor da imagem"</string>
- <string name="picture_color_mode_desc" msgid="151780973768136200">"Utilizar sRGB"</string>
+ <string name="picture_color_mode_desc" msgid="151780973768136200">"Usar sRGB"</string>
<string name="daltonizer_mode_disabled" msgid="403424372812399228">"Desativado"</string>
<string name="daltonizer_mode_monochromacy" msgid="362060873835885014">"Monocromacia"</string>
<string name="daltonizer_mode_deuteranomaly" msgid="3507284319584683963">"Deuteranomalia (vermelho-verde)"</string>
@@ -504,9 +506,9 @@
<string name="retail_demo_reset_next" msgid="3688129033843885362">"Próximo"</string>
<string name="retail_demo_reset_title" msgid="1866911701095959800">"Palavra-passe obrigatória"</string>
<string name="active_input_method_subtypes" msgid="4232680535471633046">"Métodos de introdução activos"</string>
- <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Utilizar idiomas do sistema"</string>
+ <string name="use_system_language_to_select_input_method_subtypes" msgid="4865195835541387040">"Usar idiomas do sistema"</string>
<string name="failed_to_open_app_settings_toast" msgid="764897252657692092">"Falha ao abrir as definições para <xliff:g id="SPELL_APPLICATION_NAME">%1$s</xliff:g>"</string>
- <string name="ime_security_warning" msgid="6547562217880551450">"Este método de introdução pode permitir a recolha de todo o texto que digitar, incluindo dados pessoais como, por exemplo, palavras-passe e números de cartões de crédito. Decorre da aplicação <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Utilizar este método de introdução?"</string>
+ <string name="ime_security_warning" msgid="6547562217880551450">"Este método de introdução pode permitir a recolha de todo o texto que digitar, incluindo dados pessoais como, por exemplo, palavras-passe e números de cartões de crédito. Decorre da aplicação <xliff:g id="IME_APPLICATION_NAME">%1$s</xliff:g>. Usar este método de introdução?"</string>
<string name="direct_boot_unaware_dialog_message" msgid="7845398276735021548">"Nota: após reiniciar, só é possível iniciar esta aplicação quando o telemóvel for desbloqueado."</string>
<string name="ims_reg_title" msgid="8197592958123671062">"Estado do registo IMS"</string>
<string name="ims_reg_status_registered" msgid="884916398194885457">"Registado"</string>
@@ -663,7 +665,7 @@
<string name="physical_keyboard_title" msgid="4811935435315835220">"Teclado físico"</string>
<string name="keyboard_layout_dialog_title" msgid="3927180147005616290">"Escolha um esquema de teclado"</string>
<string name="keyboard_layout_default_label" msgid="1997292217218546957">"Predefinição"</string>
- <string name="turn_screen_on_title" msgid="3266937298097573424">"Ative o ecrã"</string>
+ <string name="turn_screen_on_title" msgid="3266937298097573424">"Ativação do ecrã"</string>
<string name="allow_turn_screen_on" msgid="6194845766392742639">"Permitir a ativação do ecrã"</string>
<string name="allow_turn_screen_on_description" msgid="43834403291575164">"Permita que uma app ative o ecrã. Se a autorização for concedida, a app pode ativar o ecrã em qualquer altura sem a sua intenção explícita."</string>
<string name="bt_le_audio_broadcast_dialog_title" msgid="5392738488989777074">"Interromper a transmissão da app <xliff:g id="APP_NAME">%1$s</xliff:g>?"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Mover para a direita"</item>
<item msgid="324200556467459329">"Mover para cima"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-pt/arrays.xml b/packages/SettingsLib/res/values-pt/arrays.xml
index eff0922..3b61e1a 100644
--- a/packages/SettingsLib/res/values-pt/arrays.xml
+++ b/packages/SettingsLib/res/values-pt/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtro ativado"</item>
<item msgid="2779123106632690576">"Ativado"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Deixar apenas cabeçalhos da Access Control List"</item>
+ <item msgid="2776218217644557831">"Filtrar pacotes de mídia A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrar canal RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Desativar"</item>
+ <item msgid="2505973306504851132">"Preencher com string de caracteres"</item>
+ <item msgid="5883011000629613855">"Deixar apenas o cabeçalho"</item>
+ <item msgid="1051534112762023603">"Remover totalmente"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (padrão)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-pt/strings.xml b/packages/SettingsLib/res/values-pt/strings.xml
index 3a48c3d..44110c2 100644
--- a/packages/SettingsLib/res/values-pt/strings.xml
+++ b/packages/SettingsLib/res/values-pt/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Mostrar limites de corte, margens, etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Forçar layout da direita p/ esquerda"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Forçar a direção do layout da direita para a esquerda para todas as localidades"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Barra de navegação transparente"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Deixar o plano de fundo da barra de navegação transparente por padrão"</string>
<string name="window_blurs" msgid="6831008984828425106">"Permitir desfoques de janela"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forçar 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Ativar 4x MSAA em apps OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Mover para direita"</item>
<item msgid="324200556467459329">"Mover para cima"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ro/arrays.xml b/packages/SettingsLib/res/values-ro/arrays.xml
index 303d669..f713051 100644
--- a/packages/SettingsLib/res/values-ro/arrays.xml
+++ b/packages/SettingsLib/res/values-ro/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Este activat Filtrat"</item>
<item msgid="2779123106632690576">"Activat"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Lasă doar anteturile ACL"</item>
+ <item msgid="2776218217644557831">"Filtrează pachetele media A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrează canalul RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Dezactivează"</item>
+ <item msgid="2505973306504851132">"Umple cu un șir de caractere"</item>
+ <item msgid="5883011000629613855">"Lasă doar antetul"</item>
+ <item msgid="1051534112762023603">"Elimină complet"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (prestabilit)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ro/strings.xml b/packages/SettingsLib/res/values-ro/strings.xml
index e9afb3d..97060f9 100644
--- a/packages/SettingsLib/res/values-ro/strings.xml
+++ b/packages/SettingsLib/res/values-ro/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Afișează limitele clipului, marginile etc."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Direcție aspect dreapta - stânga"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Direcție obligatorie aspect ecran dreapta - stânga"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Bară de navigare transparentă"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Setează culoarea fundalului barei de navigare la transparentă în mod prestabilit"</string>
<string name="window_blurs" msgid="6831008984828425106">"Permite estompări la nivel de fereastră"</string>
<string name="force_msaa" msgid="4081288296137775550">"Forțați MSAA 4x"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Activează MSAA 4x în aplicațiile OpenGL ES 2.0"</string>
@@ -516,7 +518,7 @@
<string name="wifi_tether_connected_summary" msgid="5282919920463340158">"{count,plural, =0{Niciun dispozitiv conectat}=1{Un dispozitiv conectat}few{# dispozitive conectate}other{# de dispozitive conectate}}"</string>
<string name="accessibility_manual_zen_more_time" msgid="5141801092071134235">"Mai mult timp."</string>
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Mai puțin timp."</string>
- <string name="cancel" msgid="5665114069455378395">"Anulați"</string>
+ <string name="cancel" msgid="5665114069455378395">"Anulează"</string>
<string name="okay" msgid="949938843324579502">"OK"</string>
<string name="done" msgid="381184316122520313">"Gata"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Alarme și mementouri"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Deplasează la dreapta"</item>
<item msgid="324200556467459329">"Deplasează în sus"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ru/arrays.xml b/packages/SettingsLib/res/values-ru/arrays.xml
index 4772df98..80ae696 100644
--- a/packages/SettingsLib/res/values-ru/arrays.xml
+++ b/packages/SettingsLib/res/values-ru/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Включены фильтры"</item>
<item msgid="2779123106632690576">"Включено"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Только заголовки списка контроля доступа"</item>
+ <item msgid="2776218217644557831">"Фильтровать A2DP-медиапакеты"</item>
+ <item msgid="8163235976612675092">"Фильтровать RFCOMM-канал"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Отключить"</item>
+ <item msgid="2505973306504851132">"Заполнить строкой символов"</item>
+ <item msgid="5883011000629613855">"Оставить только заголовок"</item>
+ <item msgid="1051534112762023603">"Удалить полностью"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (по умолчанию)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ru/strings.xml b/packages/SettingsLib/res/values-ru/strings.xml
index 16788c3..47bf5a0 100644
--- a/packages/SettingsLib/res/values-ru/strings.xml
+++ b/packages/SettingsLib/res/values-ru/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Показывать границы обрезки, поля и т. п."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Отразить интерфейс"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Принудительно расположить элементы интерфейса справа налево вне зависимости от региональных настроек"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Прозрачная панель навигации"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Сделать цвет фона панели навигации прозрачным по умолчанию"</string>
<string name="window_blurs" msgid="6831008984828425106">"Размытие на уровне окон"</string>
<string name="force_msaa" msgid="4081288296137775550">"Включить 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Включить 4x MSAA в приложениях OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Переместите палец вправо"</item>
<item msgid="324200556467459329">"Переместите палец вверх"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-si/arrays.xml b/packages/SettingsLib/res/values-si/arrays.xml
index 8de6a71..01103f5 100644
--- a/packages/SettingsLib/res/values-si/arrays.xml
+++ b/packages/SettingsLib/res/values-si/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"සබල පෙරහන් කළ"</item>
<item msgid="2779123106632690576">"සබලයි"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL ශීර්ෂයන් පමණක් තබන්න"</item>
+ <item msgid="2776218217644557831">"A2DP මාධ්ය පැකට් පෙරහන් කරන්න"</item>
+ <item msgid="8163235976612675092">"RFCOMM නාලිකාව පෙරහන් කරන්න"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"අබල කරන්න"</item>
+ <item msgid="2505973306504851132">"අනුලකුණු තන්තුවක් සමග පුරවන්න"</item>
+ <item msgid="5883011000629613855">"ශීර්ෂකය පමණක් තබන්න"</item>
+ <item msgid="1051534112762023603">"සම්පූර්ණයෙන්ම ඉවත් කරන්න"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (පෙරනිමි)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-si/strings.xml b/packages/SettingsLib/res/values-si/strings.xml
index 5ba553d..fbefa92 100644
--- a/packages/SettingsLib/res/values-si/strings.xml
+++ b/packages/SettingsLib/res/values-si/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"ක්ලිප් සීමා, මායිම්, ආදිය පෙන්වන්න."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"බල RTL පිරිසැලසුම් දිශාව"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"සියලු පෙදෙසි සඳහා RTL වෙත බල තිර පිරිසැලසුම"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"පාරදෘශ්ය සංචලන තීරුව"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"සංචලන තීරු පසුබිම් වර්ණය පෙරනිමියෙන් පාරදෘශ්ය කරන්න"</string>
<string name="window_blurs" msgid="6831008984828425106">"කවුළු මට්. බොඳ කි. ඉඩ දෙ."</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA බල කරන්න"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 යෙදුම්හි 4x MSAA සබල කරන්න"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"දකුණට ගෙන යන්න"</item>
<item msgid="324200556467459329">"ඉහළට ගෙන යන්න"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sk/arrays.xml b/packages/SettingsLib/res/values-sk/arrays.xml
index f15dfb7..5a6eb99 100644
--- a/packages/SettingsLib/res/values-sk/arrays.xml
+++ b/packages/SettingsLib/res/values-sk/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Aktivované filtrované"</item>
<item msgid="2779123106632690576">"Aktivované"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Ponechať iba hlavičky zoznamu prístupových práv"</item>
+ <item msgid="2776218217644557831">"Filtrovať balíky médií A2DP"</item>
+ <item msgid="8163235976612675092">"Filtrovať kanál RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Vypnúť"</item>
+ <item msgid="2505973306504851132">"Vyplniť reťazcom znakov"</item>
+ <item msgid="5883011000629613855">"Ponechať iba hlavičku"</item>
+ <item msgid="1051534112762023603">"Úplne odstrániť"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (predvolené)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sk/strings.xml b/packages/SettingsLib/res/values-sk/strings.xml
index 89ef946..80374e0 100644
--- a/packages/SettingsLib/res/values-sk/strings.xml
+++ b/packages/SettingsLib/res/values-sk/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Zobraziť vo výstrižku ohraničenie, okraje a pod."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Rozloženie sprava doľava"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Vynútiť pre všetky jazyky rozloženie obrazovky sprava doľava"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Priehľadný navigačný panel"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Nastaviť farbu pozadia navigačné panela predvolene priehľadnú"</string>
<string name="window_blurs" msgid="6831008984828425106">"Povoliť rozmazanie na úrovni okna"</string>
<string name="force_msaa" msgid="4081288296137775550">"Vynútiť 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Povoliť 4x MSAA v aplikáciách OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Posuňte doprava"</item>
<item msgid="324200556467459329">"Presuňte nahor"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sl/arrays.xml b/packages/SettingsLib/res/values-sl/arrays.xml
index 9ef852c..aff47ed 100644
--- a/packages/SettingsLib/res/values-sl/arrays.xml
+++ b/packages/SettingsLib/res/values-sl/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Omogočeno filtrirano"</item>
<item msgid="2779123106632690576">"Omogočeno"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Ohranitev samo glav ACL"</item>
+ <item msgid="2776218217644557831">"Filtriranje predstavnostnih paketov A2DP"</item>
+ <item msgid="8163235976612675092">"Filtriranje kanala RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Onemogoči"</item>
+ <item msgid="2505973306504851132">"Zapolnitev z nizom znakov"</item>
+ <item msgid="5883011000629613855">"Ohranitev samo glave"</item>
+ <item msgid="1051534112762023603">"Popolna odstranitev"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (privzeto)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sl/strings.xml b/packages/SettingsLib/res/values-sl/strings.xml
index dc65447..6640b43 100644
--- a/packages/SettingsLib/res/values-sl/strings.xml
+++ b/packages/SettingsLib/res/values-sl/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Pokaži meje obrezovanja, obrobe ipd."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Vsili od desne proti levi"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Vsili smer postavitve na zaslonu od desne proti levi za vse jezike."</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Prosojna vrstica za krmarjenje"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Privzeta nastavitev prosojne barve ozadja vrstice za krmarjenje"</string>
<string name="window_blurs" msgid="6831008984828425106">"Dovoli zameglitve na ravni okna"</string>
<string name="force_msaa" msgid="4081288296137775550">"Vsili 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"V aplikacijah OpenGL ES 2.0 omogoči 4x MSAA."</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Premaknite se desno"</item>
<item msgid="324200556467459329">"Premaknite se navzgor"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sq/arrays.xml b/packages/SettingsLib/res/values-sq/arrays.xml
index 89a316d..60dba5b 100644
--- a/packages/SettingsLib/res/values-sq/arrays.xml
+++ b/packages/SettingsLib/res/values-sq/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Të aktivizuara të filtruara"</item>
<item msgid="2779123106632690576">"Aktiv"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Mbaj vetëm titujt ACL"</item>
+ <item msgid="2776218217644557831">"Filtro paketat e medias A2DP"</item>
+ <item msgid="8163235976612675092">"Filtro kanalin RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Çaktivizo"</item>
+ <item msgid="2505973306504851132">"Plotëso me varg karakteresh"</item>
+ <item msgid="5883011000629613855">"Mbaj vetëm titullin"</item>
+ <item msgid="1051534112762023603">"Hiqe plotësisht"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (I parazgjedhur)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sq/strings.xml b/packages/SettingsLib/res/values-sq/strings.xml
index e61c34a..5897466 100644
--- a/packages/SettingsLib/res/values-sq/strings.xml
+++ b/packages/SettingsLib/res/values-sq/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Shfaq konturet e klipit, hapësirat etj."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Detyro drejtimin e shkrimit nga e djathta në të majtë"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Ndrysho me detyrim drejtimin e planit të ekranit nga e djathta në të majtë për të gjitha vendet"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Shiriti transparent i navigimit"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Bëje, si parazgjedhje, transparente ngjyrën e sfondit të shiritit të navigimit"</string>
<string name="window_blurs" msgid="6831008984828425106">"Lejo turbullimet në nivel dritareje"</string>
<string name="force_msaa" msgid="4081288296137775550">"Detyro 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Aktivizo 4x MSAA në aplikacionet OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Lëvize djathtas"</item>
<item msgid="324200556467459329">"Lëvize lart"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sr/arrays.xml b/packages/SettingsLib/res/values-sr/arrays.xml
index e76820e..d74f55b 100644
--- a/packages/SettingsLib/res/values-sr/arrays.xml
+++ b/packages/SettingsLib/res/values-sr/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Омогућено филтрирано"</item>
<item msgid="2779123106632690576">"Омогућено"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Задржите само ACL заглавља"</item>
+ <item msgid="2776218217644557831">"Филтрирајте A2DP медијске пакете"</item>
+ <item msgid="8163235976612675092">"Филтрирајте RFCOMM канал"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Онемогућите"</item>
+ <item msgid="2505973306504851132">"Испуните стрингом знакова"</item>
+ <item msgid="5883011000629613855">"Задржите само заглавље"</item>
+ <item msgid="1051534112762023603">"Уклоните у потпуности"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (подразумевано)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sr/strings.xml b/packages/SettingsLib/res/values-sr/strings.xml
index cfac256..32affcc 100644
--- a/packages/SettingsLib/res/values-sr/strings.xml
+++ b/packages/SettingsLib/res/values-sr/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Приказује границе клипа, маргине итд."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Наметни смер распореда здесна налево"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Намеће смер распореда екрана здесна налево за све локалитете"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Прозирна трака за навигацију"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Нека боја позадине траке за навигацију буде подразумевано прозирна"</string>
<string name="window_blurs" msgid="6831008984828425106">"Дозволи замагљења прозора"</string>
<string name="force_msaa" msgid="4081288296137775550">"Наметни 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Омогућава 4x MSAA у OpenGL ES 2.0 апликацијама"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Померите надесно"</item>
<item msgid="324200556467459329">"Померите нагоре"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sv/arrays.xml b/packages/SettingsLib/res/values-sv/arrays.xml
index 391f603..5ff90cb 100644
--- a/packages/SettingsLib/res/values-sv/arrays.xml
+++ b/packages/SettingsLib/res/values-sv/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtrering har aktiverats"</item>
<item msgid="2779123106632690576">"Aktiverad"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Lämna bara ACL-rubriker"</item>
+ <item msgid="2776218217644557831">"Filtrera A2DP-mediepaket"</item>
+ <item msgid="8163235976612675092">"Filtrera RFCOMM-kanal"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Inaktivera"</item>
+ <item msgid="2505973306504851132">"Fyll med en sträng med tecken"</item>
+ <item msgid="5883011000629613855">"Lämna bara rubriken"</item>
+ <item msgid="1051534112762023603">"Ta bort fullständigt"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (standard)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sv/strings.xml b/packages/SettingsLib/res/values-sv/strings.xml
index 99b8c4f..f60fc83 100644
--- a/packages/SettingsLib/res/values-sv/strings.xml
+++ b/packages/SettingsLib/res/values-sv/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Visa gränser för videoklipp, marginaler m.m."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Tvinga fram RTL-layout"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Tvinga fram RTL-skärmlayout (hö–vä) för alla språk"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Genomskinligt navigeringsfält"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Gör bakgrundsfärgen genomskinlig för navigeringsfältet som standard"</string>
<string name="window_blurs" msgid="6831008984828425106">"Tillåt oskärpa på fönsternivå"</string>
<string name="force_msaa" msgid="4081288296137775550">"Tvinga 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Aktivera 4x MSAA i OpenGL ES 2.0-appar"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Flytta åt höger"</item>
<item msgid="324200556467459329">"Flytta uppåt"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-sw/arrays.xml b/packages/SettingsLib/res/values-sw/arrays.xml
index 1a33b6e4..30cc69f 100644
--- a/packages/SettingsLib/res/values-sw/arrays.xml
+++ b/packages/SettingsLib/res/values-sw/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Vichujio Vilivyowekwa"</item>
<item msgid="2779123106632690576">"Imewashwa"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Acha vijajuu vya ACL pekee"</item>
+ <item msgid="2776218217644557831">"Chuja kifurushi cha maudhui cha A2DP"</item>
+ <item msgid="8163235976612675092">"Chuja kituo cha RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Zima"</item>
+ <item msgid="2505973306504851132">"Jaza ukitumia mfuatano wa herufi"</item>
+ <item msgid="5883011000629613855">"Acha kijajuu pekee"</item>
+ <item msgid="1051534112762023603">"Ondoa kabisa"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Chaguomsingi)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-sw/strings.xml b/packages/SettingsLib/res/values-sw/strings.xml
index ce3068f..b6a3a62 100644
--- a/packages/SettingsLib/res/values-sw/strings.xml
+++ b/packages/SettingsLib/res/values-sw/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Onyesha mipaka ya picha, kingo, nk."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Lazimisha uelekezaji wa muundo wa RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Lazimisha mkao wa skrini uwe wa kulia kwenda kushoto kwa lugha zote"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Sehemu angavu ya viungo muhimu"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Fanya rangi ya mandharinyuma ya sehemu ya viungo muhimu iwe angavu kwa chaguomsingi"</string>
<string name="window_blurs" msgid="6831008984828425106">"Ruhusu ukungu wa kiwango cha dirisha"</string>
<string name="force_msaa" msgid="4081288296137775550">"Lazimisha 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Wezesha 4x MSAA katika programu za OpenGL ES 2.0"</string>
@@ -518,7 +520,7 @@
<string name="accessibility_manual_zen_less_time" msgid="6828877595848229965">"Muda kidogo."</string>
<string name="cancel" msgid="5665114069455378395">"Ghairi"</string>
<string name="okay" msgid="949938843324579502">"Sawa"</string>
- <string name="done" msgid="381184316122520313">"Imemaliza"</string>
+ <string name="done" msgid="381184316122520313">"Nimemaliza"</string>
<string name="alarms_and_reminders_label" msgid="6918395649731424294">"Ving\'ora na vikumbusho"</string>
<string name="alarms_and_reminders_switch_title" msgid="4939393911531826222">"Ruhusu iweke kengele na vikumbusho"</string>
<string name="alarms_and_reminders_title" msgid="8819933264635406032">"Kengele na vikumbusho"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Sogeza kulia"</item>
<item msgid="324200556467459329">"Sogeza juu"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"Asilimia <xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ta/arrays.xml b/packages/SettingsLib/res/values-ta/arrays.xml
index 23eb242..5774bf9 100644
--- a/packages/SettingsLib/res/values-ta/arrays.xml
+++ b/packages/SettingsLib/res/values-ta/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"இயக்கப்பட்டு வடிகட்டப்பட்டது"</item>
<item msgid="2779123106632690576">"இயக்கப்பட்டது"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACL தலைப்புகளை மட்டும் விட்டுவிடுதல்"</item>
+ <item msgid="2776218217644557831">"A2DP மீடியா பேக்கெட்டுகளை வடிகட்டுதல்"</item>
+ <item msgid="8163235976612675092">"RFCOMM சேனலை வடிகட்டுதல்"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"முடக்குதல்"</item>
+ <item msgid="2505973306504851132">"எழுத்துகளைக் கொண்ட வார்த்தையால் நிரப்புதல்"</item>
+ <item msgid="5883011000629613855">"தலைப்பை மட்டும் விட்டுவிடுதல்"</item>
+ <item msgid="1051534112762023603">"முழுமையாக அகற்றுதல்"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (இயல்பு)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ta/strings.xml b/packages/SettingsLib/res/values-ta/strings.xml
index ea12899..402aeb2 100644
--- a/packages/SettingsLib/res/values-ta/strings.xml
+++ b/packages/SettingsLib/res/values-ta/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"கிளிப் எல்லைகள், ஓரங்கள், மேலும் பலவற்றைக் காட்டு"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL தளவமைப்பின் திசையை வலியுறுத்து"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"எல்லா மொழிகளுக்கும் திரையின் தளவமைப்பு திசையை RTL க்கு மாற்றும்"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"தெளிவுத்திறனுடன் இருக்கும் வழிசெலுத்தல் பட்டி"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"வழிசெலுத்தல் பட்டியின் பின்னணி வண்ணத்தை இயல்பாகவே தெளிவுத்திறன் உடையதாக அமைக்கவும்"</string>
<string name="window_blurs" msgid="6831008984828425106">"திரை-நிலை மங்கலை அனுமதி"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA ஐ வலியுறுத்து"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 பயன்பாடுகளில் 4x MSAA ஐ இயக்கு"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"வலதுபுறம் நகர்த்துங்கள்"</item>
<item msgid="324200556467459329">"மேலே நகர்த்துங்கள்"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-te/arrays.xml b/packages/SettingsLib/res/values-te/arrays.xml
index 0f62c1d..db2307d 100644
--- a/packages/SettingsLib/res/values-te/arrays.xml
+++ b/packages/SettingsLib/res/values-te/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"ప్రారంభించబడింది ఫిల్టర్ చేయబడింది"</item>
<item msgid="2779123106632690576">"ప్రారంభించబడింది"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ACLహెడర్లను మాత్రమే వదిలివేయండి"</item>
+ <item msgid="2776218217644557831">"A2DP మీడియా ప్యాకెట్లను ఫిల్టర్ చేయండి"</item>
+ <item msgid="8163235976612675092">"RFCOMM ఛానెల్ని ఫిల్టర్ చేయండి"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"డిజేబుల్ చేయండి"</item>
+ <item msgid="2505973306504851132">"అక్షరాల వాక్యంతో పూరించండి"</item>
+ <item msgid="5883011000629613855">"హెడర్ మాత్రమే ఉంచండి"</item>
+ <item msgid="1051534112762023603">"పూర్తిగా తీసివేయండి"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.4 (ఆటోమేటిక్ సెట్టింగ్)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-te/strings.xml b/packages/SettingsLib/res/values-te/strings.xml
index ed91fea..0512a0d 100644
--- a/packages/SettingsLib/res/values-te/strings.xml
+++ b/packages/SettingsLib/res/values-te/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"క్లిప్ సరిహద్దులు, అంచులు మొ. చూపు"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL లేఅవుట్ దిశను నిర్బంధం చేయండి"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"అన్ని లొకేల్ల కోసం RTLకి స్క్రీన్ లేఅవుట్ దిశను నిర్భందించు"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"పారదర్శక నావిగేషన్ బార్"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"నావిగేషన్ బార్ బ్యాక్గ్రౌండ్ రంగును ఆటోమేటిక్గా పారదర్శకంగా చేయండి"</string>
<string name="window_blurs" msgid="6831008984828425106">"విండో-స్థాయి బ్లర్ అనుమతించండి"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA అమలు తప్పనిసరి"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 యాప్లలో 4x MSAAను ప్రారంభించండి"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"కుడి వైపుగా జరపండి"</item>
<item msgid="324200556467459329">"పైకి జరపండి"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-th/arrays.xml b/packages/SettingsLib/res/values-th/arrays.xml
index 8d98cdb..21eba14 100644
--- a/packages/SettingsLib/res/values-th/arrays.xml
+++ b/packages/SettingsLib/res/values-th/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"เปิดใช้รายการที่กรอง"</item>
<item msgid="2779123106632690576">"เปิดใช้"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"ออกจากส่วนหัว ACL เท่านั้น"</item>
+ <item msgid="2776218217644557831">"กรองแพ็กเก็ตสื่อ A2DP"</item>
+ <item msgid="8163235976612675092">"กรองแชแนล RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"ปิดใช้"</item>
+ <item msgid="2505973306504851132">"กรอกสตริงอักขระ"</item>
+ <item msgid="5883011000629613855">"ออกจากส่วนหัวเท่านั้น"</item>
+ <item msgid="1051534112762023603">"นำออกอย่างสมบูรณ์"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ค่าเริ่มต้น)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-th/strings.xml b/packages/SettingsLib/res/values-th/strings.xml
index a1dec58..89b8ce2 100644
--- a/packages/SettingsLib/res/values-th/strings.xml
+++ b/packages/SettingsLib/res/values-th/strings.xml
@@ -289,7 +289,7 @@
<string name="bluetooth_select_a2dp_codec_bits_per_sample_dialog_title" msgid="4898693684282596143">"ทริกเกอร์การเลือกตัวแปลงรหัส\nเสียงบลูทูธ: บิตต่อตัวอย่าง"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode" msgid="364277285688014427">"โหมดช่องสัญญาณเสียงบลูทูธ"</string>
<string name="bluetooth_select_a2dp_codec_channel_mode_dialog_title" msgid="2076949781460359589">"ทริกเกอร์การเลือกตัวแปลงรหัส\nเสียงบลูทูธ: โหมดช่องสัญญาณ"</string>
- <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ตัวแปลงรหัสเสียงบลูทูธที่ใช้ LDAC: คุณภาพการเล่น"</string>
+ <string name="bluetooth_select_a2dp_codec_ldac_playback_quality" msgid="3233402355917446304">"ตัวแปลงสัญญาณเสียงบลูทูธที่ใช้ LDAC: คุณภาพการเล่น"</string>
<string name="bluetooth_select_a2dp_codec_ldac_playback_quality_dialog_title" msgid="7274396574659784285">"ทริกเกอร์การเลือกตัวแปลงรหัส LDAC\nเสียงบลูทูธ: คุณภาพการเล่น"</string>
<string name="bluetooth_select_a2dp_codec_streaming_label" msgid="2040810756832027227">"สตรีมมิง: <xliff:g id="STREAMING_PARAMETER">%1$s</xliff:g>"</string>
<string name="select_private_dns_configuration_title" msgid="7887550926056143018">"DNS ส่วนตัว"</string>
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"แสดงหน้าปกคลิป ขอบ ฯลฯ"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"บังคับทิศทางการจัดวางขวาไปซ้าย"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"บังคับทิศทางการจัดวางหน้าจอเป็นขวาไปซ้ายสำหรับทุกภาษา"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"ทำให้แถบนำทางโปร่งใส"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"ทำให้สีพื้นหลังของแถบนำทางโปร่งใสโดยค่าเริ่มต้น"</string>
<string name="window_blurs" msgid="6831008984828425106">"อนุญาตการเบลอระดับหน้าต่าง"</string>
<string name="force_msaa" msgid="4081288296137775550">"บังคับใช้ 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"เปิดใช้งาน 4x MSAA ในแอปพลิเคชัน OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"ย้ายไปทางขวา"</item>
<item msgid="324200556467459329">"ย้ายขึ้น"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-tl/arrays.xml b/packages/SettingsLib/res/values-tl/arrays.xml
index ed47d32..9af30d6 100644
--- a/packages/SettingsLib/res/values-tl/arrays.xml
+++ b/packages/SettingsLib/res/values-tl/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Na-enable Na-filter"</item>
<item msgid="2779123106632690576">"Naka-enable"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Mga ACL header lang ang iwanan"</item>
+ <item msgid="2776218217644557831">"I-filter ang mga A2DP na media packet"</item>
+ <item msgid="8163235976612675092">"I-filter ang RFCOMM channel"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"I-disable"</item>
+ <item msgid="2505973306504851132">"Punan ng string ng mga character"</item>
+ <item msgid="5883011000629613855">"Header lang ang iwanan"</item>
+ <item msgid="1051534112762023603">"Ganap na alisin"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Default)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-tl/strings.xml b/packages/SettingsLib/res/values-tl/strings.xml
index 7847da6..dbd3a8b 100644
--- a/packages/SettingsLib/res/values-tl/strings.xml
+++ b/packages/SettingsLib/res/values-tl/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Ipakita ang mga hangganan ng clip, margin, atbp."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Ipilit ang RTL na dir. ng layout"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Ipilit ang RTL na direksyon ng screen layout sa lahat ng lokal"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Transparent na navigation bar"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Gawing transparent ang kulay ng background ng navigation bar bilang default"</string>
<string name="window_blurs" msgid="6831008984828425106">"Payagan ang pag-blur sa antas ng window"</string>
<string name="force_msaa" msgid="4081288296137775550">"Puwersahin ang 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Paganahin ang 4x MSAA sa OpenGL ES 2.0 na apps"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Ilipat pakanan"</item>
<item msgid="324200556467459329">"Ilipat pataas"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-tr/arrays.xml b/packages/SettingsLib/res/values-tr/arrays.xml
index 45580f5..6d8821e 100644
--- a/packages/SettingsLib/res/values-tr/arrays.xml
+++ b/packages/SettingsLib/res/values-tr/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Etkin Filtrelenmiş"</item>
<item msgid="2779123106632690576">"Etkin"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Yalnızca EKL başlıklarını bırak"</item>
+ <item msgid="2776218217644557831">"A2DP medya paketlerini filtrele"</item>
+ <item msgid="8163235976612675092">"RFCOMM kanalını filtrele"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Devre dışı bırak"</item>
+ <item msgid="2505973306504851132">"Karakterlerden oluşan bir dizeyle doldur"</item>
+ <item msgid="5883011000629613855">"Yalnızca başlığı bırak"</item>
+ <item msgid="1051534112762023603">"Tamamen kaldır"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Varsayılan)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-tr/strings.xml b/packages/SettingsLib/res/values-tr/strings.xml
index 1f56170..628bd93 100644
--- a/packages/SettingsLib/res/values-tr/strings.xml
+++ b/packages/SettingsLib/res/values-tr/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Klip sınırlarını, kenar boşluklarını vb. göster"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Sağdan sola düzenini zorla"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Tüm yerel ayarlar için sağdan sola ekran düzenini zorla"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Şeffaf gezinme çubuğu"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Gezinme çubuğu arka plan rengini varsayılan olarak şeffaf yap"</string>
<string name="window_blurs" msgid="6831008984828425106">"Pencere bulanıklaştırmaya izin ver"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA\'yı zorla"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 uygulamalarda 4x MSAA\'yı etkinleştir"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Sağa taşı"</item>
<item msgid="324200556467459329">"Yukarı taşı"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"%%<xliff:g id="PERCENTAGE">%1$d</xliff:g>"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-uk/arrays.xml b/packages/SettingsLib/res/values-uk/arrays.xml
index f97452c..b606d07 100644
--- a/packages/SettingsLib/res/values-uk/arrays.xml
+++ b/packages/SettingsLib/res/values-uk/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Увімкнено з фільтром"</item>
<item msgid="2779123106632690576">"Увімкнено"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Залишити тільки заголовки ACL"</item>
+ <item msgid="2776218217644557831">"Фільтрувати за пакетами медіаданих A2DP"</item>
+ <item msgid="8163235976612675092">"Фільтрувати за каналом RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Вимкнути"</item>
+ <item msgid="2505973306504851132">"Заповнити рядком символів"</item>
+ <item msgid="5883011000629613855">"Залишити тільки заголовок"</item>
+ <item msgid="1051534112762023603">"Повністю вилучити"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (за умовчанням)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-uk/strings.xml b/packages/SettingsLib/res/values-uk/strings.xml
index 92c0e11..15c24e8 100644
--- a/packages/SettingsLib/res/values-uk/strings.xml
+++ b/packages/SettingsLib/res/values-uk/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Показувати межі роликів, поля тощо"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Макет письма справа наліво"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Застосовувати макет письма справа наліво для всіх мов"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Прозора панель навігації"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Зробити колір фону панелі навігації прозорим за умовчанням"</string>
<string name="window_blurs" msgid="6831008984828425106">"Дозволити розмиття вікон"</string>
<string name="force_msaa" msgid="4081288296137775550">"Примус. запустити 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Увімкнути 4x MSAA в програмах OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Перемістіть палець праворуч"</item>
<item msgid="324200556467459329">"Перемістіть палець угору"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-ur/arrays.xml b/packages/SettingsLib/res/values-ur/arrays.xml
index 74af322..6d4062d 100644
--- a/packages/SettingsLib/res/values-ur/arrays.xml
+++ b/packages/SettingsLib/res/values-ur/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"فعال کردہ فلٹر کردہ"</item>
<item msgid="2779123106632690576">"فعال"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"صرف ACL ہیڈر چھوڑ دیں"</item>
+ <item msgid="2776218217644557831">"A2DP میڈیا پیکٹ کو فلٹر کریں"</item>
+ <item msgid="8163235976612675092">"RFCOMM چینل کو فلٹر کریں"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"غیر فعال کریں"</item>
+ <item msgid="2505973306504851132">"حروف کی سٹرنگز کے ساتھ پُر کریں"</item>
+ <item msgid="5883011000629613855">"صرف ہیڈر چھوڑیں"</item>
+ <item msgid="1051534112762023603">"مکمل طور پر ہٹائیں"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (ڈیفالٹ)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-ur/strings.xml b/packages/SettingsLib/res/values-ur/strings.xml
index 94bb557..e3b95ae 100644
--- a/packages/SettingsLib/res/values-ur/strings.xml
+++ b/packages/SettingsLib/res/values-ur/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"کلپ باؤنڈز، حاشیے وغیرہ دکھائیں"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"RTL لے آؤٹ سمت زبردستی نافذ کریں"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"سبھی زبانوں کیلئے اسکرین لے آؤٹ کی سمت کو RTL پر مجبور کریں"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"شفاف نیویگیشن بار"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"نیویگیشن بار کے پس منظر کے رنگ کو بطور ڈیفالٹ شفاف بنائیں"</string>
<string name="window_blurs" msgid="6831008984828425106">"ونڈو کی سطح پر دھندلاپن کی اجازت دیں"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA زبردستی نافذ کریں"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ایپس میں 4x MSAA فعال کریں"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"بائيں منتقل کریں"</item>
<item msgid="324200556467459329">"اوپر منتقل کریں"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-uz/arrays.xml b/packages/SettingsLib/res/values-uz/arrays.xml
index 3e53ae6..4b08f47 100644
--- a/packages/SettingsLib/res/values-uz/arrays.xml
+++ b/packages/SettingsLib/res/values-uz/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Filtrlar yoniq"</item>
<item msgid="2779123106632690576">"Yoniq"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Faqat ACL sarlavhalari qolsin"</item>
+ <item msgid="2776218217644557831">"A2DP media paketlarni filtrlash"</item>
+ <item msgid="8163235976612675092">"RFCOMM kanalini filtrlash"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Faolsizlantirish"</item>
+ <item msgid="2505973306504851132">"Qatorni harflar bilan toʻldiring"</item>
+ <item msgid="5883011000629613855">"Faqat sarlavha qolsin"</item>
+ <item msgid="1051534112762023603">"Butunlay olib tashlash"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (asosiy)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-uz/strings.xml b/packages/SettingsLib/res/values-uz/strings.xml
index 48705dd..503a3e0 100644
--- a/packages/SettingsLib/res/values-uz/strings.xml
+++ b/packages/SettingsLib/res/values-uz/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Klip, maydon va h.k. chegaralarini ko‘rsatish"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"O‘ngdan chapga qarab yozish"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Barcha tillarda o‘ngdan chapga qarab yozish"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Shaffof navigatsiya paneli"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Navigatsiya paneli fon rangini standart holatda shaffof qilish"</string>
<string name="window_blurs" msgid="6831008984828425106">"Oyna xiralashga ruxsat"</string>
<string name="force_msaa" msgid="4081288296137775550">"4x MSAA sozlamasini yoqish"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"OpenGL ES 2.0 ilovasidan 4x MSAAni yoqish"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Oʻngga siljitish"</item>
<item msgid="324200556467459329">"Tepaga siljitish"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-vi/arrays.xml b/packages/SettingsLib/res/values-vi/arrays.xml
index 649cb5c..08f4550 100644
--- a/packages/SettingsLib/res/values-vi/arrays.xml
+++ b/packages/SettingsLib/res/values-vi/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Đã bật và lọc"</item>
<item msgid="2779123106632690576">"Đã bật"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Chỉ để lại tiêu đề ACL"</item>
+ <item msgid="2776218217644557831">"Lọc các gói nội dung nghe nhìn A2DP"</item>
+ <item msgid="8163235976612675092">"Lọc kênh RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Tắt"</item>
+ <item msgid="2505973306504851132">"Điền bằng chuỗi ký tự"</item>
+ <item msgid="5883011000629613855">"Chỉ để lại tiêu đề"</item>
+ <item msgid="1051534112762023603">"Xoá toàn bộ"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (Mặc định)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-vi/strings.xml b/packages/SettingsLib/res/values-vi/strings.xml
index 1b7d651..847cfaa 100644
--- a/packages/SettingsLib/res/values-vi/strings.xml
+++ b/packages/SettingsLib/res/values-vi/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Hiện viền của đoạn video, lề, v.v.."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Buộc hướng bố cục phải sang trái"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Buộc hướng bố cục màn hình phải sang trái cho tất cả ngôn ngữ"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Thanh điều hướng trong suốt"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Thiết lập màu nền của thanh điều hướng thành trong suốt theo mặc định"</string>
<string name="window_blurs" msgid="6831008984828425106">"Cho phép làm mờ cửa sổ"</string>
<string name="force_msaa" msgid="4081288296137775550">"Bắt buộc 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Bật 4x MSAA trong ứng dụng OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Di chuyển sang phải"</item>
<item msgid="324200556467459329">"Di chuyển lên"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rCN/arrays.xml b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
index 13941af..1eb597a 100644
--- a/packages/SettingsLib/res/values-zh-rCN/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"已启用“已过滤”"</item>
<item msgid="2779123106632690576">"已启用"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"只留下 ACL 标头"</item>
+ <item msgid="2776218217644557831">"过滤 A2DP 媒体数据包"</item>
+ <item msgid="8163235976612675092">"过滤 RFCOMM 通道"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"停用"</item>
+ <item msgid="2505973306504851132">"使用字符串填充"</item>
+ <item msgid="5883011000629613855">"只留下标头"</item>
+ <item msgid="1051534112762023603">"完全移除"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5(默认)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-zh-rCN/strings.xml b/packages/SettingsLib/res/values-zh-rCN/strings.xml
index 1716124..a2aca7a 100644
--- a/packages/SettingsLib/res/values-zh-rCN/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rCN/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"显示剪辑边界、边距等。"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"强制使用从右到左的布局方向"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"强制将所有语言区域的屏幕布局方向改为从右到左"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"透明导航栏"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"默认将导航栏背景颜色设为透明"</string>
<string name="window_blurs" msgid="6831008984828425106">"允许窗口级模糊处理"</string>
<string name="force_msaa" msgid="4081288296137775550">"强制启用 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"在 OpenGL ES 2.0 应用中启用 4x MSAA"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"右移"</item>
<item msgid="324200556467459329">"上移"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g>%%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rHK/arrays.xml b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
index 9b359ed..e14f719 100644
--- a/packages/SettingsLib/res/values-zh-rHK/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"已啟用篩選"</item>
<item msgid="2779123106632690576">"已啟用"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"只保留 ACL 標題"</item>
+ <item msgid="2776218217644557831">"篩選 A2DP 媒體封包"</item>
+ <item msgid="8163235976612675092">"篩選 RFCOMM 渠道"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"停用"</item>
+ <item msgid="2505973306504851132">"填入字元字串"</item>
+ <item msgid="5883011000629613855">"只保留標題"</item>
+ <item msgid="1051534112762023603">"完全移除"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (預設)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-zh-rHK/strings.xml b/packages/SettingsLib/res/values-zh-rHK/strings.xml
index 56f17fa..f49932d 100644
--- a/packages/SettingsLib/res/values-zh-rHK/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rHK/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"顯示剪輯範圍、邊界等"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"強制使用從右至左的版面配置方向"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"強制將所有語言代碼的畫面配置方向改為從右至左"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"透明導覽列"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"使用透明色作為導覽列的預設背景顏色"</string>
<string name="window_blurs" msgid="6831008984828425106">"允許視窗層級模糊處理"</string>
<string name="force_msaa" msgid="4081288296137775550">"強制 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"在 OpenGL ES 2.0 應用程式中啟用 4x MSAA"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"向右移"</item>
<item msgid="324200556467459329">"向上移"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zh-rTW/arrays.xml b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
index 00362d8..16890be 100644
--- a/packages/SettingsLib/res/values-zh-rTW/arrays.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"已啟用篩選結果"</item>
<item msgid="2779123106632690576">"已啟用"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"僅保留 ACL 標頭"</item>
+ <item msgid="2776218217644557831">"篩選 A2DP 媒體封包"</item>
+ <item msgid="8163235976612675092">"篩選 RFCOMM 管道"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"停用"</item>
+ <item msgid="2505973306504851132">"填入字元字串"</item>
+ <item msgid="5883011000629613855">"僅保留標頭"</item>
+ <item msgid="1051534112762023603">"完全移除"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"AVRCP 1.5 (預設)"</item>
<item msgid="1637054408779685086">"AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-zh-rTW/strings.xml b/packages/SettingsLib/res/values-zh-rTW/strings.xml
index 588c4f4..c381ebd 100644
--- a/packages/SettingsLib/res/values-zh-rTW/strings.xml
+++ b/packages/SettingsLib/res/values-zh-rTW/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"顯示剪輯範圍、邊界等"</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"強制使用從右至左版面配置方向"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"強制將所有語言代碼的畫面配置方向改為從右至左"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"透明導覽列"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"使用透明色做為導覽列的預設背景顏色"</string>
<string name="window_blurs" msgid="6831008984828425106">"允許視窗層級模糊處理"</string>
<string name="force_msaa" msgid="4081288296137775550">"強制 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"在 OpenGL ES 2.0 應用程式中啟用 4x MSAA"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"向右移"</item>
<item msgid="324200556467459329">"向上移"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/res/values-zu/arrays.xml b/packages/SettingsLib/res/values-zu/arrays.xml
index ac3cb02..d20c7db 100644
--- a/packages/SettingsLib/res/values-zu/arrays.xml
+++ b/packages/SettingsLib/res/values-zu/arrays.xml
@@ -63,13 +63,17 @@
<item msgid="6336372935919715515">"Okuhlungiwe okunikwe amandla"</item>
<item msgid="2779123106632690576">"Kunikwe amandla"</item>
</string-array>
- <!-- no translation found for bt_hci_snoop_log_filters_entries:0 (195768089203590086) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:1 (2776218217644557831) -->
- <!-- no translation found for bt_hci_snoop_log_filters_entries:2 (8163235976612675092) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:0 (3961868665260627524) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:1 (2505973306504851132) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:2 (5883011000629613855) -->
- <!-- no translation found for bt_hci_snoop_log_profile_filter_entries:3 (1051534112762023603) -->
+ <string-array name="bt_hci_snoop_log_filters_entries">
+ <item msgid="195768089203590086">"Shiya kuphela onhlokweni be-ACL"</item>
+ <item msgid="2776218217644557831">"Hlunga amaphakethe wemidiya ye-A2DP"</item>
+ <item msgid="8163235976612675092">"Isiteshi se-RFCOMM"</item>
+ </string-array>
+ <string-array name="bt_hci_snoop_log_profile_filter_entries">
+ <item msgid="3961868665260627524">"Khubaza"</item>
+ <item msgid="2505973306504851132">"Gcwalisa ngeyunithi yezinhlamvu"</item>
+ <item msgid="5883011000629613855">"Shiya unhlokweni kuphela"</item>
+ <item msgid="1051534112762023603">"Susa ngokugcwele"</item>
+ </string-array>
<string-array name="bluetooth_avrcp_versions">
<item msgid="6603880723315236832">"I-AVRCP 1.5 (Okuzenzakalelayo)"</item>
<item msgid="1637054408779685086">"I-AVRCP 1.3"</item>
diff --git a/packages/SettingsLib/res/values-zu/strings.xml b/packages/SettingsLib/res/values-zu/strings.xml
index 6c35510..f80515a 100644
--- a/packages/SettingsLib/res/values-zu/strings.xml
+++ b/packages/SettingsLib/res/values-zu/strings.xml
@@ -371,6 +371,8 @@
<string name="debug_layout_summary" msgid="8825829038287321978">"Bonisa imikhawulo, imiphetho, njll, yesiqeshana."</string>
<string name="force_rtl_layout_all_locales" msgid="8690762598501599796">"Phoqelela isikhombisi-ndlela sesakhiwo se-RTL"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="6663016859517239880">"Phoqelela isikhombisi-ndlela sesikrini ku-RTL kuzo zonke izifunda"</string>
+ <string name="transparent_navigation_bar" msgid="1933192171384678484">"Ibha yokuzula ebonisa ngale"</string>
+ <string name="transparent_navigation_bar_summary" msgid="5454359021817330722">"Yenza umbala wangemuva webha yokufuna ubonise ngale ngokuzenzakalelayo"</string>
<string name="window_blurs" msgid="6831008984828425106">"Vumela ukufiphala kweleveli yewindi"</string>
<string name="force_msaa" msgid="4081288296137775550">"Phoqelela i-4x MSAA"</string>
<string name="force_msaa_summary" msgid="9070437493586769500">"Nika amandla i-4x MSAA ezinhlelweni zokusebenza ze-OpenGL ES 2.0"</string>
@@ -679,4 +681,5 @@
<item msgid="7728484337962740316">"Yisa kwesokudla"</item>
<item msgid="324200556467459329">"Khuphula"</item>
</string-array>
+ <string name="font_scale_percentage" msgid="2624057443622817886">"<xliff:g id="PERCENTAGE">%1$d</xliff:g> %%"</string>
</resources>
diff --git a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
index c61ebc0..0630a2e 100644
--- a/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
+++ b/packages/SettingsLib/src/com/android/settingslib/bluetooth/LocalBluetoothLeBroadcastMetadata.java
@@ -261,19 +261,21 @@
Pattern pattern = Pattern.compile(PATTERN_BT_BROADCAST_METADATA);
Matcher match = pattern.matcher(qrCodeString);
if (match.find()) {
- mSourceAddressType = Integer.parseInt(match.group(MATCH_INDEX_ADDRESS_TYPE));
- mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
+ try {
+ mSourceAddressType = Integer.parseInt(match.group(MATCH_INDEX_ADDRESS_TYPE));
+ mSourceDevice = BluetoothAdapter.getDefaultAdapter().getRemoteDevice(
match.group(MATCH_INDEX_DEVICE));
- mSourceAdvertisingSid = Integer.parseInt(match.group(MATCH_INDEX_ADVERTISING_SID));
- mBroadcastId = Integer.parseInt(match.group(MATCH_INDEX_BROADCAST_ID));
- mPaSyncInterval = Integer.parseInt(match.group(MATCH_INDEX_SYNC_INTERVAL));
- mIsEncrypted = Boolean.valueOf(match.group(MATCH_INDEX_IS_ENCRYPTED));
- mBroadcastCode = match.group(MATCH_INDEX_BROADCAST_CODE).getBytes();
- mPresentationDelayMicros =
- Integer.parseInt(match.group(MATCH_INDEX_PRESENTATION_DELAY));
+ mSourceAdvertisingSid = Integer.parseInt(
+ match.group(MATCH_INDEX_ADVERTISING_SID));
+ mBroadcastId = Integer.parseInt(match.group(MATCH_INDEX_BROADCAST_ID));
+ mPaSyncInterval = Integer.parseInt(match.group(MATCH_INDEX_SYNC_INTERVAL));
+ mIsEncrypted = Boolean.valueOf(match.group(MATCH_INDEX_IS_ENCRYPTED));
+ mBroadcastCode = match.group(MATCH_INDEX_BROADCAST_CODE).getBytes();
+ mPresentationDelayMicros =
+ Integer.parseInt(match.group(MATCH_INDEX_PRESENTATION_DELAY));
- if (DEBUG) {
- Log.d(TAG, "Converted qrCodeString result: "
+ if (DEBUG) {
+ Log.d(TAG, "Converted qrCodeString result: "
+ " ,Type = " + mSourceAddressType
+ " ,Device = " + mSourceDevice
+ " ,AdSid = " + mSourceAdvertisingSid
@@ -282,11 +284,11 @@
+ " ,encrypted = " + mIsEncrypted
+ " ,BroadcastCode = " + Arrays.toString(mBroadcastCode)
+ " ,delay = " + mPresentationDelayMicros);
- }
+ }
- mSubgroup = convertToSubgroup(match.group(MATCH_INDEX_SUBGROUPS));
+ mSubgroup = convertToSubgroup(match.group(MATCH_INDEX_SUBGROUPS));
- return new BluetoothLeBroadcastMetadata.Builder()
+ return new BluetoothLeBroadcastMetadata.Builder()
.setSourceDevice(mSourceDevice, mSourceAddressType)
.setSourceAdvertisingSid(mSourceAdvertisingSid)
.setBroadcastId(mBroadcastId)
@@ -296,10 +298,13 @@
.setPresentationDelayMicros(mPresentationDelayMicros)
.addSubgroup(mSubgroup)
.build();
+ } catch (IllegalArgumentException e) {
+ Log.d(TAG, "IllegalArgumentException when convert : " + e);
+ return null;
+ }
} else {
if (DEBUG) {
- Log.d(TAG,
- "The match fail, can not convert it to BluetoothLeBroadcastMetadata.");
+ Log.d(TAG, "The match fail, can not convert it to BluetoothLeBroadcastMetadata.");
}
return null;
}
diff --git a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
index 0fa15eb..fdefcde 100644
--- a/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
+++ b/packages/SettingsLib/tests/integ/src/com/android/settingslib/devicestate/DeviceStateRotationLockSettingsManagerTest.java
@@ -70,12 +70,20 @@
when(mMockContext.getApplicationContext()).thenReturn(mMockContext);
when(mMockContext.getResources()).thenReturn(mMockResources);
when(mMockContext.getContentResolver()).thenReturn(context.getContentResolver());
+ when(mMockResources.getStringArray(R.array.config_perDeviceStateRotationLockDefaults))
+ .thenReturn(new String[]{"0:1", "1:0:2", "2:2"});
+ when(mMockResources.getIntArray(R.array.config_foldedDeviceStates))
+ .thenReturn(new int[]{0});
+ when(mMockResources.getIntArray(R.array.config_halfFoldedDeviceStates))
+ .thenReturn(new int[]{1});
+ when(mMockResources.getIntArray(R.array.config_openDeviceStates))
+ .thenReturn(new int[]{2});
mFakeSecureSettings.registerContentObserver(
Settings.Secure.DEVICE_STATE_ROTATION_LOCK,
/* notifyForDescendents= */ false, //NOTYPO
mContentObserver,
UserHandle.USER_CURRENT);
- mManager = new DeviceStateRotationLockSettingsManager(context, mFakeSecureSettings);
+ mManager = new DeviceStateRotationLockSettingsManager(mMockContext, mFakeSecureSettings);
}
@Test
@@ -109,7 +117,7 @@
public void getSettableDeviceStates_returnsExpectedValuesInOriginalOrder() {
when(mMockResources.getStringArray(
R.array.config_perDeviceStateRotationLockDefaults)).thenReturn(
- new String[]{"2:2", "4:0", "1:1", "0:0"});
+ new String[]{"2:1", "1:0:1", "0:2"});
List<SettableDeviceState> settableDeviceStates =
DeviceStateRotationLockSettingsManager.getInstance(
@@ -117,9 +125,8 @@
assertThat(settableDeviceStates).containsExactly(
new SettableDeviceState(/* deviceState= */ 2, /* isSettable= */ true),
- new SettableDeviceState(/* deviceState= */ 4, /* isSettable= */ false),
- new SettableDeviceState(/* deviceState= */ 1, /* isSettable= */ true),
- new SettableDeviceState(/* deviceState= */ 0, /* isSettable= */ false)
+ new SettableDeviceState(/* deviceState= */ 1, /* isSettable= */ false),
+ new SettableDeviceState(/* deviceState= */ 0, /* isSettable= */ true)
).inOrder();
}
diff --git a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
index f6a216e..0aa3860 100644
--- a/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
+++ b/packages/SettingsProvider/src/android/provider/settings/validators/SystemSettingsValidators.java
@@ -52,6 +52,7 @@
|| (val == BatteryManager.BATTERY_PLUGGED_AC)
|| (val == BatteryManager.BATTERY_PLUGGED_USB)
|| (val == BatteryManager.BATTERY_PLUGGED_WIRELESS)
+ || (val == BatteryManager.BATTERY_PLUGGED_DOCK)
|| (val
== (BatteryManager.BATTERY_PLUGGED_AC
| BatteryManager.BATTERY_PLUGGED_USB))
@@ -64,7 +65,13 @@
|| (val
== (BatteryManager.BATTERY_PLUGGED_AC
| BatteryManager.BATTERY_PLUGGED_USB
- | BatteryManager.BATTERY_PLUGGED_WIRELESS));
+ | BatteryManager.BATTERY_PLUGGED_WIRELESS))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_AC
+ | BatteryManager.BATTERY_PLUGGED_DOCK))
+ || (val
+ == (BatteryManager.BATTERY_PLUGGED_USB
+ | BatteryManager.BATTERY_PLUGGED_DOCK));
} catch (NumberFormatException e) {
return false;
}
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java b/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java
index a4c59ea..80030f7 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/GenerationRegistry.java
@@ -31,7 +31,7 @@
/**
* This class tracks changes for config/global/secure/system tables
- * on a per user basis and updates shared memory regions which
+ * on a per-user basis and updates shared memory regions which
* client processes can read to determine if their local caches are
* stale.
*/
@@ -50,10 +50,6 @@
@GuardedBy("mLock")
private final ArrayMap<Integer, ArrayMap<String, Integer>> mKeyToIndexMapMap = new ArrayMap<>();
- @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
- // Maximum number of backing stores allowed
- static final int NUM_MAX_BACKING_STORE = 8;
-
@GuardedBy("mLock")
private int mNumBackingStore = 0;
@@ -65,8 +61,24 @@
// The generation number is only increased when a new non-predefined setting is inserted
private static final String DEFAULT_MAP_KEY_FOR_UNSET_SETTINGS = "";
- public GenerationRegistry(Object lock) {
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ // Minimum number of backing stores; supports 3 users
+ static final int MIN_NUM_BACKING_STORE = 8;
+ // Maximum number of backing stores; supports 18 users
+ static final int MAX_NUM_BACKING_STORE = 38;
+
+ private final int mMaxNumBackingStore;
+
+ GenerationRegistry(Object lock, int maxNumUsers) {
mLock = lock;
+ // Add some buffer to maxNumUsers to accommodate corner cases when the actual number of
+ // users in the system exceeds the limit
+ maxNumUsers = maxNumUsers + 2;
+ // Number of backing stores needed for N users is (N + N + 1 + 1) = N * 2 + 2
+ // N Secure backing stores and N System backing stores, 1 Config and 1 Global for all users
+ // However, we always make sure that at least 3 users and at most 18 users are supported.
+ mMaxNumBackingStore = Math.min(Math.max(maxNumUsers * 2 + 2, MIN_NUM_BACKING_STORE),
+ MAX_NUM_BACKING_STORE);
}
/**
@@ -195,8 +207,10 @@
}
if (backingStore == null) {
try {
- if (mNumBackingStore >= NUM_MAX_BACKING_STORE) {
- Slog.e(LOG_TAG, "Error creating backing store - at capacity");
+ if (mNumBackingStore >= mMaxNumBackingStore) {
+ if (DEBUG) {
+ Slog.e(LOG_TAG, "Error creating backing store - at capacity");
+ }
return null;
}
backingStore = new MemoryIntArray(MAX_BACKING_STORE_SIZE);
@@ -256,7 +270,9 @@
+ " on user:" + SettingsState.getUserIdFromKey(key));
}
} else {
- Slog.e(LOG_TAG, "Could not allocate generation index");
+ if (DEBUG) {
+ Slog.e(LOG_TAG, "Could not allocate generation index");
+ }
}
}
return index;
@@ -271,4 +287,9 @@
}
return -1;
}
+
+ @VisibleForTesting(visibility = VisibleForTesting.Visibility.PRIVATE)
+ int getMaxNumBackingStores() {
+ return mMaxNumBackingStore;
+ }
}
\ No newline at end of file
diff --git a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
index 7607909..721b3c4 100644
--- a/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
+++ b/packages/SettingsProvider/src/com/android/providers/settings/SettingsProvider.java
@@ -19,9 +19,9 @@
import static android.os.Process.ROOT_UID;
import static android.os.Process.SHELL_UID;
import static android.os.Process.SYSTEM_UID;
-import static android.provider.Settings.Config.SYNC_DISABLED_MODE_NONE;
-import static android.provider.Settings.Config.SYNC_DISABLED_MODE_PERSISTENT;
-import static android.provider.Settings.Config.SYNC_DISABLED_MODE_UNTIL_REBOOT;
+import static android.provider.DeviceConfig.SYNC_DISABLED_MODE_NONE;
+import static android.provider.DeviceConfig.SYNC_DISABLED_MODE_PERSISTENT;
+import static android.provider.DeviceConfig.SYNC_DISABLED_MODE_UNTIL_REBOOT;
import static android.provider.Settings.SET_ALL_RESULT_DISABLED;
import static android.provider.Settings.SET_ALL_RESULT_FAILURE;
import static android.provider.Settings.SET_ALL_RESULT_SUCCESS;
@@ -2831,7 +2831,7 @@
public SettingsRegistry() {
mHandler = new MyHandler(getContext().getMainLooper());
- mGenerationRegistry = new GenerationRegistry(mLock);
+ mGenerationRegistry = new GenerationRegistry(mLock, UserManager.getMaxSupportedUsers());
mBackupManager = new BackupManager(getContext());
}
diff --git a/packages/SettingsProvider/test/AndroidTest.xml b/packages/SettingsProvider/test/AndroidTest.xml
index 9d23526..0bf53cc 100644
--- a/packages/SettingsProvider/test/AndroidTest.xml
+++ b/packages/SettingsProvider/test/AndroidTest.xml
@@ -14,6 +14,12 @@
limitations under the License.
-->
<configuration description="Run Settings Provider Tests.">
+ <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" />
+ <option name="force-skip-system-props" value="true" />
+ </target_preparer>
+
<target_preparer class="com.android.tradefed.targetprep.TestAppInstallSetup">
<option name="test-file-name" value="SettingsProviderTest.apk" />
</target_preparer>
diff --git a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
index 07b71d3..aebdf4f 100644
--- a/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
+++ b/packages/SettingsProvider/test/src/android/provider/SettingsBackupTest.java
@@ -266,7 +266,6 @@
Settings.Global.ENABLE_DELETION_HELPER_NO_THRESHOLD_TOGGLE,
Settings.Global.ENABLE_DISKSTATS_LOGGING,
Settings.Global.ENABLE_EPHEMERAL_FEATURE,
- Settings.Global.ENABLE_RESTRICTED_BUCKET,
Settings.Global.ENABLE_TARE,
Settings.Global.DYNAMIC_POWER_SAVINGS_ENABLED,
Settings.Global.DYNAMIC_POWER_SAVINGS_DISABLE_THRESHOLD,
diff --git a/packages/SettingsProvider/test/src/com/android/providers/settings/GenerationRegistryTest.java b/packages/SettingsProvider/test/src/com/android/providers/settings/GenerationRegistryTest.java
index 6ec8146..12865f4 100644
--- a/packages/SettingsProvider/test/src/com/android/providers/settings/GenerationRegistryTest.java
+++ b/packages/SettingsProvider/test/src/com/android/providers/settings/GenerationRegistryTest.java
@@ -36,7 +36,7 @@
public class GenerationRegistryTest {
@Test
public void testGenerationsWithRegularSetting() throws IOException {
- final GenerationRegistry generationRegistry = new GenerationRegistry(new Object());
+ final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 2);
final int secureKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE, 0);
final String testSecureSetting = "test_secure_setting";
Bundle b = new Bundle();
@@ -93,7 +93,7 @@
@Test
public void testGenerationsWithConfigSetting() throws IOException {
- final GenerationRegistry generationRegistry = new GenerationRegistry(new Object());
+ final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 1);
final String prefix = "test_namespace/";
final int configKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_CONFIG, 0);
@@ -110,10 +110,10 @@
@Test
public void testMaxNumBackingStores() throws IOException {
- final GenerationRegistry generationRegistry = new GenerationRegistry(new Object());
+ final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 2);
final String testSecureSetting = "test_secure_setting";
Bundle b = new Bundle();
- for (int i = 0; i < GenerationRegistry.NUM_MAX_BACKING_STORE; i++) {
+ for (int i = 0; i < generationRegistry.getMaxNumBackingStores(); i++) {
b.clear();
final int key = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE, i);
generationRegistry.addGenerationData(b, key, testSecureSetting);
@@ -121,7 +121,7 @@
}
b.clear();
final int key = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE,
- GenerationRegistry.NUM_MAX_BACKING_STORE + 1);
+ generationRegistry.getMaxNumBackingStores() + 1);
generationRegistry.addGenerationData(b, key, testSecureSetting);
// Should fail to add generation because the number of backing stores has reached limit
checkBundle(b, -1, -1, true);
@@ -133,7 +133,7 @@
@Test
public void testMaxSizeBackingStore() throws IOException {
- final GenerationRegistry generationRegistry = new GenerationRegistry(new Object());
+ final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 1);
final int secureKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE, 0);
final String testSecureSetting = "test_secure_setting";
Bundle b = new Bundle();
@@ -153,7 +153,7 @@
@Test
public void testUnsetSettings() throws IOException {
- final GenerationRegistry generationRegistry = new GenerationRegistry(new Object());
+ final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 1);
final int secureKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_SECURE, 0);
final String testSecureSetting = "test_secure_setting";
Bundle b = new Bundle();
@@ -170,6 +170,35 @@
checkBundle(b, 1, 2, false);
}
+ @Test
+ public void testGlobalSettings() throws IOException {
+ final GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 2);
+ final int globalKey = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_GLOBAL, 0);
+ final String testGlobalSetting = "test_global_setting";
+ final Bundle b = new Bundle();
+ generationRegistry.addGenerationData(b, globalKey, testGlobalSetting);
+ checkBundle(b, 0, 1, false);
+ final MemoryIntArray array = getArray(b);
+ final int globalKey2 = SettingsState.makeKey(SettingsState.SETTINGS_TYPE_GLOBAL, 10);
+ b.clear();
+ generationRegistry.addGenerationData(b, globalKey2, testGlobalSetting);
+ checkBundle(b, 0, 1, false);
+ final MemoryIntArray array2 = getArray(b);
+ // Check that user10 and user0 use the same array to store global settings' generations
+ assertThat(array).isEqualTo(array2);
+ }
+
+ @Test
+ public void testNumberOfBackingStores() {
+ GenerationRegistry generationRegistry = new GenerationRegistry(new Object(), 0);
+ // Test that the capacity of the backing stores is always valid
+ assertThat(generationRegistry.getMaxNumBackingStores()).isEqualTo(
+ GenerationRegistry.MIN_NUM_BACKING_STORE);
+ generationRegistry = new GenerationRegistry(new Object(), 100);
+ // Test that the capacity of the backing stores is always valid
+ assertThat(generationRegistry.getMaxNumBackingStores()).isEqualTo(
+ GenerationRegistry.MAX_NUM_BACKING_STORE);
+ }
private void checkBundle(Bundle b, int expectedIndex, int expectedGeneration, boolean isNull)
throws IOException {
diff --git a/packages/Shell/AndroidManifest.xml b/packages/Shell/AndroidManifest.xml
index 4c48f0e..5e160cd 100644
--- a/packages/Shell/AndroidManifest.xml
+++ b/packages/Shell/AndroidManifest.xml
@@ -830,6 +830,9 @@
<uses-permission android:name="android.permission.LOG_FOREGROUND_RESOURCE_USE"/>
+ <!-- Permission required for CTS test - CtsPackageInstallTestCases -->
+ <uses-permission android:name="android.permission.READ_INSTALLED_SESSION_PATHS" />
+
<application android:label="@string/app_label"
android:theme="@android:style/Theme.DeviceDefault.DayNight"
android:defaultToDeviceProtectedStorage="true"
diff --git a/packages/SystemUI/Android.bp b/packages/SystemUI/Android.bp
index b236ac5..941697b 100644
--- a/packages/SystemUI/Android.bp
+++ b/packages/SystemUI/Android.bp
@@ -368,6 +368,7 @@
plugins: ["dagger2-compiler"],
lint: {
test: true,
+ extra_check_modules: ["SystemUILintChecker"],
},
}
@@ -375,7 +376,7 @@
name: "SystemUIRobo-stub",
defaults: [
"platform_app_defaults",
- "SystemUI_app_defaults",
+ "SystemUI_optimized_defaults",
"SystemUI_compose_defaults",
],
manifest: "tests/AndroidManifest-base.xml",
@@ -442,7 +443,7 @@
}
systemui_optimized_java_defaults {
- name: "SystemUI_app_defaults",
+ name: "SystemUI_optimized_defaults",
soong_config_variables: {
SYSTEMUI_OPTIMIZE_JAVA: {
optimize: {
@@ -451,12 +452,10 @@
shrink: true,
shrink_resources: true,
proguard_compatibility: false,
- proguard_flags_files: ["proguard.flags"],
},
conditions_default: {
optimize: {
proguard_compatibility: false,
- proguard_flags_files: ["proguard.flags"],
},
},
},
@@ -467,7 +466,7 @@
name: "SystemUI",
defaults: [
"platform_app_defaults",
- "SystemUI_app_defaults",
+ "SystemUI_optimized_defaults",
],
static_libs: [
"SystemUI-core",
@@ -482,6 +481,9 @@
kotlincflags: ["-Xjvm-default=enable"],
dxflags: ["--multi-dex"],
+ optimize: {
+ proguard_flags_files: ["proguard.flags"],
+ },
required: [
"privapp_whitelist_com.android.systemui",
"wmshell.protolog.json.gz",
diff --git a/packages/SystemUI/AndroidManifest.xml b/packages/SystemUI/AndroidManifest.xml
index 1136c11..650d5fa 100644
--- a/packages/SystemUI/AndroidManifest.xml
+++ b/packages/SystemUI/AndroidManifest.xml
@@ -27,6 +27,7 @@
<!-- Used to read wallpaper -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
+ <uses-permission android:name="android.permission.READ_WALLPAPER_INTERNAL" />
<!-- Used to read storage for all users -->
<uses-permission android:name="android.permission.WRITE_MEDIA_STORAGE" />
@@ -924,7 +925,7 @@
android:showForAllUsers="true"
android:finishOnTaskLaunch="true"
android:launchMode="singleInstance"
- android:configChanges="screenSize|smallestScreenSize|screenLayout|keyboard|keyboardHidden"
+ android:configChanges="screenLayout|keyboard|keyboardHidden|orientation"
android:visibleToInstantApps="true">
</activity>
@@ -946,7 +947,7 @@
android:showWhenLocked="true"
android:showForAllUsers="true"
android:finishOnTaskLaunch="true"
- android:lockTaskMode="if_whitelisted"
+ android:lockTaskMode="always"
android:configChanges="screenSize|smallestScreenSize|screenLayout|orientation|keyboard|keyboardHidden"
android:visibleToInstantApps="true">
</activity>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml b/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
index 440c6e5..ca84265 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/AndroidManifest.xml
@@ -58,8 +58,5 @@
<intent>
<action android:name="android.intent.action.VOICE_COMMAND" />
</intent>
- <!--intent>
- <action android:name="android.settings.ACCESSIBILITY_SETTINGS" />
- </intent-->
</queries>
</manifest>
\ No newline at end of file
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/values/strings.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/values/strings.xml
index 0747ef0..81fa8e6 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/values/strings.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/values/strings.xml
@@ -49,7 +49,6 @@
<!-- Short summary of app that appears as subtext on the service preference in Settings -->
<string name="accessibility_menu_summary">Control device via large menu</string>
- <!-- TODO(b/113371047): string need to be reviewed -->
<!-- String defining the settings name -->
<string name="accessibility_menu_settings_name">Accessibility Menu Settings</string>
@@ -57,8 +56,6 @@
<string name="accessibility_menu_large_buttons_title">Large buttons</string>
<!-- String defining the summary of Large button setting -->
<string name="accessibility_menu_large_buttons_summary">Increase size of Accessibility Menu Buttons</string>
- <!-- String defining the title of the preference to show help and feedback menu [CHAR LIMIT=40] -->
- <string name="pref_help_and_feedback_title">Help & feedback</string>
<!-- String defining the title of the preference to show help menu [CHAR LIMIT=40] -->
<string name="pref_help_title">Help</string>
@@ -67,7 +64,4 @@
<!-- The percentage of the music volume, and double "%" is required to represent the symbol "%" -->
<string name="music_volume_percentage_label">Music volume <xliff:g id="percentage">%1$s</xliff:g> %%</string>
- <!-- The label of a settings item that displays legal information about the licenses used in this app. [CHAR LIMIT=NONE] -->
- <string name="pref_item_licenses">Open Source Licenses</string>
-
</resources>
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_preferences.xml b/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_preferences.xml
index 3b79287..e42c3cd 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_preferences.xml
+++ b/packages/SystemUI/accessibility/accessibilitymenu/res/xml/accessibilitymenu_preferences.xml
@@ -28,6 +28,6 @@
<Preference
android:key="@string/pref_help"
- android:title="@string/pref_help_and_feedback_title"/>
+ android:title="@string/pref_help_title"/>
</androidx.preference.PreferenceScreen>
\ No newline at end of file
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
index 8f29348..4b6f9a4 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/src/com/android/systemui/accessibility/accessibilitymenu/activity/A11yMenuSettingsActivity.java
@@ -71,8 +71,6 @@
private void initializeHelpAndFeedbackPreference() {
final Preference prefHelp = findPreference(getString(R.string.pref_help));
if (prefHelp != null) {
- prefHelp.setTitle(R.string.pref_help_title);
-
// Do not allow access to web during setup.
if (Settings.Secure.getInt(
getContext().getContentResolver(),
diff --git a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
index 0e89dcd..7277392 100644
--- a/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
+++ b/packages/SystemUI/accessibility/accessibilitymenu/tests/src/com/android/systemui/accessibility/accessibilitymenu/tests/AccessibilityMenuServiceTest.java
@@ -29,6 +29,8 @@
import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.INTENT_TOGGLE_MENU;
import static com.android.systemui.accessibility.accessibilitymenu.AccessibilityMenuService.PACKAGE_NAME;
+import static com.google.common.truth.Truth.assertThat;
+
import android.accessibilityservice.AccessibilityServiceInfo;
import android.app.Instrumentation;
import android.app.UiAutomation;
@@ -39,6 +41,7 @@
import android.hardware.display.BrightnessInfo;
import android.hardware.display.DisplayManager;
import android.media.AudioManager;
+import android.os.PowerManager;
import android.provider.Settings;
import android.util.Log;
import android.view.accessibility.AccessibilityManager;
@@ -375,4 +378,26 @@
() -> sLastGlobalAction.compareAndSet(
GLOBAL_ACTION_TAKE_SCREENSHOT, NO_GLOBAL_ACTION));
}
+
+ @Test
+ public void testOnScreenLock_closesMenu() throws Throwable {
+ openMenu();
+ Context context = sInstrumentation.getTargetContext();
+ PowerManager powerManager = context.getSystemService(PowerManager.class);
+
+ assertThat(powerManager).isNotNull();
+ assertThat(powerManager.isInteractive()).isTrue();
+
+ sUiAutomation.performGlobalAction(GLOBAL_ACTION_LOCK_SCREEN);
+ TestUtils.waitUntil("Screen did not become locked",
+ TIMEOUT_UI_CHANGE_S,
+ () -> !powerManager.isInteractive());
+
+ sUiAutomation.executeShellCommand("input keyevent KEYCODE_WAKEUP");
+ TestUtils.waitUntil("Screen did not wake up",
+ TIMEOUT_UI_CHANGE_S,
+ () -> powerManager.isInteractive());
+
+ assertThat(isMenuVisible()).isFalse();
+ }
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
index 280e7ed9..23fcb69 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/shaderutil/ShaderUtilLibrary.kt
@@ -15,163 +15,166 @@
*/
package com.android.systemui.surfaceeffects.shaderutil
-/** A common utility functions that are used for computing shaders. */
-class ShaderUtilLibrary {
+/** Common utility functions that are used for computing shaders. */
+object ShaderUtilLibrary {
// language=AGSL
- companion object {
- const val SHADER_LIB =
- """
- float triangleNoise(vec2 n) {
- n = fract(n * vec2(5.3987, 5.4421));
- n += dot(n.yx, n.xy + vec2(21.5351, 14.3137));
- float xy = n.x * n.y;
- // compute in [0..2[ and remap to [-1.0..1.0[
- return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;
+ const val SHADER_LIB =
+ """
+ float triangleNoise(vec2 n) {
+ n = fract(n * vec2(5.3987, 5.4421));
+ n += dot(n.yx, n.xy + vec2(21.5351, 14.3137));
+ float xy = n.x * n.y;
+ // compute in [0..2[ and remap to [-1.0..1.0[
+ return fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0;
+ }
+
+ const float PI = 3.1415926535897932384626;
+
+ float sparkles(vec2 uv, float t) {
+ float n = triangleNoise(uv);
+ float s = 0.0;
+ for (float i = 0; i < 4; i += 1) {
+ float l = i * 0.01;
+ float h = l + 0.1;
+ float o = smoothstep(n - l, h, n);
+ o *= abs(sin(PI * o * (t + 0.55 * i)));
+ s += o;
}
+ return s;
+ }
- const float PI = 3.1415926535897932384626;
+ vec2 distort(vec2 p, float time, float distort_amount_radial,
+ float distort_amount_xy) {
+ float angle = atan(p.y, p.x);
+ return p + vec2(sin(angle * 8 + time * 0.003 + 1.641),
+ cos(angle * 5 + 2.14 + time * 0.00412)) * distort_amount_radial
+ + vec2(sin(p.x * 0.01 + time * 0.00215 + 0.8123),
+ cos(p.y * 0.01 + time * 0.005931)) * distort_amount_xy;
+ }
- float sparkles(vec2 uv, float t) {
- float n = triangleNoise(uv);
- float s = 0.0;
- for (float i = 0; i < 4; i += 1) {
- float l = i * 0.01;
- float h = l + 0.1;
- float o = smoothstep(n - l, h, n);
- o *= abs(sin(PI * o * (t + 0.55 * i)));
- s += o;
- }
- return s;
- }
+ // Perceived luminosity (L′), not absolute luminosity.
+ half getLuminosity(vec3 c) {
+ return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
+ }
- vec2 distort(vec2 p, float time, float distort_amount_radial,
- float distort_amount_xy) {
- float angle = atan(p.y, p.x);
- return p + vec2(sin(angle * 8 + time * 0.003 + 1.641),
- cos(angle * 5 + 2.14 + time * 0.00412)) * distort_amount_radial
- + vec2(sin(p.x * 0.01 + time * 0.00215 + 0.8123),
- cos(p.y * 0.01 + time * 0.005931)) * distort_amount_xy;
- }
+ // Creates a luminosity mask and clamp to the legal range.
+ vec3 maskLuminosity(vec3 dest, float lum) {
+ dest.rgb *= vec3(lum);
+ // Clip back into the legal range
+ dest = clamp(dest, vec3(0.), vec3(1.0));
+ return dest;
+ }
- // Perceived luminosity (L′), not absolute luminosity.
- half getLuminosity(vec3 c) {
- return 0.3 * c.r + 0.59 * c.g + 0.11 * c.b;
- }
+ // Return range [-1, 1].
+ vec3 hash(vec3 p) {
+ p = fract(p * vec3(.3456, .1234, .9876));
+ p += dot(p, p.yxz + 43.21);
+ p = (p.xxy + p.yxx) * p.zyx;
+ return (fract(sin(p) * 4567.1234567) - .5) * 2.;
+ }
- // Creates a luminosity mask and clamp to the legal range.
- vec3 maskLuminosity(vec3 dest, float lum) {
- dest.rgb *= vec3(lum);
- // Clip back into the legal range
- dest = clamp(dest, vec3(0.), vec3(1.0));
- return dest;
- }
+ // Skew factors (non-uniform).
+ const half SKEW = 0.3333333; // 1/3
+ const half UNSKEW = 0.1666667; // 1/6
- // Return range [-1, 1].
- vec3 hash(vec3 p) {
- p = fract(p * vec3(.3456, .1234, .9876));
- p += dot(p, p.yxz + 43.21);
- p = (p.xxy + p.yxx) * p.zyx;
- return (fract(sin(p) * 4567.1234567) - .5) * 2.;
- }
+ // Return range roughly [-1,1].
+ // It's because the hash function (that returns a random gradient vector) returns
+ // different magnitude of vectors. Noise doesn't have to be in the precise range thus
+ // skipped normalize.
+ half simplex3d(vec3 p) {
+ // Skew the input coordinate, so that we get squashed cubical grid
+ vec3 s = floor(p + (p.x + p.y + p.z) * SKEW);
- // Skew factors (non-uniform).
- const half SKEW = 0.3333333; // 1/3
- const half UNSKEW = 0.1666667; // 1/6
+ // Unskew back
+ vec3 u = s - (s.x + s.y + s.z) * UNSKEW;
- // Return range roughly [-1,1].
- // It's because the hash function (that returns a random gradient vector) returns
- // different magnitude of vectors. Noise doesn't have to be in the precise range thus
- // skipped normalize.
- half simplex3d(vec3 p) {
- // Skew the input coordinate, so that we get squashed cubical grid
- vec3 s = floor(p + (p.x + p.y + p.z) * SKEW);
+ // Unskewed coordinate that is relative to p, to compute the noise contribution
+ // based on the distance.
+ vec3 c0 = p - u;
- // Unskew back
- vec3 u = s - (s.x + s.y + s.z) * UNSKEW;
+ // We have six simplices (in this case tetrahedron, since we are in 3D) that we
+ // could possibly in.
+ // Here, we are finding the correct tetrahedron (simplex shape), and traverse its
+ // four vertices (c0..3) when computing noise contribution.
+ // The way we find them is by comparing c0's x,y,z values.
+ // For example in 2D, we can find the triangle (simplex shape in 2D) that we are in
+ // by comparing x and y values. i.e. x>y lower, x<y, upper triangle.
+ // Same applies in 3D.
+ //
+ // Below indicates the offsets (or offset directions) when c0=(x0,y0,z0)
+ // x0>y0>z0: (1,0,0), (1,1,0), (1,1,1)
+ // x0>z0>y0: (1,0,0), (1,0,1), (1,1,1)
+ // z0>x0>y0: (0,0,1), (1,0,1), (1,1,1)
+ // z0>y0>x0: (0,0,1), (0,1,1), (1,1,1)
+ // y0>z0>x0: (0,1,0), (0,1,1), (1,1,1)
+ // y0>x0>z0: (0,1,0), (1,1,0), (1,1,1)
+ //
+ // The rule is:
+ // * For offset1, set 1 at the max component, otherwise 0.
+ // * For offset2, set 0 at the min component, otherwise 1.
+ // * For offset3, set 1 for all.
+ //
+ // Encode x0-y0, y0-z0, z0-x0 in a vec3
+ vec3 en = c0 - c0.yzx;
+ // Each represents whether x0>y0, y0>z0, z0>x0
+ en = step(vec3(0.), en);
+ // en.zxy encodes z0>x0, x0>y0, y0>x0
+ vec3 offset1 = en * (1. - en.zxy); // find max
+ vec3 offset2 = 1. - en.zxy * (1. - en); // 1-(find min)
+ vec3 offset3 = vec3(1.);
- // Unskewed coordinate that is relative to p, to compute the noise contribution
- // based on the distance.
- vec3 c0 = p - u;
+ vec3 c1 = c0 - offset1 + UNSKEW;
+ vec3 c2 = c0 - offset2 + UNSKEW * 2.;
+ vec3 c3 = c0 - offset3 + UNSKEW * 3.;
- // We have six simplices (in this case tetrahedron, since we are in 3D) that we
- // could possibly in.
- // Here, we are finding the correct tetrahedron (simplex shape), and traverse its
- // four vertices (c0..3) when computing noise contribution.
- // The way we find them is by comparing c0's x,y,z values.
- // For example in 2D, we can find the triangle (simplex shape in 2D) that we are in
- // by comparing x and y values. i.e. x>y lower, x<y, upper triangle.
- // Same applies in 3D.
- //
- // Below indicates the offsets (or offset directions) when c0=(x0,y0,z0)
- // x0>y0>z0: (1,0,0), (1,1,0), (1,1,1)
- // x0>z0>y0: (1,0,0), (1,0,1), (1,1,1)
- // z0>x0>y0: (0,0,1), (1,0,1), (1,1,1)
- // z0>y0>x0: (0,0,1), (0,1,1), (1,1,1)
- // y0>z0>x0: (0,1,0), (0,1,1), (1,1,1)
- // y0>x0>z0: (0,1,0), (1,1,0), (1,1,1)
- //
- // The rule is:
- // * For offset1, set 1 at the max component, otherwise 0.
- // * For offset2, set 0 at the min component, otherwise 1.
- // * For offset3, set 1 for all.
- //
- // Encode x0-y0, y0-z0, z0-x0 in a vec3
- vec3 en = c0 - c0.yzx;
- // Each represents whether x0>y0, y0>z0, z0>x0
- en = step(vec3(0.), en);
- // en.zxy encodes z0>x0, x0>y0, y0>x0
- vec3 offset1 = en * (1. - en.zxy); // find max
- vec3 offset2 = 1. - en.zxy * (1. - en); // 1-(find min)
- vec3 offset3 = vec3(1.);
+ // Kernel summation: dot(max(0, r^2-d^2))^4, noise contribution)
+ //
+ // First compute d^2, squared distance to the point.
+ vec4 w; // w = max(0, r^2 - d^2))
+ w.x = dot(c0, c0);
+ w.y = dot(c1, c1);
+ w.z = dot(c2, c2);
+ w.w = dot(c3, c3);
- vec3 c1 = c0 - offset1 + UNSKEW;
- vec3 c2 = c0 - offset2 + UNSKEW * 2.;
- vec3 c3 = c0 - offset3 + UNSKEW * 3.;
+ // Noise contribution should decay to zero before they cross the simplex boundary.
+ // Usually r^2 is 0.5 or 0.6;
+ // 0.5 ensures continuity but 0.6 increases the visual quality for the application
+ // where discontinuity isn't noticeable.
+ w = max(0.6 - w, 0.);
- // Kernel summation: dot(max(0, r^2-d^2))^4, noise contribution)
- //
- // First compute d^2, squared distance to the point.
- vec4 w; // w = max(0, r^2 - d^2))
- w.x = dot(c0, c0);
- w.y = dot(c1, c1);
- w.z = dot(c2, c2);
- w.w = dot(c3, c3);
+ // Noise contribution from each point.
+ vec4 nc;
+ nc.x = dot(hash(s), c0);
+ nc.y = dot(hash(s + offset1), c1);
+ nc.z = dot(hash(s + offset2), c2);
+ nc.w = dot(hash(s + offset3), c3);
- // Noise contribution should decay to zero before they cross the simplex boundary.
- // Usually r^2 is 0.5 or 0.6;
- // 0.5 ensures continuity but 0.6 increases the visual quality for the application
- // where discontinuity isn't noticeable.
- w = max(0.6 - w, 0.);
+ nc *= w*w*w*w;
- // Noise contribution from each point.
- vec4 nc;
- nc.x = dot(hash(s), c0);
- nc.y = dot(hash(s + offset1), c1);
- nc.z = dot(hash(s + offset2), c2);
- nc.w = dot(hash(s + offset3), c3);
+ // Add all the noise contributions.
+ // Should multiply by the possible max contribution to adjust the range in [-1,1].
+ return dot(vec4(32.), nc);
+ }
- nc *= w*w*w*w;
+ // Random rotations.
+ // The way you create fractal noise is layering simplex noise with some rotation.
+ // To make random cloud looking noise, the rotations should not align. (Otherwise it
+ // creates patterned noise).
+ // Below rotations only rotate in one axis.
+ const mat3 rot1 = mat3(1.0, 0. ,0., 0., 0.15, -0.98, 0., 0.98, 0.15);
+ const mat3 rot2 = mat3(-0.95, 0. ,-0.3, 0., 1., 0., 0.3, 0., -0.95);
+ const mat3 rot3 = mat3(1.0, 0. ,0., 0., -0.44, -0.89, 0., 0.89, -0.44);
- // Add all the noise contributions.
- // Should multiply by the possible max contribution to adjust the range in [-1,1].
- return dot(vec4(32.), nc);
- }
+ // Octave = 4
+ // Divide each coefficient by 3 to produce more grainy noise.
+ half simplex3d_fractal(vec3 p) {
+ return 0.675 * simplex3d(p * rot1) + 0.225 * simplex3d(2.0 * p * rot2)
+ + 0.075 * simplex3d(4.0 * p * rot3) + 0.025 * simplex3d(8.0 * p);
+ }
- // Random rotations.
- // The way you create fractal noise is layering simplex noise with some rotation.
- // To make random cloud looking noise, the rotations should not align. (Otherwise it
- // creates patterned noise).
- // Below rotations only rotate in one axis.
- const mat3 rot1 = mat3(1.0, 0. ,0., 0., 0.15, -0.98, 0., 0.98, 0.15);
- const mat3 rot2 = mat3(-0.95, 0. ,-0.3, 0., 1., 0., 0.3, 0., -0.95);
- const mat3 rot3 = mat3(1.0, 0. ,0., 0., -0.44, -0.89, 0., 0.89, -0.44);
-
- // Octave = 4
- // Divide each coefficient by 3 to produce more grainy noise.
- half simplex3d_fractal(vec3 mat) {
- return 0.675 * simplex3d(mat * rot1) + 0.225 * simplex3d(2.0 * mat * rot2)
- + 0.075 * simplex3d(4.0 * mat * rot3) + 0.025 * simplex3d(8.0 * mat);
- }
- """
- }
+ // Screen blend
+ vec3 screen(vec3 dest, vec3 src) {
+ return dest + src - dest * src;
+ }
+ """
}
diff --git a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
index 0e22667..d1ba7c4 100644
--- a/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
+++ b/packages/SystemUI/animation/src/com/android/systemui/surfaceeffects/turbulencenoise/TurbulenceNoiseShader.kt
@@ -36,6 +36,7 @@
uniform float in_aspectRatio;
uniform float in_opacity;
uniform float in_pixelDensity;
+ uniform float in_inverseLuma;
layout(color) uniform vec4 in_color;
layout(color) uniform vec4 in_backgroundColor;
"""
@@ -47,7 +48,7 @@
uv.x *= in_aspectRatio;
vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum;
- float luma = simplex3d(noiseP) * in_opacity;
+ float luma = abs(in_inverseLuma - simplex3d(noiseP)) * in_opacity;
vec3 mask = maskLuminosity(in_color.rgb, luma);
vec3 color = in_backgroundColor.rgb + mask * 0.6;
@@ -69,7 +70,7 @@
uv.x *= in_aspectRatio;
vec3 noiseP = vec3(uv + in_noiseMove.xy, in_noiseMove.z) * in_gridNum;
- float luma = simplex3d_fractal(noiseP) * in_opacity;
+ float luma = abs(in_inverseLuma - simplex3d_fractal(noiseP)) * in_opacity;
vec3 mask = maskLuminosity(in_color.rgb, luma);
vec3 color = in_backgroundColor.rgb + mask * 0.6;
@@ -123,6 +124,17 @@
setFloatUniform("in_aspectRatio", width / max(height, 0.001f))
}
+ /**
+ * Sets whether to inverse the luminosity of the noise.
+ *
+ * By default noise will be used as a luma matte as is. This means that you will see color in
+ * the brighter area. If you want to invert it, meaning blend color onto the darker side, set to
+ * true.
+ */
+ fun setInverseNoiseLuminosity(inverse: Boolean) {
+ setFloatUniform("in_inverseLuma", if (inverse) 1f else 0f)
+ }
+
/** Current noise movements in x, y, and z axes. */
var noiseOffsetX: Float = 0f
private set
diff --git a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeInitializerImpl.kt b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeInitializerImpl.kt
index 772c891..fbd7f83 100644
--- a/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeInitializerImpl.kt
+++ b/packages/SystemUI/compose/facade/enabled/src/com/android/systemui/compose/ComposeInitializerImpl.kt
@@ -49,14 +49,12 @@
// initializer are created once, when the process is started.
val savedStateRegistryOwner =
object : SavedStateRegistryOwner {
- private val savedStateRegistry =
+ private val savedStateRegistryController =
SavedStateRegistryController.create(this).apply { performRestore(null) }
- override fun getLifecycle(): Lifecycle = lifecycleOwner.lifecycle
+ override val savedStateRegistry = savedStateRegistryController.savedStateRegistry
- override fun getSavedStateRegistry(): SavedStateRegistry {
- return savedStateRegistry.savedStateRegistry
- }
+ override fun getLifecycle(): Lifecycle = lifecycleOwner.lifecycle
}
// We must call [ViewLifecycleOwner.onCreate] after creating the [SavedStateRegistryOwner]
diff --git a/packages/SystemUI/compose/features/src/com/android/systemui/multishade/ui/composable/MultiShade.kt b/packages/SystemUI/compose/features/src/com/android/systemui/multishade/ui/composable/MultiShade.kt
index b9e38cf..99fe26c 100644
--- a/packages/SystemUI/compose/features/src/com/android/systemui/multishade/ui/composable/MultiShade.kt
+++ b/packages/SystemUI/compose/features/src/com/android/systemui/multishade/ui/composable/MultiShade.kt
@@ -53,6 +53,7 @@
modifier: Modifier = Modifier,
) {
val isScrimEnabled: Boolean by viewModel.isScrimEnabled.collectAsState()
+ val scrimAlpha: Float by viewModel.scrimAlpha.collectAsState()
// TODO(b/273298030): find a different way to get the height constraint from its parent.
BoxWithConstraints(modifier = modifier) {
@@ -61,7 +62,7 @@
Scrim(
modifier = Modifier.fillMaxSize(),
remoteTouch = viewModel::onScrimTouched,
- alpha = { viewModel.scrimAlpha.value },
+ alpha = { scrimAlpha },
isScrimEnabled = isScrimEnabled,
)
Shade(
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
index 00c0a0b..e73afe7 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/clocks/ClockRegistry.kt
@@ -29,14 +29,15 @@
import com.android.systemui.plugins.ClockProvider
import com.android.systemui.plugins.ClockProviderPlugin
import com.android.systemui.plugins.ClockSettings
+import com.android.systemui.plugins.PluginLifecycleManager
import com.android.systemui.plugins.PluginListener
import com.android.systemui.plugins.PluginManager
import com.android.systemui.util.Assert
+import java.util.concurrent.atomic.AtomicBoolean
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
-private val TAG = ClockRegistry::class.simpleName!!
private const val DEBUG = true
private val KEY_TIMESTAMP = "appliedTimestamp"
@@ -51,7 +52,10 @@
val handleAllUsers: Boolean,
defaultClockProvider: ClockProvider,
val fallbackClockId: ClockId = DEFAULT_CLOCK_ID,
+ val keepAllLoaded: Boolean,
+ val subTag: String,
) {
+ private val TAG = "${ClockRegistry::class.simpleName} ($subTag)"
interface ClockChangeListener {
// Called when the active clock changes
fun onCurrentClockChanged() {}
@@ -76,11 +80,85 @@
private val pluginListener =
object : PluginListener<ClockProviderPlugin> {
- override fun onPluginConnected(plugin: ClockProviderPlugin, context: Context) =
- connectClocks(plugin)
+ override fun onPluginAttached(manager: PluginLifecycleManager<ClockProviderPlugin>) {
+ manager.loadPlugin()
+ }
- override fun onPluginDisconnected(plugin: ClockProviderPlugin) =
- disconnectClocks(plugin)
+ override fun onPluginLoaded(
+ plugin: ClockProviderPlugin,
+ pluginContext: Context,
+ manager: PluginLifecycleManager<ClockProviderPlugin>
+ ) {
+ var isClockListChanged = false
+ for (clock in plugin.getClocks()) {
+ val id = clock.clockId
+ var isNew = false
+ val info =
+ availableClocks.getOrPut(id) {
+ isNew = true
+ ClockInfo(clock, plugin, manager)
+ }
+
+ if (isNew) {
+ isClockListChanged = true
+ onConnected(id)
+ }
+
+ if (manager != info.manager) {
+ Log.e(
+ TAG,
+ "Clock Id conflict on load: $id is registered to another provider"
+ )
+ continue
+ }
+
+ info.provider = plugin
+ onLoaded(id)
+ }
+
+ if (isClockListChanged) {
+ triggerOnAvailableClocksChanged()
+ }
+ verifyLoadedProviders()
+ }
+
+ override fun onPluginUnloaded(
+ plugin: ClockProviderPlugin,
+ manager: PluginLifecycleManager<ClockProviderPlugin>
+ ) {
+ for (clock in plugin.getClocks()) {
+ val id = clock.clockId
+ val info = availableClocks[id]
+ if (info?.manager != manager) {
+ Log.e(
+ TAG,
+ "Clock Id conflict on unload: $id is registered to another provider"
+ )
+ continue
+ }
+ info.provider = null
+ onUnloaded(id)
+ }
+
+ verifyLoadedProviders()
+ }
+
+ override fun onPluginDetached(manager: PluginLifecycleManager<ClockProviderPlugin>) {
+ val removed = mutableListOf<ClockId>()
+ availableClocks.entries.removeAll {
+ if (it.value.manager != manager) {
+ return@removeAll false
+ }
+
+ removed.add(it.key)
+ return@removeAll true
+ }
+
+ removed.forEach(::onDisconnected)
+ if (removed.size > 0) {
+ triggerOnAvailableClocksChanged()
+ }
+ }
}
private val userSwitchObserver =
@@ -96,7 +174,8 @@
protected set(value) {
if (field != value) {
field = value
- scope.launch(mainDispatcher) { onClockChanged { it.onCurrentClockChanged() } }
+ verifyLoadedProviders()
+ triggerOnCurrentClockChanged()
}
}
@@ -168,9 +247,36 @@
Assert.isNotMainThread()
}
- private fun onClockChanged(func: (ClockChangeListener) -> Unit) {
- assertMainThread()
- clockChangeListeners.forEach(func)
+ private var isClockChanged = AtomicBoolean(false)
+ private fun triggerOnCurrentClockChanged() {
+ val shouldSchedule = isClockChanged.compareAndSet(false, true)
+ if (!shouldSchedule) {
+ return
+ }
+
+ android.util.Log.e("HAWK", "triggerOnCurrentClockChanged")
+ scope.launch(mainDispatcher) {
+ assertMainThread()
+ android.util.Log.e("HAWK", "isClockChanged")
+ isClockChanged.set(false)
+ clockChangeListeners.forEach { it.onCurrentClockChanged() }
+ }
+ }
+
+ private var isClockListChanged = AtomicBoolean(false)
+ private fun triggerOnAvailableClocksChanged() {
+ val shouldSchedule = isClockListChanged.compareAndSet(false, true)
+ if (!shouldSchedule) {
+ return
+ }
+
+ android.util.Log.e("HAWK", "triggerOnAvailableClocksChanged")
+ scope.launch(mainDispatcher) {
+ assertMainThread()
+ android.util.Log.e("HAWK", "isClockListChanged")
+ isClockListChanged.set(false)
+ clockChangeListeners.forEach { it.onAvailableClocksChanged() }
+ }
}
public fun mutateSetting(mutator: (ClockSettings) -> ClockSettings) {
@@ -190,7 +296,12 @@
}
init {
- connectClocks(defaultClockProvider)
+ // Register default clock designs
+ for (clock in defaultClockProvider.getClocks()) {
+ availableClocks[clock.clockId] = ClockInfo(clock, defaultClockProvider, null)
+ }
+
+ // Something has gone terribly wrong if the default clock isn't present
if (!availableClocks.containsKey(DEFAULT_CLOCK_ID)) {
throw IllegalArgumentException(
"$defaultClockProvider did not register clock at $DEFAULT_CLOCK_ID"
@@ -244,59 +355,87 @@
}
}
- private fun connectClocks(provider: ClockProvider) {
- var isAvailableChanged = false
- val currentId = currentClockId
- for (clock in provider.getClocks()) {
- val id = clock.clockId
- val current = availableClocks[id]
- if (current != null) {
- Log.e(
- TAG,
- "Clock Id conflict: $id is registered by both " +
- "${provider::class.simpleName} and ${current.provider::class.simpleName}"
- )
- continue
- }
-
- availableClocks[id] = ClockInfo(clock, provider)
- isAvailableChanged = true
- if (DEBUG) {
- Log.i(TAG, "Added ${clock.clockId}")
- }
-
- if (currentId == id) {
- if (DEBUG) {
- Log.i(TAG, "Current clock ($currentId) was connected")
- }
- onClockChanged { it.onCurrentClockChanged() }
- }
+ private var isVerifying = AtomicBoolean(false)
+ private fun verifyLoadedProviders() {
+ val shouldSchedule = isVerifying.compareAndSet(false, true)
+ if (!shouldSchedule) {
+ return
}
- if (isAvailableChanged) {
- onClockChanged { it.onAvailableClocksChanged() }
+ scope.launch(bgDispatcher) {
+ if (keepAllLoaded) {
+ // Enforce that all plugins are loaded if requested
+ for ((_, info) in availableClocks) {
+ info.manager?.loadPlugin()
+ }
+ isVerifying.set(false)
+ return@launch
+ }
+
+ val currentClock = availableClocks[currentClockId]
+ if (currentClock == null) {
+ // Current Clock missing, load no plugins and use default
+ for ((_, info) in availableClocks) {
+ info.manager?.unloadPlugin()
+ }
+ isVerifying.set(false)
+ return@launch
+ }
+
+ val currentManager = currentClock.manager
+ currentManager?.loadPlugin()
+
+ for ((_, info) in availableClocks) {
+ val manager = info.manager
+ if (manager != null && manager.isLoaded && currentManager != manager) {
+ manager.unloadPlugin()
+ }
+ }
+ isVerifying.set(false)
}
}
- private fun disconnectClocks(provider: ClockProvider) {
- var isAvailableChanged = false
- val currentId = currentClockId
- for (clock in provider.getClocks()) {
- availableClocks.remove(clock.clockId)
- isAvailableChanged = true
-
- if (DEBUG) {
- Log.i(TAG, "Removed ${clock.clockId}")
- }
-
- if (currentId == clock.clockId) {
- Log.w(TAG, "Current clock ($currentId) was disconnected")
- onClockChanged { it.onCurrentClockChanged() }
- }
+ private fun onConnected(clockId: ClockId) {
+ if (DEBUG) {
+ Log.i(TAG, "Connected $clockId")
}
- if (isAvailableChanged) {
- onClockChanged { it.onAvailableClocksChanged() }
+ if (currentClockId == clockId) {
+ if (DEBUG) {
+ Log.i(TAG, "Current clock ($clockId) was connected")
+ }
+ }
+ }
+
+ private fun onLoaded(clockId: ClockId) {
+ if (DEBUG) {
+ Log.i(TAG, "Loaded $clockId")
+ }
+
+ if (currentClockId == clockId) {
+ Log.i(TAG, "Current clock ($clockId) was loaded")
+ triggerOnCurrentClockChanged()
+ }
+ }
+
+ private fun onUnloaded(clockId: ClockId) {
+ if (DEBUG) {
+ Log.i(TAG, "Unloaded $clockId")
+ }
+
+ if (currentClockId == clockId) {
+ Log.w(TAG, "Current clock ($clockId) was unloaded")
+ triggerOnCurrentClockChanged()
+ }
+ }
+
+ private fun onDisconnected(clockId: ClockId) {
+ if (DEBUG) {
+ Log.i(TAG, "Disconnected $clockId")
+ }
+
+ if (currentClockId == clockId) {
+ Log.w(TAG, "Current clock ($clockId) was disconnected")
}
}
@@ -345,6 +484,7 @@
private data class ClockInfo(
val metadata: ClockMetadata,
- val provider: ClockProvider,
+ var provider: ClockProvider?,
+ val manager: PluginLifecycleManager<ClockProviderPlugin>?,
)
}
diff --git a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
index 0d88075..f9e8aaf 100644
--- a/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
+++ b/packages/SystemUI/customization/src/com/android/systemui/shared/customization/data/content/CustomizationProviderContract.kt
@@ -184,6 +184,9 @@
/** Flag denoting whether the Monochromatic Theme is enabled. */
const val FLAG_NAME_MONOCHROMATIC_THEME = "is_monochromatic_theme_enabled"
+ /** Flag denoting AI Wallpapers are enabled in wallpaper picker. */
+ const val FLAG_NAME_WALLPAPER_PICKER_UI_FOR_AIWP = "wallpaper_picker_ui_for_aiwp"
+
object Columns {
/** String. Unique ID for the flag. */
const val NAME = "name"
diff --git a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
index 70b5d73..b7088d5 100644
--- a/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
+++ b/packages/SystemUI/plugin/src/com/android/systemui/plugins/statusbar/StatusBarStateController.java
@@ -50,6 +50,13 @@
boolean isPulsing();
/**
+ * Is device dreaming. This method is more inclusive than
+ * {@link android.service.dreams.IDreamManager.isDreaming}, as it will return true during the
+ * dream's wake-up phase.
+ */
+ boolean isDreaming();
+
+ /**
* Adds a state listener
*/
void addCallback(StateListener listener);
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginLifecycleManager.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginLifecycleManager.java
new file mode 100644
index 0000000..cc6a46f
--- /dev/null
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginLifecycleManager.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.plugins;
+
+/**
+ * Provides the ability for consumers to control plugin lifecycle.
+ *
+ * @param <T> is the target plugin type
+ */
+public interface PluginLifecycleManager<T extends Plugin> {
+ /** Returns the currently loaded plugin instance (if plugin is loaded) */
+ T getPlugin();
+
+ /** returns true if the plugin is currently loaded */
+ default boolean isLoaded() {
+ return getPlugin() != null;
+ }
+
+ /**
+ * Loads and creates the plugin instance if it does not exist.
+ *
+ * This will trigger {@link PluginListener#onPluginLoaded} with the new instance if it did not
+ * already exist.
+ */
+ void loadPlugin();
+
+ /**
+ * Unloads and destroys the plugin instance if it exists.
+ *
+ * This will trigger {@link PluginListener#onPluginUnloaded} if a concrete plugin instance
+ * existed when this call was made.
+ */
+ void unloadPlugin();
+}
diff --git a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java
index b488d2a..c5f5032 100644
--- a/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java
+++ b/packages/SystemUI/plugin_core/src/com/android/systemui/plugins/PluginListener.java
@@ -17,7 +17,32 @@
import android.content.Context;
/**
- * Interface for listening to plugins being connected.
+ * Interface for listening to plugins being connected and disconnected.
+ *
+ * The call order for a plugin is
+ * 1) {@link #onPluginAttached}
+ * Called when a new plugin is added to the device, or an existing plugin was replaced by
+ * the package manager. Will only be called once per package manager event. If multiple
+ * non-conflicting packages which have the same plugin interface are installed on the
+ * device, then this method can be called multiple times with different instances of
+ * {@link PluginLifecycleManager} (as long as `allowMultiple` was set to true when the
+ * listener was registered with {@link PluginManager#addPluginListener}).
+ * 2) {@link #onPluginLoaded}
+ * Called whenever a new instance of the plugin object is created and ready for use. Can be
+ * called multiple times per {@link PluginLifecycleManager}, but will always pass a newly
+ * created plugin object. {@link #onPluginUnloaded} with the previous plugin object will
+ * be called before another call to {@link #onPluginLoaded} is made. This method will be
+ * called once automatically after {@link #onPluginAttached}. Besides the initial call,
+ * {@link #onPluginLoaded} will occur due to {@link PluginLifecycleManager#loadPlugin}.
+ * 3) {@link #onPluginUnloaded}
+ * Called when a request to unload the plugin has been received. This can be triggered from
+ * a related call to {@link PluginLifecycleManager#unloadPlugin} or for any reason that
+ * {@link #onPluginDetached} would be triggered.
+ * 4) {@link #onPluginDetached}
+ * Called when the package is removed from the device, disabled, or replaced due to an
+ * external trigger. These are events from the android package manager.
+ *
+ * @param <T> is the target plugin type
*/
public interface PluginListener<T extends Plugin> {
/**
@@ -25,14 +50,69 @@
* This may be called multiple times if multiple plugins are allowed.
* It may also be called in the future if the plugin package changes
* and needs to be reloaded.
+ *
+ * @deprecated Migrate to {@link #onPluginLoaded} or {@link #onPluginAttached}
*/
- void onPluginConnected(T plugin, Context pluginContext);
+ @Deprecated
+ default void onPluginConnected(T plugin, Context pluginContext) {
+ // Optional
+ }
+
+ /**
+ * Called when the plugin is first attached to the host application. {@link #onPluginLoaded}
+ * will be automatically called as well when first attached. This may be called multiple times
+ * if multiple plugins are allowed. It may also be called in the future if the plugin package
+ * changes and needs to be reloaded. Each call to {@link #onPluginAttached} will provide a new
+ * or different {@link PluginLifecycleManager}.
+ */
+ default void onPluginAttached(PluginLifecycleManager<T> manager) {
+ // Optional
+ }
/**
* Called when a plugin has been uninstalled/updated and should be removed
* from use.
+ *
+ * @deprecated Migrate to {@link #onPluginDetached} or {@link #onPluginUnloaded}
*/
+ @Deprecated
default void onPluginDisconnected(T plugin) {
// Optional.
}
-}
+
+ /**
+ * Called when the plugin has been detached from the host application. Implementers should no
+ * longer attempt to reload it via this {@link PluginLifecycleManager}. If the package was
+ * updated and not removed, then {@link #onPluginAttached} will be called again when the updated
+ * package is available.
+ */
+ default void onPluginDetached(PluginLifecycleManager<T> manager) {
+ // Optional.
+ }
+
+ /**
+ * Called when the plugin is loaded into the host's process and is available for use. This can
+ * happen several times if clients are using {@link PluginLifecycleManager} to manipulate a
+ * plugin's load state. Each call to {@link #onPluginLoaded} will have a matched call to
+ * {@link #onPluginUnloaded} when that plugin object should no longer be used.
+ */
+ default void onPluginLoaded(
+ T plugin,
+ Context pluginContext,
+ PluginLifecycleManager<T> manager
+ ) {
+ // Optional, default to deprecated version
+ onPluginConnected(plugin, pluginContext);
+ }
+
+ /**
+ * Called when the plugin should no longer be used. Listeners should clean up all references to
+ * the relevant plugin so that it can be garbage collected. If the plugin object is required in
+ * the future a call can be made to {@link PluginLifecycleManager#loadPlugin} to create a new
+ * plugin object and trigger {@link #onPluginLoaded}.
+ */
+ default void onPluginUnloaded(T plugin, PluginLifecycleManager<T> manager) {
+ // Optional, default to deprecated version
+ onPluginDisconnected(plugin);
+ }
+}
\ No newline at end of file
diff --git a/packages/SystemUI/proguard.flags b/packages/SystemUI/proguard.flags
index 038021e..a8ed843 100644
--- a/packages/SystemUI/proguard.flags
+++ b/packages/SystemUI/proguard.flags
@@ -5,7 +5,7 @@
*;
}
--keep class com.android.systemui.tv.TVSystemUIInitializer {
+-keep class com.android.systemui.tv.TvSystemUIInitializer {
*;
}
diff --git a/packages/SystemUI/res-keyguard/values-am/strings.xml b/packages/SystemUI/res-keyguard/values-am/strings.xml
index 9cbb627..4129f07 100644
--- a/packages/SystemUI/res-keyguard/values-am/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-am/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • በፍጥነት ኃይልን በመሙላት ላይ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • በዝግታ ኃይልን በመሙላት ላይ"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ባትሪን ለመጠበቅ ኃይል መሙላት ተብቷል"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ተለዋዋጭን ኃይል በመሙላት ላይ ችግር"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ለመክፈት ምናሌ ተጫን።"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"አውታረ መረብ ተቆልፏል"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"ምንም SIM የለም"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ar/strings.xml b/packages/SystemUI/res-keyguard/values-ar/strings.xml
index ad931fe..b340d56 100644
--- a/packages/SystemUI/res-keyguard/values-ar/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ar/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن سريعًا"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • جارٍ الشحن ببطء"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • تم تحسين الشحن لحماية البطارية"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • مشكلة متعلّقة بجهاز الشحن الملحق"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"اضغط على \"القائمة\" لإلغاء التأمين."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"الشبكة مؤمّنة"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"لا تتوفر شريحة SIM."</string>
diff --git a/packages/SystemUI/res-keyguard/values-as/strings.xml b/packages/SystemUI/res-keyguard/values-as/strings.xml
index cdc260e..cb446b9 100644
--- a/packages/SystemUI/res-keyguard/values-as/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-as/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্ৰুত গতিৰে চ্চাৰ্জ কৰি থকা হৈছে"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • লাহে লাহে চ্চাৰ্জ কৰি থকা হৈছে"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • বেটাৰী সুৰক্ষিত কৰিবলৈ চাৰ্জিং অপ্টিমাইজ কৰা হৈছে"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চাৰ্জিঙৰ আনুষংগিক সামগ্ৰীত সমস্যা হৈছে"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক কৰিবলৈ মেনু টিপক।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটৱর্ক লক কৰা অৱস্থাত আছে"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"কোনো ছিম নাই"</string>
diff --git a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
index 30a55d1..90a5a20 100644
--- a/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-b+sr+Latn/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Brzo se puni"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Sporo se puni"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Punjenje je optimizovano da bi se zaštitila baterija"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem sa dodatnim priborom za punjenje"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pritisnite Meni da biste otključali."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mreža je zaključana"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nema SIM-a"</string>
diff --git a/packages/SystemUI/res-keyguard/values-be/strings.xml b/packages/SystemUI/res-keyguard/values-be/strings.xml
index 844ed93..8127353 100644
--- a/packages/SystemUI/res-keyguard/values-be/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-be/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе хуткая зарадка"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ідзе павольная зарадка"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • У мэтах зберажэння акумулятара зарадка аптымізавана"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Праблема з зараднай прыладай"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Націсніце кнопку \"Меню\", каб разблакіраваць."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сетка заблакіравана"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Няма SIM-карты"</string>
diff --git a/packages/SystemUI/res-keyguard/values-bn/strings.xml b/packages/SystemUI/res-keyguard/values-bn/strings.xml
index cb25c99..414eb51 100644
--- a/packages/SystemUI/res-keyguard/values-bn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-bn/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • দ্রুত চার্জ হচ্ছে"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ধীরে চার্জ হচ্ছে"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ব্যাটারি ভাল রাখতে চার্জিং অপ্টিমাইজ করা হয়েছে"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • চার্জিং অ্যাক্সেসরিতে সমস্যা রয়েছে"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"আনলক করতে মেনুতে টিপুন।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"নেটওয়ার্ক লক করা আছে"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"কোনও সিম নেই"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ca/strings.xml b/packages/SystemUI/res-keyguard/values-ca/strings.xml
index 185461f..7dac29d 100644
--- a/packages/SystemUI/res-keyguard/values-ca/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ca/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant ràpidament"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • S\'està carregant lentament"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Càrrega optimitzada per protegir la bateria"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema relacionat amb l\'accessori de càrrega"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prem Menú per desbloquejar."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"La xarxa està bloquejada"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No hi ha cap SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-cs/strings.xml b/packages/SystemUI/res-keyguard/values-cs/strings.xml
index f2ebe80..fcd3231 100644
--- a/packages/SystemUI/res-keyguard/values-cs/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-cs/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Rychlé nabíjení"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pomalé nabíjení"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Optimalizované nabíjení za účelem ochrany baterie"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problém s nabíjecím příslušenstvím"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Klávesy odemknete stisknutím tlačítka nabídky."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Síť je blokována"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Žádná SIM karta"</string>
diff --git a/packages/SystemUI/res-keyguard/values-da/strings.xml b/packages/SystemUI/res-keyguard/values-da/strings.xml
index aedfa58..e0cc87d 100644
--- a/packages/SystemUI/res-keyguard/values-da/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-da/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader hurtigt"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Oplader langsomt"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Opladning er optimeret for at beskytte batteriet"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem med opladertilbehør"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tryk på menuen for at låse op."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netværket er låst"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Intet SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-de/strings.xml b/packages/SystemUI/res-keyguard/values-de/strings.xml
index 294bb68..9c7fab5 100644
--- a/packages/SystemUI/res-keyguard/values-de/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-de/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird schnell geladen"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Wird langsam geladen"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Optimiertes Laden zur Akkuschonung"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem mit dem Ladezubehör"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Zum Entsperren die Menütaste drücken."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Netzwerk gesperrt"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Keine SIM-Karte"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
index fec15b4..03608ce 100644
--- a/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es-rUS/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rápidamente"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga optimizada para proteger la batería"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema con el accesorio de carga"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Presiona Menú para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No hay ninguna tarjeta SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-es/strings.xml b/packages/SystemUI/res-keyguard/values-es/strings.xml
index 04e02d8..6ff17ca 100644
--- a/packages/SystemUI/res-keyguard/values-es/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-es/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rápidamente"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga optimizada para proteger la batería"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema con el accesorio de carga"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Pulsa el menú para desbloquear la pantalla."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada para la red"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"No hay ninguna SIM."</string>
diff --git a/packages/SystemUI/res-keyguard/values-fa/strings.xml b/packages/SystemUI/res-keyguard/values-fa/strings.xml
index edb4761..e88b4b3 100644
--- a/packages/SystemUI/res-keyguard/values-fa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fa/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • درحال شارژ سریع"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • آهستهآهسته شارژ میشود"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • برای محافظت از باتری، شارژ بهینه میشود"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • در شارژ وسیله جانبی مشکلی وجود دارد"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"برای باز کردن قفل روی «منو» فشار دهید."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"شبکه قفل شد"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"سیمکارتی وجود ندارد"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fi/strings.xml b/packages/SystemUI/res-keyguard/values-fi/strings.xml
index e6b1400..17928c7 100644
--- a/packages/SystemUI/res-keyguard/values-fi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fi/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan nopeasti"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladataan hitaasti"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lataus optimoitu akun suojaamiseksi"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ongelma laturin kanssa"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Poista lukitus painamalla Valikkoa."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Verkko lukittu"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Ei SIM-korttia"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
index 57e4664..7978fda 100644
--- a/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr-rCA/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"En recharge rapide : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"En recharge lente : <xliff:g id="PERCENTAGE">%s</xliff:g>"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge optimisée pour protéger la pile"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problème concernant l\'accessoire de recharge"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur la touche Menu pour déverrouiller l\'appareil."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Aucune carte SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-fr/strings.xml b/packages/SystemUI/res-keyguard/values-fr/strings.xml
index 81f0034..67ce8b1 100644
--- a/packages/SystemUI/res-keyguard/values-fr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-fr/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge rapide…"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge lente"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Recharge optimisée pour protéger la batterie"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problème de recharge de l\'accessoire"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Appuyez sur \"Menu\" pour déverrouiller le clavier."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Réseau verrouillé"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Aucune SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gl/strings.xml b/packages/SystemUI/res-keyguard/values-gl/strings.xml
index 43d41e1..c1159e8 100644
--- a/packages/SystemUI/res-keyguard/values-gl/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gl/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando rapidamente"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Cargando lentamente"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carga optimizada para protexer a batería"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema co accesorio de carga"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Preme Menú para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Bloqueada pola rede"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Non hai ningunha SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-gu/strings.xml b/packages/SystemUI/res-keyguard/values-gu/strings.xml
index 2524397..8ef5dc2 100644
--- a/packages/SystemUI/res-keyguard/values-gu/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-gu/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ઝડપથી ચાર્જિંગ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ધીમેથી ચાર્જિંગ"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • બૅટરીની સુરક્ષા કરવા માટે, ચાર્જિંગ ઑપ્ટિમાઇઝ કરવામાં આવ્યું છે"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ચાર્જિંગ ઍક્સેસરીમાં સમસ્યા"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"અનલૉક કરવા માટે મેનૂ દબાવો."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"નેટવર્ક લૉક થયું"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"કોઈ સિમ કાર્ડ નથી"</string>
diff --git a/packages/SystemUI/res-keyguard/values-hy/strings.xml b/packages/SystemUI/res-keyguard/values-hy/strings.xml
index 0ecc55c..e85f61c 100644
--- a/packages/SystemUI/res-keyguard/values-hy/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-hy/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Արագ լիցքավորում"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Դանդաղ լիցքավորում"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Մարտկոցը պաշտպանելու համար լիցքավորումն օպտիմալացվել է"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Լիցքավորիչի հետ կապված խնդիր"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ապակողպելու համար սեղմեք Ընտրացանկը:"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Ցանցը կողպված է"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM քարտ չկա"</string>
diff --git a/packages/SystemUI/res-keyguard/values-in/strings.xml b/packages/SystemUI/res-keyguard/values-in/strings.xml
index 39f6553..bc00d74 100644
--- a/packages/SystemUI/res-keyguard/values-in/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-in/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya dengan cepat"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Mengisi daya dengan lambat"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Pengisian daya dioptimalkan untuk melindungi baterai"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Masalah dengan aksesori pengisian daya"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Tekan Menu untuk membuka kunci."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Jaringan terkunci"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Tidak ada SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-is/strings.xml b/packages/SystemUI/res-keyguard/values-is/strings.xml
index c06109d..1d93e08 100644
--- a/packages/SystemUI/res-keyguard/values-is/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-is/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hröð hleðsla"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hæg hleðsla"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hleðsla fínstillt til að vernda rafhlöðuna"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Vandamál með hleðslubúnað"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ýttu á valmyndarhnappinn til að taka úr lás."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Net læst"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Ekkert SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-it/strings.xml b/packages/SystemUI/res-keyguard/values-it/strings.xml
index cc05bee..51a86df 100644
--- a/packages/SystemUI/res-keyguard/values-it/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-it/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica veloce"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica lenta"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ricarica ottimizzata per proteggere la batteria"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema relativo all\'accessorio di ricarica"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Premi Menu per sbloccare."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rete bloccata"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nessuna SIM presente"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ka/strings.xml b/packages/SystemUI/res-keyguard/values-ka/strings.xml
index eb96a9e..6b57061 100644
--- a/packages/SystemUI/res-keyguard/values-ka/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ka/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • სწრაფად იტენება"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ნელა იტენება"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • დატენვა ოპტიმიზირებულია ბატარეის დასაცავად"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • დამტენი დამხმარე მოწყობილობის პრობლემა"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"განსაბლოკად დააჭირეთ მენიუს."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ქსელი ჩაკეტილია"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM არ არის"</string>
diff --git a/packages/SystemUI/res-keyguard/values-kk/strings.xml b/packages/SystemUI/res-keyguard/values-kk/strings.xml
index 90519df..db031d6 100644
--- a/packages/SystemUI/res-keyguard/values-kk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-kk/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жылдам зарядталуда"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Баяу зарядталуда"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны қорғау үшін зарядтау оңтайландырылды"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядтау құрылғысына қатысты мәселе туындады."</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Ашу үшін \"Мәзір\" пернесін басыңыз."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Желі құлыптаулы"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM картасы жоқ."</string>
diff --git a/packages/SystemUI/res-keyguard/values-ky/strings.xml b/packages/SystemUI/res-keyguard/values-ky/strings.xml
index 5cf8ad3..23afa38 100644
--- a/packages/SystemUI/res-keyguard/values-ky/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ky/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Тез кубатталууда"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Жай кубатталууда"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батареяны коргоо үчүн кубаттоо процесси оптималдаштырылды"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Кубаттоочу шайманда көйгөй бар"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Кулпуну ачуу үчүн Менюну басыңыз."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Тармак кулпуланган"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM карта жок"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lo/strings.xml b/packages/SystemUI/res-keyguard/values-lo/strings.xml
index 7e3cd89..408e916 100644
--- a/packages/SystemUI/res-keyguard/values-lo/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lo/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກແບບດ່ວນ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ກຳລັງສາກແບບຊ້າ"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ການສາກຖືກປັບໃຫ້ເໝາະສົມເພື່ອປົກປ້ອງແບັດເຕີຣີ"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ບັນຫາກັບອຸປະກອນເສີມໃນການສາກ"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ກົດ \"ເມນູ\" ເພື່ອປົດລັອກ."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ເຄືອຂ່າຍຖືກລັອກ"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"ບໍ່ມີຊິມ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lt/strings.xml b/packages/SystemUI/res-keyguard/values-lt/strings.xml
index 23601d3..b60f2b7 100644
--- a/packages/SystemUI/res-keyguard/values-lt/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lt/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Greitai įkraunama"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lėtai įkraunama"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Įkrovimas optimizuotas siekiant apsaugoti akumuliatorių"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Su įkrovimo priedu susijusi problema"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Paspauskite meniu, jei norite atrakinti."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Tinklas užrakintas"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nėra SIM kortelės"</string>
diff --git a/packages/SystemUI/res-keyguard/values-lv/strings.xml b/packages/SystemUI/res-keyguard/values-lv/strings.xml
index e66a018..e8cd99b 100644
--- a/packages/SystemUI/res-keyguard/values-lv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-lv/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek ātrā uzlāde"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Notiek lēnā uzlāde"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Uzlāde optimizēta, lai saudzētu akumulatoru"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problēma ar uzlādes ierīci"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lai atbloķētu, nospiediet izvēlnes ikonu."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Tīkls ir bloķēts."</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Nav SIM kartes"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mk/strings.xml b/packages/SystemUI/res-keyguard/values-mk/strings.xml
index 28d6988..b35be97 100644
--- a/packages/SystemUI/res-keyguard/values-mk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mk/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо полнење"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Бавно полнење"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Полнењето е оптимизирано за да се заштити батеријата"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проблем со додатокот за полнење"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притиснете „Мени“ за отклучување."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежата е заклучена"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Нема SIM-картичка"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mn/strings.xml b/packages/SystemUI/res-keyguard/values-mn/strings.xml
index 1b36541..2e941ba 100644
--- a/packages/SystemUI/res-keyguard/values-mn/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mn/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Хурдан цэнэглэж байна"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Удаан цэнэглэж байна"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Батарейг хамгаалахын тулд цэнэглэх явцыг оновчилсон"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Цэнэглэх хэрэгсэлд асуудал гарлаа"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Түгжээг тайлах бол цэсийг дарна уу."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сүлжээ түгжигдсэн"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM байхгүй"</string>
diff --git a/packages/SystemUI/res-keyguard/values-mr/strings.xml b/packages/SystemUI/res-keyguard/values-mr/strings.xml
index 400d884..74b3d39 100644
--- a/packages/SystemUI/res-keyguard/values-mr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-mr/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • वेगाने चार्ज होत आहे"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • सावकाश चार्ज होत आहे"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • बॅटरीचे संरक्षण करण्यासाठी चार्जिंग ऑप्टिमाइझ केले आहे"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्जिंगच्या ॲक्सेसरीसंबंधित समस्या"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलॉक करण्यासाठी मेनू दाबा."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लॉक केले"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"सिम नाही"</string>
diff --git a/packages/SystemUI/res-keyguard/values-nb/strings.xml b/packages/SystemUI/res-keyguard/values-nb/strings.xml
index a9a051e..abc0005 100644
--- a/packages/SystemUI/res-keyguard/values-nb/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-nb/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader raskt"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Lader sakte"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ladingen er optimalisert for å beskytte batteriet"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problem med ladetilbehøret"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Trykk på menyknappen for å låse opp."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Nettverket er låst"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Ingen SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ne/strings.xml b/packages/SystemUI/res-keyguard/values-ne/strings.xml
index f533610..d835f42 100644
--- a/packages/SystemUI/res-keyguard/values-ne/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ne/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • द्रुत गतिमा चार्ज गरिँदै छ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • मन्द गतिमा चार्ज गरिँदै"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ब्याट्री जोगाउन चार्ज गर्ने प्रक्रिया अप्टिमाइज गरिएको छ"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • चार्ज गर्ने एक्सेसरीमा कुनै समस्या आयो"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"अनलक गर्न मेनु थिच्नुहोस्।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"नेटवर्क लक भएको छ"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM कार्ड हालिएको छैन"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pa/strings.xml b/packages/SystemUI/res-keyguard/values-pa/strings.xml
index bf435ee..383eee5 100644
--- a/packages/SystemUI/res-keyguard/values-pa/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pa/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਤੇਜ਼ੀ ਨਾਲ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਹੌਲੀ-ਹੌਲੀ ਚਾਰਜ ਹੋ ਰਿਹਾ ਹੈ"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਬੈਟਰੀ ਦੀ ਸੁਰੱਖਿਆ ਲਈ ਚਾਰਜਿੰਗ ਨੂੰ ਸੁਯੋਗ ਬਣਾਇਆ ਗਿਆ"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • ਚਾਰਜ ਕਰਨ ਵਾਲੀ ਐਕਸੈਸਰੀ ਸੰਬੰਧੀ ਸਮੱਸਿਆ"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"ਅਣਲਾਕ ਕਰਨ ਲਈ \"ਮੀਨੂ\" ਦਬਾਓ।"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"ਨੈੱਟਵਰਕ ਲਾਕ ਕੀਤਾ ਗਿਆ"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"ਕੋਈ ਸਿਮ ਨਹੀਂ ਹੈ"</string>
diff --git a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
index 5a5212e..e0d3eb0 100644
--- a/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-pt-rPT/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar rapidamente…"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • A carregar lentamente…"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Carregamento otimizado para proteger a bateria"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problema com o acessório de carregamento"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Prima Menu para desbloquear."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rede bloqueada"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Sem SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ro/strings.xml b/packages/SystemUI/res-keyguard/values-ro/strings.xml
index 4730293..0a5538f 100644
--- a/packages/SystemUI/res-keyguard/values-ro/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ro/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă rapid"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Se încarcă lent"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Încărcarea este optimizată pentru a proteja bateria"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Problemă legată de accesoriul de încărcare"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Apasă pe Meniu pentru a debloca."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Rețea blocată"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Niciun card SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ru/strings.xml b/packages/SystemUI/res-keyguard/values-ru/strings.xml
index 792af9d..39bf861 100644
--- a/packages/SystemUI/res-keyguard/values-ru/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ru/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"Идет быстрая зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"Идет медленная зарядка (<xliff:g id="PERCENTAGE">%s</xliff:g>)"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Зарядка оптимизирована для защиты батареи"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проблема с зарядным устройством"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Для разблокировки нажмите \"Меню\"."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Сеть заблокирована"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM-карта отсутствует"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sr/strings.xml b/packages/SystemUI/res-keyguard/values-sr/strings.xml
index 98d9029..a26d7e8 100644
--- a/packages/SystemUI/res-keyguard/values-sr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sr/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Брзо се пуни"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Споро се пуни"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Пуњење је оптимизовано да би се заштитила батерија"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проблем са додатним прибором за пуњење"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Притисните Мени да бисте откључали."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мрежа је закључана"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Нема SIM-а"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sv/strings.xml b/packages/SystemUI/res-keyguard/values-sv/strings.xml
index 22e7fdb..623532b 100644
--- a/packages/SystemUI/res-keyguard/values-sv/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sv/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas snabbt"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddas långsamt"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Laddningen har optimerats för att skydda batteriet"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Ett problem uppstod med att ladda tillbehöret"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Lås upp genom att trycka på Meny."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Nätverk låst"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Inget SIM-kort"</string>
diff --git a/packages/SystemUI/res-keyguard/values-sw/strings.xml b/packages/SystemUI/res-keyguard/values-sw/strings.xml
index bdf5b00..96309e1 100644
--- a/packages/SystemUI/res-keyguard/values-sw/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-sw/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji kwa kasi"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Inachaji pole pole"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hali ya kuchaji imeboreshwa ili kulinda betri"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Kifuasi cha kuchaji kina hitilafu"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Bonyeza Menyu ili kufungua."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mtandao umefungwa"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Hakuna SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-ta/strings.xml b/packages/SystemUI/res-keyguard/values-ta/strings.xml
index f23c839..9f85a97 100644
--- a/packages/SystemUI/res-keyguard/values-ta/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-ta/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • வேகமாகச் சார்ஜாகிறது"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • மெதுவாகச் சார்ஜாகிறது"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • பேட்டரியைப் பாதுகாக்க சார்ஜிங் மேம்படுத்தப்பட்டுள்ளது"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • சார்ஜரில் சிக்கல் உள்ளது"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"அன்லாக் செய்ய மெனுவை அழுத்தவும்."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"நெட்வொர்க் பூட்டப்பட்டது"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"சிம் இல்லை"</string>
diff --git a/packages/SystemUI/res-keyguard/values-tr/strings.xml b/packages/SystemUI/res-keyguard/values-tr/strings.xml
index 2ee4e67..ae8be96 100644
--- a/packages/SystemUI/res-keyguard/values-tr/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-tr/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Hızlı şarj oluyor"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Yavaş şarj oluyor"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj işlemi pili korumak üzere optimize edildi"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Şarj aksesuarı ile ilgili sorun"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Kilidi açmak için Menü\'ye basın."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Ağ kilitli"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"SIM yok"</string>
diff --git a/packages/SystemUI/res-keyguard/values-uk/strings.xml b/packages/SystemUI/res-keyguard/values-uk/strings.xml
index 52daa8e..3b3b20c 100644
--- a/packages/SystemUI/res-keyguard/values-uk/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-uk/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Швидке заряджання"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Повільне заряджання"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Заряджання оптимізовано, щоб захистити акумулятор"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Проблема із зарядним пристроєм"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Натисніть меню, щоб розблокувати."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Мережу заблоковано"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Немає SIM-карти"</string>
diff --git a/packages/SystemUI/res-keyguard/values-vi/strings.xml b/packages/SystemUI/res-keyguard/values-vi/strings.xml
index 287363d..79b9f06 100644
--- a/packages/SystemUI/res-keyguard/values-vi/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-vi/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc nhanh"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Đang sạc chậm"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Quá trình sạc được tối ưu hoá để bảo vệ pin"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • Có vấn đề với phụ kiện sạc"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"Nhấn vào Menu để mở khóa."</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"Mạng đã bị khóa"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"Không có SIM"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
index d69bbc0..8eeb8a3f 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rHK/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 快速充電中"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 慢速充電中"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 為保護電池,系統已優化充電"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電配件發生問題"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按下 [選單] 即可解鎖。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"網絡已鎖定"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"沒有 SIM 卡"</string>
diff --git a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
index c11959c..781cf44 100644
--- a/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-keyguard/values-zh-rTW/strings.xml
@@ -31,8 +31,7 @@
<string name="keyguard_plugged_in_charging_fast" msgid="4386594091107340426">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 快速充電中"</string>
<string name="keyguard_plugged_in_charging_slowly" msgid="217655355424210">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 慢速充電中"</string>
<string name="keyguard_plugged_in_charging_limited" msgid="1053130519456324630">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 為保護電池,充電效能已最佳化"</string>
- <!-- no translation found for keyguard_plugged_in_incompatible_charger (3687961801947819076) -->
- <skip />
+ <string name="keyguard_plugged_in_incompatible_charger" msgid="3687961801947819076">"<xliff:g id="PERCENTAGE">%s</xliff:g> • 充電配件有問題"</string>
<string name="keyguard_instructions_when_pattern_disabled" msgid="8448804180089936954">"按選單鍵解鎖。"</string>
<string name="keyguard_network_locked_message" msgid="407096292844868608">"網路已鎖定"</string>
<string name="keyguard_missing_sim_message_short" msgid="685029586173458728">"沒有 SIM 卡"</string>
diff --git a/packages/SystemUI/res-product/values-af/strings.xml b/packages/SystemUI/res-product/values-af/strings.xml
index 8d416b3..1fab1d4 100644
--- a/packages/SystemUI/res-product/values-af/strings.xml
+++ b/packages/SystemUI/res-product/values-af/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Jy het die foon <xliff:g id="NUMBER">%d</xliff:g> keer verkeerd probeer ontsluit. Die werkprofiel sal verwyder word, wat alle profieldata sal uitvee."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou e-posrekening te gebruik om jou tablet te ontsluit.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Jy het jou ontsluitpatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer verkeerd geteken. Na nóg <xliff:g id="NUMBER_1">%2$d</xliff:g> onsuksesvolle pogings sal jy gevra word om jou e-posrekening te gebruik om jou foon te ontsluit.\n\n Probeer weer oor <xliff:g id="NUMBER_2">%3$d</xliff:g> sekondes."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Die vingerafdruksensor is op die aan/af-skakelaar. Dit is die plat knoppie langs die verhewe volumeknoppie aan die kant van die tablet.\n\nDie skerm skakel af wanneer iemand die aan/af-skakelaar druk."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Die vingerafdruksensor is op die aan/af-skakelaar. Dit is die plat knoppie langs die verhewe volumeknoppie aan die kant van die toestel.\n\nDie skerm skakel af wanneer iemand die aan/af-skakelaar druk."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Die vingerafdruksensor is op die aan/af-skakelaar. Dit is die plat knoppie langs die verhewe volumeknoppie aan die kant van die foon.\n\nDie skerm skakel af wanneer iemand die aan/af-skakelaar druk."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Die vingerafdruksensor is op die aan/af-skakelaar. Dit is die plat knoppie langs die verhewe volumeknoppie aan die kant van die tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Die vingerafdruksensor is op die aan/af-skakelaar. Dit is die plat knoppie langs die verhewe volumeknoppie aan die kant van die toestel."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Die vingerafdruksensor is op die aan/af-skakelaar. Dit is die plat knoppie langs die verhewe volumeknoppie aan die kant van die foon."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ontsluit jou foon vir meer opsies"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ontsluit jou tablet vir meer opsies"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ontsluit jou toestel vir meer opsies"</string>
diff --git a/packages/SystemUI/res-product/values-am/strings.xml b/packages/SystemUI/res-product/values-am/strings.xml
index ca062e1..ab55d22 100644
--- a/packages/SystemUI/res-product/values-am/strings.xml
+++ b/packages/SystemUI/res-product/values-am/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ስልኩን <xliff:g id="NUMBER">%d</xliff:g> ጊዜ ትክክል ባልሆነ መልኩ ለመክፈት ሞክረዋል። የስራ መገለጫው ይወገዳል፣ ይህም ሁሉንም የመገለጫ ውሂብ ይሰርዛል።"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ጡባዊዎን እንዲከፍቱ ይጠየቃሉ።\n\n ከ<xliff:g id="NUMBER_2">%3$d</xliff:g> ከሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"የመክፈቻ ስርዓተ ጥለቱን <xliff:g id="NUMBER_0">%1$d</xliff:g> ጊዜ በትክክል አልሳሉትም። ከ<xliff:g id="NUMBER_1">%2$d</xliff:g> ተጨማሪ ያልተሳኩ ሙከራዎች በኋላ የኢሜይል መለያ ተጠቅመው ስልክዎን እንዲከፍቱ ይጠየቃሉ።\n\nእባክዎ ከ<xliff:g id="NUMBER_2">%3$d</xliff:g> ሰከንዶች በኋላ እንደገና ይሞክሩ።"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"የጣት አሻራ ዳሳሹ የማብሪያ/ማጥፊያ ቁልፉ ላይ ነው። በጡባዊው ጫፍ ላይ ከፍ ካለው የድምፅ አዝራር ቀጥሎ ያለው ጠፍጣፋ አዝራር ነው።\n\nየማብሪያ/ማጥፊያ ቁልፉን መጫን ማያ ገጹን ያጠፋዋል።"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"የጣት አሻራ ዳሳሹ የማብሪያ/ማጥፊያ ቁልፉ ላይ ነው። በመሣሪያው ጫፍ ላይ ከፍ ካለው የድምፅ አዝራር ቀጥሎ ያለው ጠፍጣፋ አዝራር ነው።\n\nየማብሪያ/ማጥፊያ ቁልፉን መጫን ማያ ገጹን ያጠፋዋል።"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"የጣት አሻራ ዳሳሹ የማብሪያ/ማጥፊያ ቁልፉ ላይ ነው። በስልኩ ጫፍ ላይ ከፍ ካለው የድምፅ አዝራር ቀጥሎ ያለው ጠፍጣፋ አዝራር ነው።\n\nየማብሪያ/ማጥፊያ ቁልፉን መጫን ማያ ገጹን ያጠፋዋል።"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"የጣት አሻራ ዳሳሹ የማብሪያ/ማጥፊያ ቁልፉ ላይ ነው። በጡባዊው ጫፍ ላይ ከፍ ካለው የድምፅ አዝራር ቀጥሎ ያለው ጠፍጣፋ አዝራር ነው።"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"የጣት አሻራ ዳሳሹ የማብሪያ/ማጥፊያ ቁልፉ ላይ ነው። በመሣሪያው ጫፍ ላይ ከፍ ካለው የድምፅ አዝራር ቀጥሎ ያለው ጠፍጣፋ አዝራር ነው።"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"የጣት አሻራ ዳሳሹ የማብሪያ/ማጥፊያ ቁልፉ ላይ ነው። በስልኩ ጫፍ ላይ ከፍ ካለው የድምፅ አዝራር ቀጥሎ ያለው ጠፍጣፋ አዝራር ነው።"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ለተጨማሪ አማራጮች የእርስዎን ስልክ ይክፈቱ"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ለተጨማሪ አማራጮች የእርስዎን ጡባዊ ይክፈቱ"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ለተጨማሪ አማራጮች የእርስዎን መሣሪያ ይክፈቱ"</string>
diff --git a/packages/SystemUI/res-product/values-ar/strings.xml b/packages/SystemUI/res-product/values-ar/strings.xml
index 6955f20..1664d6f 100644
--- a/packages/SystemUI/res-product/values-ar/strings.xml
+++ b/packages/SystemUI/res-product/values-ar/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"أخطأت في محاولة فتح قفل الهاتف <xliff:g id="NUMBER">%d</xliff:g> مرة. ستتم إزالة الملف الشخصي للعمل، ومن ثم يتم حذف جميع بياناته."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستُطالَب بفتح قفل الجهاز اللوحي باستخدام معلومات حساب بريد إلكتروني.\n\n يُرجى إعادة المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"رسمت نقش فتح القفل بشكل غير صحيح <xliff:g id="NUMBER_0">%1$d</xliff:g> مرة. بعد إجراء <xliff:g id="NUMBER_1">%2$d</xliff:g> محاولة غير ناجحة أخرى، ستُطالَب بفتح قفل الهاتف باستخدام حساب بريد إلكتروني.\n\n يُرجى إعادة المحاولة خلال <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانية."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"توجد أداة استشعار بصمة الإصبع على زر التشغيل. زر التشغيل هو الزر المسطّح بجانب زرّي التحكم بمستوى الصوت البارزين في الجزء الجانبي من الجهاز اللوحي.\n\nيؤدي الضغط على زر التشغيل إلى إطفاء الشاشة."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"توجد أداة استشعار بصمة الإصبع على زر التشغيل. زر التشغيل هو الزر المسطّح بجانب زرّي التحكم بمستوى الصوت البارزين في الجزء الجانبي من الجهاز.\n\nيؤدي الضغط على زر التشغيل إلى إطفاء الشاشة."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"توجد أداة استشعار بصمة الإصبع على زر التشغيل. زر التشغيل هو الزر المسطّح بجانب زرّي التحكم بمستوى الصوت البارزين في الجزء الجانبي من الهاتف.\n\nيؤدي الضغط على زر التشغيل إلى إطفاء الشاشة."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"توجد أداة استشعار بصمة الإصبع على زر التشغيل. زر التشغيل هو الزر المسطّح بجانب زرَّي التحكّم بمستوى الصوت البارزَين في الجزء الجانبي من الجهاز اللوحي."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"توجد أداة استشعار بصمة الإصبع على زر التشغيل. زر التشغيل هو الزر المسطّح بجانب زرَّي التحكّم بمستوى الصوت البارزَين في الجزء الجانبي من الجهاز."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"توجد أداة استشعار بصمة الإصبع على زر التشغيل. زر التشغيل هو الزر المسطّح بجانب زرَّي التحكّم بمستوى الصوت البارزَين في الجزء الجانبي من الهاتف."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"يمكنك فتح قفل هاتفك للوصول إلى مزيد من الخيارات."</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"يمكنك فتح قفل جهازك اللوحي للوصول إلى مزيد من الخيارات."</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"يمكنك فتح قفل جهازك للوصول إلى مزيد من الخيارات."</string>
diff --git a/packages/SystemUI/res-product/values-as/strings.xml b/packages/SystemUI/res-product/values-as/strings.xml
index 687feae..05c69b8 100644
--- a/packages/SystemUI/res-product/values-as/strings.xml
+++ b/packages/SystemUI/res-product/values-as/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"আপুনি ফ’নটো আনলক কৰিবলৈ <xliff:g id="NUMBER">%d</xliff:g> বাৰ ভুলকৈ প্ৰয়াস কৰিছে। কৰ্মস্থানৰ প্ৰ’ফাইলটো আঁতৰোৱা হ’ব, যিয়ে প্ৰ’ফাইলটোৰ আটাইবোৰ ডেটা মচি পেলাব।"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"আপুনি নিজৰ আনলক কৰা আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুলকৈ প্ৰয়াস কৰাৰ পাছত আপোনাক নিজৰ টেবলেটটো এটা ইমেইল একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ’ব।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পাছত পুনৰ চেষ্টা কৰক।"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"আপুনি নিজৰ আনলক কৰা আৰ্হিটো <xliff:g id="NUMBER_0">%1$d</xliff:g> বাৰ ভুলকৈ আঁকিছে। আৰু <xliff:g id="NUMBER_1">%2$d</xliff:g> বাৰ ভুলকৈ প্ৰয়াস কৰাৰ পাছত আপোনাক নিজৰ ফ’নটো এটা ইমেইল একাউণ্টৰ জৰিয়তে আনলক কৰিবলৈ কোৱা হ’ব।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ছেকেণ্ডৰ পাছত পুনৰ চেষ্টা কৰক।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো পাৱাৰ বুটামটোত আছে। এইটো হৈছে টেবলেটটোৰ প্ৰান্তত থকা ভলিউম বঢ়োৱা বুটামটোৰ কাষত থকা সমতল বুটামটো।\n\nপাৱাৰ বুটাম টিপিলে স্ক্ৰীনখন অফ হৈ যায়।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো পাৱাৰ বুটামটোত আছে। এইটো হৈছে ডিভাইচটোৰ প্ৰান্তত থকা ভলিউম বঢ়োৱা বুটামটোৰ কাষত থকা সমতল বুটামটো।\n\nপাৱাৰ বুটাম টিপিলে স্ক্ৰীনখন অফ হৈ যায়।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো পাৱাৰ বুটামটোত আছে। এইটো হৈছে ফ’নটোৰ প্ৰান্তত থকা ভলিউম বঢ়োৱা বুটামটোৰ কাষত থকা সমতল বুটামটো।\n\nপাৱাৰ বুটাম টিপিলে স্ক্ৰীনখন অফ হৈ যায়।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো পাৱাৰ বুটামটোত আছে। এইটো হৈছে টেবলেটটোৰ প্ৰান্তত থকা উঠঙা ভলিউমৰ বুটামটোৰ কাষত থকা চেপেটা বুটামটো।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো পাৱাৰ বুটামটোত আছে। এইটো হৈছে ডিভাইচটোৰ প্ৰান্তত থকা উঠঙা ভলিউমৰ বুটামটোৰ কাষত থকা চেপেটা বুটামটো।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ফিংগাৰপ্ৰিণ্ট ছেন্সৰটো পাৱাৰ বুটামটোত আছে। এইটো হৈছে ফ’নটোৰ প্ৰান্তত থকা উঠঙা ভলিউমৰ বুটামটোৰ কাষত থকা চেপেটা বুটামটো।"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"অধিক বিকল্পৰ বাবে আপোনাৰ ফ’নটো আনলক কৰক"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"অধিক বিকল্পৰ বাবে আপোনাৰ টেবলেটটো আনলক কৰক"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"অধিক বিকল্পৰ বাবে আপোনাৰ ডিভাইচটো আনলক কৰক"</string>
diff --git a/packages/SystemUI/res-product/values-az/strings.xml b/packages/SystemUI/res-product/values-az/strings.xml
index 848b88d..3cc7d8c 100644
--- a/packages/SystemUI/res-product/values-az/strings.xml
+++ b/packages/SystemUI/res-product/values-az/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Telefonun kilidini açmaq üçün <xliff:g id="NUMBER">%d</xliff:g> dəfə yanlış cəhd etmisiniz. İş profili silinəcək və bütün data ləğv ediləcək."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Kilid açma modelini <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra planşet kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra cəhd edin."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Kilid açma modelini artıq <xliff:g id="NUMBER_0">%1$d</xliff:g> dəfə yanlış çəkmisiniz. Daha <xliff:g id="NUMBER_1">%2$d</xliff:g> uğursuz cəhddən sonra telefon kilidini e-poçt hesabınızla açmaq tələb olunacaq.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniyə sonra cəhd edin."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Barmaq izi sensoru enerji düyməsinin üzərindədir. Bu, planşetin kənarındakı qabarıq səs düyməsinin yanındakı yastı düymədir.\n\nEnerji düyməsini basdıqda ekran sönür."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Barmaq izi sensoru enerji düyməsinin üzərindədir. Bu, cihazın kənarındakı qabarıq səs düyməsinin yanındakı yastı düymədir.\n\nEnerji düyməsini basdıqda ekran sönür."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Barmaq izi sensoru enerji düyməsinin üzərindədir. Bu, telefonun kənarındakı qabarıq səs düyməsinin yanındakı yastı düymədir.\n\nEnerji düyməsini basdıqda ekran sönür."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Barmaq izi sensoru enerji düyməsinin üzərindədir. Bu, planşetin kənarındakı qabarıq səs düyməsinin yanındakı yastı düymədir."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Barmaq izi sensoru enerji düyməsinin üzərindədir. Bu, cihazın kənarındakı qabarıq səs düyməsinin yanındakı yastı düymədir."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Barmaq izi sensoru enerji düyməsinin üzərindədir. Bu, telefonun kənarındakı qabarıq səs düyməsinin yanındakı yastı düymədir."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Daha çox seçim üçün telefonu kiliddən çıxarın"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Daha çox seçim üçün planşeti kiliddən çıxarın"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Daha çox seçim üçün cihazı kiliddən çıxarın"</string>
diff --git a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
index 6d480bf..07d8c94 100644
--- a/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res-product/values-b+sr+Latn/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Pogrešno ste pokušali da otključate telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Uklonićemo poslovni profil, čime se brišu svi podaci sa profila."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate tablet pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Netačno ste nacrtali šablon za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. Ako pogrešno pokušate još <xliff:g id="NUMBER_1">%2$d</xliff:g> puta, zatražićemo da otključate telefon pomoću imejl naloga.\n\n Probajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Senzor za otisak prsta se nalazi na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na ivici tableta.\n\nPritiskom na dugme za uključivanje isključuje se ekran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Senzor za otisak prsta se nalazi na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na ivici uređaja.\n\nPritiskom na dugme za uključivanje isključuje se ekran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Senzor za otisak prsta se nalazi na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na ivici telefona.\n\nPritiskom na dugme za uključivanje isključuje se ekran."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzor za otisak prsta se nalazi na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na ivici tableta."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzor za otisak prsta se nalazi na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na ivici uređaja."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzor za otisak prsta se nalazi na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na ivici telefona."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Otključajte telefon za još opcija"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Otključajte tablet za još opcija"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Otključajte uređaj za još opcija"</string>
diff --git a/packages/SystemUI/res-product/values-be/strings.xml b/packages/SystemUI/res-product/values-be/strings.xml
index 132a605..e9c491a 100644
--- a/packages/SystemUI/res-product/values-be/strings.xml
+++ b/packages/SystemUI/res-product/values-be/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Вы не змаглі разблакіраваць тэлефон столькі разоў: <xliff:g id="NUMBER">%d</xliff:g>. Працоўны профіль будзе выдалены, і гэта прывядзе да выдалення ўсіх даных у профілі."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) вам будзе прапанавана разблакіраваць планшэт, увайшоўшы ва ўліковы запіс электроннай пошты.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Вы няправільна ўвялі ўзор разблакіроўкі столькі разоў: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Пасля яшчэ некалькіх няўдалых спроб (<xliff:g id="NUMBER_1">%2$d</xliff:g>) вам будзе прапанавана разблакіраваць тэлефон, увайшоўшы ва ўліковы запіс электроннай пошты.\n\n Паўтарыце спробу праз <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Сканер адбіткаў пальцаў знаходзіцца на кнопцы сілкавання. Гэта плоская кнопка побач з выпуклай кнопкай гучнасці на бакавой грані планшэта.\n\nНацісканне кнопкі сілкавання выключае экран."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Сканер адбіткаў пальцаў знаходзіцца на кнопцы сілкавання. Гэта плоская кнопка побач з выпуклай кнопкай гучнасці на бакавой грані прылады.\n\nНацісканне кнопкі сілкавання выключае экран."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Сканер адбіткаў пальцаў знаходзіцца на кнопцы сілкавання. Гэта плоская кнопка побач з выпуклай кнопкай гучнасці на бакавой грані тэлефона.\n\nНацісканне кнопкі сілкавання выключае экран."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сканер адбіткаў пальцаў знаходзіцца на кнопцы сілкавання. Гэта плоская кнопка побач з выпуклай кнопкай гучнасці на бакавой грані планшэта."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сканер адбіткаў пальцаў знаходзіцца на кнопцы сілкавання. Гэта плоская кнопка побач з выпуклай кнопкай гучнасці на бакавой грані прылады."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сканер адбіткаў пальцаў знаходзіцца на кнопцы сілкавання. Гэта плоская кнопка побач з выпуклай кнопкай гучнасці на бакавой грані тэлефона."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Каб адкрыць іншыя параметры, разблакіруйце тэлефон"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Каб адкрыць іншыя параметры, разблакіруйце планшэт"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Каб адкрыць іншыя параметры, разблакіруйце прыладу"</string>
diff --git a/packages/SystemUI/res-product/values-bg/strings.xml b/packages/SystemUI/res-product/values-bg/strings.xml
index 586f156..3542558 100644
--- a/packages/SystemUI/res-product/values-bg/strings.xml
+++ b/packages/SystemUI/res-product/values-bg/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Опитахте да отключите телефона и сбъркахте <xliff:g id="NUMBER">%d</xliff:g> пъти. Служебният потребителски профил ще бъде премахнат, при което ще се изтрият всички данни за него."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита ще бъдете помолени да отключите таблета си посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Начертахте неправилно фигурата си за отключване <xliff:g id="NUMBER_0">%1$d</xliff:g> пъти. След още <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни опита ще бъдете помолени да отключите телефона посредством имейл адрес.\n\n Опитайте отново след <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Сензорът за отпечатъци се намира върху бутона за захранване. Този бутон е плосък и е разположен на ръба на таблета до повдигнатия бутон за силата на звука.\n\nС натискането на бутона за захранване се изключва екранът."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Сензорът за отпечатъци се намира върху бутона за захранване. Този бутон е плосък и е разположен на ръба на устройството до повдигнатия бутон за силата на звука.\n\nС натискането на бутона за захранване се изключва екранът."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Сензорът за отпечатъци се намира върху бутона за захранване. Този бутон е плосък и е разположен на ръба на телефона до повдигнатия бутон за силата на звука.\n\nС натискането на бутона за захранване се изключва екранът."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сензорът за отпечатъци се намира върху бутона за захранване. Този бутон е плосък и е разположен на ръба на таблета до повдигнатия бутон за силата на звука."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сензорът за отпечатъци се намира върху бутона за захранване. Този бутон е плосък и е разположен на ръба на устройството до повдигнатия бутон за силата на звука."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сензорът за отпечатъци се намира върху бутона за захранване. Този бутон е плосък и е разположен на ръба на телефона до повдигнатия бутон за силата на звука."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Отключете телефона си за още опции"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Отключете таблета си за още опции"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Отключете устройството си за още опции"</string>
diff --git a/packages/SystemUI/res-product/values-bn/strings.xml b/packages/SystemUI/res-product/values-bn/strings.xml
index 322fb63..0984de2 100644
--- a/packages/SystemUI/res-product/values-bn/strings.xml
+++ b/packages/SystemUI/res-product/values-bn/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"আপনি <xliff:g id="NUMBER">%d</xliff:g> বার ভুল পদ্ধতিতে ফোন আনলক করার চেষ্টা করেছেন। অফিস প্রোফাইলটি সরিয়ে দেওয়া হবে, যার ফলে প্রোফাইলের সমস্ত ডেটা মুছে যাবে।"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল পদ্ধতিতে প্যাটার্ন আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার এটি করলে আপনাকে প্যাটার্ন আনলক করতে একটি ইমেল অ্যাকাউন্ট ব্যবহার করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন।"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"আপনি <xliff:g id="NUMBER_0">%1$d</xliff:g> বার ভুল পদ্ধতিতে প্যাটার্ন আনলক করার চেষ্টা করেছেন। আরও <xliff:g id="NUMBER_1">%2$d</xliff:g> বার এটি করলে আপনাকে প্যাটার্ন আনলক করতে একটি ইমেল অ্যাকাউন্ট ব্যবহারের করতে বলা হবে।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> সেকেন্ড পরে আবার চেষ্টা করুন।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"\'পাওয়ার\' বোতামের উপরে ফিঙ্গারপ্রিন্ট সেন্সর আছে। এটি ট্যাবলেটের প্রান্তে উঁচু \'ভলিউম\' বোতামের পাশে থাকা চ্যাপ্টা বোতাম।\n\n\'পাওয়ার\' বোতাম প্রেস করলে স্ক্রিন বন্ধ হয়ে যায়।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"\'পাওয়ার\' বোতামের উপরে ফিঙ্গারপ্রিন্ট সেন্সর আছে। এটি ডিভাইসের প্রান্তে উঁচু \'ভলিউম\' বোতামের পাশে থাকা চ্যাপ্টা বোতাম।\n\n\'পাওয়ার\' বোতাম প্রেস করলে স্ক্রিন বন্ধ হয়ে যায়।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"\'পাওয়ার\' বোতামের উপরে ফিঙ্গারপ্রিন্ট সেন্সর আছে। এটি ফোনের প্রান্তে উঁচু \'ভলিউম\' বোতামের পাশে থাকা চ্যাপ্টা বোতাম।\n\n\'পাওয়ার\' বোতাম প্রেস করলে স্ক্রিন বন্ধ হয়ে যায়।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"\'পাওয়ার\' বোতামের উপরে ফিঙ্গারপ্রিন্ট সেন্সর দেওয়া হয়েছে। ট্যাবলেটের প্রান্তে একটু বাইরে বেরিয়ে থাকা ভলিউমের বোতামের ঠিক পাশে এই ফ্ল্যাট বোতামটি আপনি খুঁজে পাবেন।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"\'পাওয়ার\' বোতামের উপরে ফিঙ্গারপ্রিন্ট সেন্সর দেওয়া হয়েছে। ডিভাইসের সাইডে একটু বাইরে বেরিয়ে থাকা ভলিউমের বোতামের ঠিক পাশে এই ফ্ল্যাট বোতামটি আপনি খুঁজে পাবেন।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"\'পাওয়ার\' বোতামের উপরে ফিঙ্গারপ্রিন্ট সেন্সর দেওয়া হয়েছে। ফোনের প্রান্তে একটু বাইরে বেরিয়ে থাকা ভলিউমের বোতামের ঠিক পাশে এই ফ্ল্যাট বোতামটি আপনি খুঁজে পাবেন।"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"আরও বিকল্প দেখতে আপনার ফোন আনলক করুন"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"আরও বিকল্প দেখতে আপনার ট্যাবলেট আনলক করুন"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"আরও বিকল্প দেখতে আপনার ডিভাইস আনলক করুন"</string>
diff --git a/packages/SystemUI/res-product/values-bs/strings.xml b/packages/SystemUI/res-product/values-bs/strings.xml
index ac1771f..576fac4 100644
--- a/packages/SystemUI/res-product/values-bs/strings.xml
+++ b/packages/SystemUI/res-product/values-bs/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Pokušali ste neispravno otključati telefon <xliff:g id="NUMBER">%d</xliff:g> puta. Radni profil će se ukloniti i svi podaci s profila će se izbrisati."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da otključate tablet pomoću računa e-pošte. \n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Pogrešno ste nacrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> puta. U slučaju još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja bez uspjeha, od vas će se tražiti da otključate telefon pomoću računa e-pošte. \n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Senzor za otisak prsta je na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na rubu tableta.\n\nPritiskanjem dugmeta za uključivanje isključuje se ekran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Senzor za otisak prsta je na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na rubu uređaja.\n\nPritiskanjem dugmeta za uključivanje isključuje se ekran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Senzor za otisak prsta je na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na rubu telefona.\n\nPritiskanjem dugmeta za uključivanje isključuje se ekran."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzor za otisak prsta je na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na rubu tableta."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzor za otisak prsta je na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na rubu uređaja."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzor za otisak prsta je na dugmetu za uključivanje. To je ravno dugme pored izdignutog dugmeta za jačinu zvuka na rubu telefona."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Otključajte telefon za više opcija"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Otključajte tablet za više opcija"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Otključajte uređaj za više opcija"</string>
diff --git a/packages/SystemUI/res-product/values-ca/strings.xml b/packages/SystemUI/res-product/values-ca/strings.xml
index 9b5469a..d8d4a47 100644
--- a/packages/SystemUI/res-product/values-ca/strings.xml
+++ b/packages/SystemUI/res-product/values-ca/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Has provat de desbloquejar el telèfon <xliff:g id="NUMBER">%d</xliff:g> vegades de manera incorrecta. El perfil de treball se suprimirà, juntament amb totes les dades que contingui."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis la tauleta amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Has dibuixat el patró de desbloqueig <xliff:g id="NUMBER_0">%1$d</xliff:g> vegades de manera incorrecta. Si falles <xliff:g id="NUMBER_1">%2$d</xliff:g> vegades més, se\'t demanarà que desbloquegis el telèfon amb un compte de correu electrònic.\n\n Torna-ho a provar d\'aquí a <xliff:g id="NUMBER_2">%3$d</xliff:g> segons."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"El sensor d\'empremtes digitals es troba al botó d\'engegada. És el botó pla situat al costat del botó de volum amb relleu al lateral de la tauleta.\n\nEn prémer el botó d\'engegada, la pantalla es desactiva."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"El sensor d\'empremtes digitals es troba al botó d\'engegada. És el botó pla situat al costat del botó de volum amb relleu al lateral del dispositiu.\n\nEn prémer el botó d\'engegada, la pantalla es desactiva."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"El sensor d\'empremtes digitals es troba al botó d\'engegada. És el botó pla situat al costat del botó de volum amb relleu al lateral del telèfon.\n\nEn prémer el botó d\'engegada, la pantalla es desactiva."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"El sensor d\'empremtes digitals es troba al botó d\'engegada. És el botó pla situat al costat del botó de volum amb relleu al lateral de la tauleta."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"El sensor d\'empremtes digitals es troba al botó d\'engegada. És el botó pla situat al costat del botó de volum amb relleu al lateral del dispositiu."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"El sensor d\'empremtes digitals es troba al botó d\'engegada. És el botó pla situat al costat del botó de volum amb relleu al lateral del telèfon."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueja el teu telèfon per veure més opcions"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueja la teva tauleta per veure més opcions"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueja el teu dispositiu per veure més opcions"</string>
diff --git a/packages/SystemUI/res-product/values-cs/strings.xml b/packages/SystemUI/res-product/values-cs/strings.xml
index a1c1691..47881bd 100644
--- a/packages/SystemUI/res-product/values-cs/strings.xml
+++ b/packages/SystemUI/res-product/values-cs/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Již <xliff:g id="NUMBER">%d</xliff:g>krát jste se pokusili odemknout telefon nesprávným způsobem. Pracovní profil bude odstraněn, čímž budou smazána všechna jeho data."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali své bezpečnostní gesto. Po <xliff:g id="NUMBER_1">%2$d</xliff:g>dalších neúspěšných pokusech budete požádáni o odemčení tabletu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Již <xliff:g id="NUMBER_0">%1$d</xliff:g>krát jste nesprávně zadali své bezpečnostní gesto. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> dalších neúspěšných pokusech budete požádáni o odemčení telefonu pomocí e-mailového účtu.\n\n Zkuste to znovu za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Snímač otisků prstů je na vypínači. Je to ploché tlačítko vedle vystouplého tlačítka hlasitosti na hraně tabletu.\n\nStisknutím vypínače vypnete obrazovku."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Snímač otisků prstů je na vypínači. Je to ploché tlačítko vedle vystouplého tlačítka hlasitosti na hraně zařízení.\n\nStisknutím vypínače vypnete obrazovku."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Snímač otisků prstů je na vypínači. Je to ploché tlačítko vedle vystouplého tlačítka hlasitosti na hraně telefonu.\n\nStisknutím vypínače vypnete obrazovku."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Snímač otisků prstů je na vypínači. Je to ploché tlačítko vedle vystouplého tlačítka hlasitosti na hraně tabletu."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Snímač otisků prstů je na vypínači. Je to ploché tlačítko vedle vystouplého tlačítka hlasitosti na hraně zařízení."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Snímač otisků prstů je na vypínači. Je to ploché tlačítko vedle vystouplého tlačítka hlasitosti na hraně telefonu."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Chcete-li zobrazit další možnosti, odemkněte telefon"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Chcete-li zobrazit další možnosti, odemkněte tablet"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Chcete-li zobrazit další možnosti, odemkněte zařízení"</string>
diff --git a/packages/SystemUI/res-product/values-da/strings.xml b/packages/SystemUI/res-product/values-da/strings.xml
index 87e1c5e..47531e7 100644
--- a/packages/SystemUI/res-product/values-da/strings.xml
+++ b/packages/SystemUI/res-product/values-da/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Du har forsøgt at låse telefonen op med den forkerte adgangskode <xliff:g id="NUMBER">%d</xliff:g> gange. Arbejdsprofilen fjernes, hvilket sletter alle profildata."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg bliver du bedt om at låse din tablet op ved hjælp af en mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Du har tegnet dit oplåsningsmønster forkert <xliff:g id="NUMBER_0">%1$d</xliff:g> gange. Efter endnu <xliff:g id="NUMBER_1">%2$d</xliff:g> mislykkede forsøg bliver du bedt om at låse din telefon op ved hjælp af en mailkonto.\n\n Prøv igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Fingeraftrykssensoren sidder på afbryderknappen. Det er den flade knap ud for den hævede lydstyrkeknap på din tablets kant.\n\nNår du trykker på afbryderknappen, slukkes skærmen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Fingeraftrykssensoren sidder på afbryderknappen. Det er den flade knap ud for den hævede lydstyrkeknap på enhedens kant.\n\nNår du trykker på afbryderknappen, slukkes skærmen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Fingeraftrykssensoren sidder på afbryderknappen. Det er den flade knap ud for den hævede lydstyrkeknap på telefonens kant.\n\nNår du trykker på afbryderknappen, slukkes skærmen."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Fingeraftrykssensoren sidder på afbryderknappen. Det er den flade knap ved siden af den hævede lydstyrkeknap på siden af din tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Fingeraftrykssensoren sidder på afbryderknappen. Det er den flade knap ved siden af den hævede lydstyrkeknap på siden af enheden."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Fingeraftrykssensoren sidder på afbryderknappen. Det er den flade knap ved siden af den hævede lydstyrkeknap på siden af telefonen."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Lås din telefon op for at se flere valgmuligheder"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Lås din tablet op for at se flere valgmuligheder"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Lås din enhed op for at se flere valgmuligheder"</string>
diff --git a/packages/SystemUI/res-product/values-de/strings.xml b/packages/SystemUI/res-product/values-de/strings.xml
index e0683eb..9c0b768 100644
--- a/packages/SystemUI/res-product/values-de/strings.xml
+++ b/packages/SystemUI/res-product/values-de/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Du hast <xliff:g id="NUMBER">%d</xliff:g>-mal erfolglos versucht, das Smartphone zu entsperren. Das Arbeitsprofil wird nun entfernt und alle Profildaten werden gelöscht."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Tablet mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Du hast dein Entsperrungsmuster <xliff:g id="NUMBER_0">%1$d</xliff:g>-mal falsch gezeichnet. Nach <xliff:g id="NUMBER_1">%2$d</xliff:g> weiteren erfolglosen Versuchen wirst du aufgefordert, dein Smartphone mithilfe eines E-Mail-Kontos zu entsperren.\n\n Versuche es in <xliff:g id="NUMBER_2">%3$d</xliff:g> Sekunden noch einmal."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Der Fingerabdrucksensor befindet sich auf der Ein-/Aus-Taste. Das ist die flache Taste neben der erhöhten Lautstärketaste an der Seite des Tablets.\n\nWenn du die Ein-/Aus-Taste drückst, schaltet sich das Display aus."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Der Fingerabdrucksensor befindet sich auf der Ein-/Aus-Taste. Das ist die flache Taste neben der erhöhten Lautstärketaste an der Seite des Geräts.\n\nWenn du die Ein-/Aus-Taste drückst, schaltet sich das Display aus."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Der Fingerabdrucksensor befindet sich auf der Ein-/Aus-Taste. Das ist die flache Taste neben der erhöhten Lautstärketaste an der Seite des Smartphones.\n\nWenn du die Ein-/Aus-Taste drückst, schaltet sich das Display aus."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Der Fingerabdrucksensor befindet sich auf der Ein-/Aus-Taste. Das ist die flache Taste neben der erhöhten Lautstärketaste am Rand des Tablets."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Der Fingerabdrucksensor befindet sich auf der Ein-/Aus-Taste. Das ist die flache Taste neben der erhöhten Lautstärketaste am Rand des Geräts."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Der Fingerabdrucksensor befindet sich auf der Ein-/Aus-Taste. Das ist die flache Taste neben der erhöhten Lautstärketaste am Rand des Smartphones."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Entsperre dein Smartphone für weitere Optionen"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Entsperre dein Tablet für weitere Optionen"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Entsperre dein Gerät für weitere Optionen"</string>
diff --git a/packages/SystemUI/res-product/values-el/strings.xml b/packages/SystemUI/res-product/values-el/strings.xml
index 5b571d8..139fa04 100644
--- a/packages/SystemUI/res-product/values-el/strings.xml
+++ b/packages/SystemUI/res-product/values-el/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Δοκιμάσατε να ξεκλειδώσετε το τηλέφωνο <xliff:g id="NUMBER">%d</xliff:g> φορές χωρίς επιτυχία. Το προφίλ εργασίας θα καταργηθεί και θα διαγραφούν όλα τα δεδομένα προφίλ."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε το tablet με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε να συνδεθείτε ξανά σε <xliff:g id="NUMBER_2">%3$d</xliff:g> δευτερόλεπτα."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Σχεδιάσατε το μοτίβο ξεκλειδώματος εσφαλμένα <xliff:g id="NUMBER_0">%1$d</xliff:g> φορές. Μετά από <xliff:g id="NUMBER_1">%2$d</xliff:g> ακόμα ανεπιτυχείς προσπάθειες, θα σας ζητηθεί να ξεκλειδώσετε το τηλέφωνό σας με τη χρήση ενός λογαριασμού ηλεκτρονικού ταχυδρομείου.\n\n Δοκιμάστε ξανά σε <xliff:g id="NUMBER_2">%3$d</xliff:g> δευτερόλεπτα."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Ο αισθητήρας δακτυλικών αποτυπωμάτων βρίσκεται στο κουμπί λειτουργίας. Είναι το επίπεδο κουμπί δίπλα στο ανυψωμένο κουμπί έντασης ήχου στο άκρο του tablet.\n\nΜε πάτημα του κουμπιού λειτουργίας απενεργοποιείται η οθόνη."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Ο αισθητήρας δακτυλικών αποτυπωμάτων βρίσκεται στο κουμπί λειτουργίας. Είναι το επίπεδο κουμπί δίπλα στο ανυψωμένο κουμπί έντασης ήχου στο άκρο της συσκευής.\n\nΜε πάτημα του κουμπιού λειτουργίας απενεργοποιείται η οθόνη."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Ο αισθητήρας δακτυλικών αποτυπωμάτων βρίσκεται στο κουμπί λειτουργίας. Είναι το επίπεδο κουμπί δίπλα στο ανυψωμένο κουμπί έντασης ήχου στο άκρο του τηλεφώνου.\n\nΜε πάτημα του κουμπιού λειτουργίας απενεργοποιείται η οθόνη."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Ο αισθητήρας δακτυλικών αποτυπωμάτων βρίσκεται στο κουμπί λειτουργίας. Είναι το επίπεδο κουμπί δίπλα στο ανυψωμένο κουμπί έντασης ήχου στο άκρο του tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Ο αισθητήρας δακτυλικών αποτυπωμάτων βρίσκεται στο κουμπί λειτουργίας. Είναι το επίπεδο κουμπί δίπλα στο ανυψωμένο κουμπί έντασης ήχου στο άκρο της συσκευής."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Ο αισθητήρας δακτυλικών αποτυπωμάτων βρίσκεται στο κουμπί λειτουργίας. Είναι το επίπεδο κουμπί δίπλα στο ανυψωμένο κουμπί έντασης ήχου στο άκρο του τηλεφώνου."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ξεκλειδώστε το τηλέφωνό σας για περισσότερες επιλογές"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ξεκλειδώστε το tablet για περισσότερες επιλογές"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ξεκλειδώστε τη συσκευή σας για περισσότερες επιλογές"</string>
diff --git a/packages/SystemUI/res-product/values-en-rAU/strings.xml b/packages/SystemUI/res-product/values-en-rAU/strings.xml
index 46c1dc5..6356fc2 100644
--- a/packages/SystemUI/res-product/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rAU/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone.\n\nPressing the power button turns off the screen."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string>
diff --git a/packages/SystemUI/res-product/values-en-rCA/strings.xml b/packages/SystemUI/res-product/values-en-rCA/strings.xml
index 37d1000..df65336 100644
--- a/packages/SystemUI/res-product/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rCA/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone.\n\nPressing the power button turns off the screen."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string>
diff --git a/packages/SystemUI/res-product/values-en-rGB/strings.xml b/packages/SystemUI/res-product/values-en-rGB/strings.xml
index 46c1dc5..6356fc2 100644
--- a/packages/SystemUI/res-product/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rGB/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone.\n\nPressing the power button turns off the screen."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string>
diff --git a/packages/SystemUI/res-product/values-en-rIN/strings.xml b/packages/SystemUI/res-product/values-en-rIN/strings.xml
index 46c1dc5..6356fc2 100644
--- a/packages/SystemUI/res-product/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rIN/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone.\n\nPressing the power button turns off the screen."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string>
diff --git a/packages/SystemUI/res-product/values-en-rXC/strings.xml b/packages/SystemUI/res-product/values-en-rXC/strings.xml
index 141ec04..4a7d0ad 100644
--- a/packages/SystemUI/res-product/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res-product/values-en-rXC/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"You have incorrectly attempted to unlock the phone <xliff:g id="NUMBER">%d</xliff:g> times. The work profile will be removed, which will delete all profile data."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your tablet using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"You have incorrectly drawn your unlock pattern <xliff:g id="NUMBER_0">%1$d</xliff:g> times. After <xliff:g id="NUMBER_1">%2$d</xliff:g> more unsuccessful attempts, you will be asked to unlock your phone using an email account.\n\n Try again in <xliff:g id="NUMBER_2">%3$d</xliff:g> seconds."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device.\n\nPressing the power button turns off the screen."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone.\n\nPressing the power button turns off the screen."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the device."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"The fingerprint sensor is on the power button. It’s the flat button next to the raised volume button on the edge of the phone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Unlock your phone for more options"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Unlock your tablet for more options"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Unlock your device for more options"</string>
diff --git a/packages/SystemUI/res-product/values-es-rUS/strings.xml b/packages/SystemUI/res-product/values-es-rUS/strings.xml
index 4364a6f..3a22304 100644
--- a/packages/SystemUI/res-product/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res-product/values-es-rUS/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Intentaste desbloquear el teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de manera incorrecta. Se quitará el perfil de trabajo, lo que borrará todos los datos asociados."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Dibujaste el patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees la tablet mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Dibujaste el patrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de manera incorrecta. Después de <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te solicitará que desbloquees el dispositivo mediante una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"El sensor de huellas dactilares está en el botón de encendido. Es el botón plano que está junto al botón de volumen en relieve, en el borde de la tablet.\n\nSi presionas el botón de encendido, se apaga la pantalla."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"El sensor de huellas dactilares está en el botón de encendido. Es el botón plano que está junto al botón de volumen en relieve, en el borde del dispositivo.\n\nSi presionas el botón de encendido, se apaga la pantalla."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"El sensor de huellas dactilares está en el botón de encendido. Es el botón plano que está junto al botón de volumen en relieve, en el borde del teléfono.\n\nSi presionas el botón de encendido, se apaga la pantalla."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"El sensor de huellas dactilares está en el botón de encendido. Es el botón plano que está junto al botón de volumen en relieve, en el borde de la tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"El sensor de huellas dactilares está en el botón de encendido. Es el botón plano que está junto al botón de volumen en relieve, en el borde del dispositivo."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"El sensor de huellas dactilares está en el botón de encendido. Es el botón plano que está junto al botón de volumen en relieve, en el borde del teléfono."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloquea el teléfono para ver más opciones"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloquea la tablet para ver más opciones"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloquea el dispositivo para ver más opciones"</string>
diff --git a/packages/SystemUI/res-product/values-es/strings.xml b/packages/SystemUI/res-product/values-es/strings.xml
index 2e6a2ae..84ebe29 100644
--- a/packages/SystemUI/res-product/values-es/strings.xml
+++ b/packages/SystemUI/res-product/values-es/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Has intentado desbloquear el teléfono de forma incorrecta <xliff:g id="NUMBER">%d</xliff:g> veces. Se quitará este perfil de trabajo y se eliminarán todos sus datos."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Has dibujado un patrón de desbloqueo incorrecto <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te pedirá que desbloquees el tablet con una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Has dibujado un patrón de desbloqueo incorrecto <xliff:g id="NUMBER_0">%1$d</xliff:g> veces. Si se producen <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos más, se te pedirá que desbloquees el teléfono con una cuenta de correo electrónico.\n\n Vuelve a intentarlo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"El sensor de huellas digitales está en el botón de encendido. Es el botón plano situado junto al botón de volumen con relieve en el lateral del tablet.\n\nAl pulsar el botón de encendido, se apagará la pantalla."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"El sensor de huellas digitales está en el botón de encendido. Es el botón plano situado junto al botón de volumen con relieve en el lateral del dispositivo.\n\nAl pulsar el botón de encendido, se apagará la pantalla."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"El sensor de huellas digitales está en el botón de encendido. Es el botón plano situado junto al botón de volumen con relieve en el lateral del teléfono.\n\nAl pulsar el botón de encendido, se apagará la pantalla."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"El sensor de huellas digitales está en el botón de encendido. Es el botón plano situado junto al botón de volumen con relieve en el lateral de la tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"El sensor de huellas digitales está en el botón de encendido. Es el botón plano situado junto al botón de volumen con relieve en el lateral del dispositivo."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"El sensor de huellas digitales está en el botón de encendido. Es el botón plano situado junto al botón de volumen con relieve en el lateral del teléfono."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloquea el teléfono para ver más opciones"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloquea el tablet para ver más opciones"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloquea el dispositivo para ver más opciones"</string>
diff --git a/packages/SystemUI/res-product/values-et/strings.xml b/packages/SystemUI/res-product/values-et/strings.xml
index 5abd1ca..4d8af24 100644
--- a/packages/SystemUI/res-product/values-et/strings.xml
+++ b/packages/SystemUI/res-product/values-et/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Olete püüdnud <xliff:g id="NUMBER">%d</xliff:g> korda telefoni valesti avada. Tööprofiil eemaldatakse ja kõik profiiliandmed kustutatakse."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil tahvelarvuti avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Joonistasite oma avamismustri <xliff:g id="NUMBER_0">%1$d</xliff:g> korda valesti. Pärast veel <xliff:g id="NUMBER_1">%2$d</xliff:g> ebaõnnestunud katset palutakse teil telefon avada meilikontoga.\n\n Proovige uuesti <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundi pärast."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Sõrmejäljeandur asub toitenupul. See on tahvelarvuti küljel helitugevuse kõrgendatud nupu kõrval olev lame nupp.\n\nToitenupu vajutamisel lülitatakse ekraan välja."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Sõrmejäljeandur asub toitenupul. See on seadme küljel helitugevuse kõrgendatud nupu kõrval olev lame nupp.\n\nToitenupu vajutamisel lülitatakse ekraan välja."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Sõrmejäljeandur asub toitenupul. See on telefoni küljel helitugevuse kõrgendatud nupu kõrval olev lame nupp.\n\nToitenupu vajutamisel lülitatakse ekraan välja."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Sõrmejäljeandur asub toitenupul. See on tahvelarvuti küljel helitugevuse kõrgendatud nupu kõrval olev lame nupp."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Sõrmejäljeandur asub toitenupul. See on seadme küljel helitugevuse kõrgendatud nupu kõrval olev lame nupp."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Sõrmejäljeandur asub toitenupul. See on telefoni küljel helitugevuse kõrgendatud nupu kõrval olev lame nupp."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Lisavalikute nägemiseks avage oma telefon"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Lisavalikute nägemiseks avage oma tahvelarvuti"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Lisavalikute nägemiseks avage oma seade"</string>
diff --git a/packages/SystemUI/res-product/values-eu/strings.xml b/packages/SystemUI/res-product/values-eu/strings.xml
index 6d67390..dcb1ead 100644
--- a/packages/SystemUI/res-product/values-eu/strings.xml
+++ b/packages/SystemUI/res-product/values-eu/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> aldiz saiatu zara telefonoa desblokeatzen, baina huts egin duzu denetan. Laneko profila kendu egingo da eta, ondorioz, profileko datu guztiak ezabatuko dira."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz oker marrazten baduzu, tableta posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Desblokeatzeko eredua oker marraztu duzu <xliff:g id="NUMBER_0">%1$d</xliff:g> aldiz. Beste <xliff:g id="NUMBER_1">%2$d</xliff:g> aldiz oker marrazten baduzu, telefonoa posta-kontu baten bidez desblokeatzeko eskatuko dizugu.\n\n Saiatu berriro <xliff:g id="NUMBER_2">%3$d</xliff:g> segundo barru."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Hatz-marken sentsorea etengailuan dago. Tabletaren ertzeko bolumen-botoi goratuaren ondoan dagoen botoi laua da.\n\nEtengailua sakatuz gero, pantaila itzaliko da."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Hatz-marken sentsorea etengailuan dago. Gailuaren ertzeko bolumen-botoi goratuaren ondoan dagoen botoi laua da.\n\nEtengailua sakatuz gero, pantaila itzaliko da."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Hatz-marken sentsorea etengailuan dago. Telefonoaren ertzeko bolumen-botoi goratuaren ondoan dagoen botoi laua da.\n\nEtengailua sakatuz gero, pantaila itzaliko da."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Hatz-marken sentsorea etengailuan dago. Tabletaren ertzeko bolumen-botoi goratuaren ondoan dagoen botoi laua da."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Hatz-marken sentsorea etengailuan dago. Gailuaren ertzeko bolumen-botoi goratuaren ondoan dagoen botoi laua da."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Hatz-marken sentsorea etengailuan dago. Telefonoaren ertzeko bolumen-botoi goratuaren ondoan dagoen botoi laua da."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desblokeatu telefonoa aukera gehiago ikusteko"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desblokeatu tableta aukera gehiago ikusteko"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desblokeatu gailua aukera gehiago ikusteko"</string>
diff --git a/packages/SystemUI/res-product/values-fa/strings.xml b/packages/SystemUI/res-product/values-fa/strings.xml
index 62efff0..a861261 100644
--- a/packages/SystemUI/res-product/values-fa/strings.xml
+++ b/packages/SystemUI/res-product/values-fa/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> تلاش ناموفق برای باز کردن قفل تلفن داشتهاید. نمایه کاری پاک میشود که با آن همه دادههای نمایه حذف میشود."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. بعداز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که بااستفاده از یک حساب ایمیل قفل رایانه لوحیتان را باز کنید.\n\n لطفاً پساز <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"الگوی بازگشایی قفل را <xliff:g id="NUMBER_0">%1$d</xliff:g> بار اشتباه کشیدهاید. پساز <xliff:g id="NUMBER_1">%2$d</xliff:g> تلاش ناموفق، از شما خواسته میشود که بااستفاده از یک حساب ایمیل قفل تلفن را باز کنید.\n\n لطفاً پساز <xliff:g id="NUMBER_2">%3$d</xliff:g> ثانیه دوباره امتحان کنید."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"حسگر اثر انگشت روی دکمه روشن/خاموش قرار دارد. این همان دکمه مسطحی است که کنار دکمه برآمده صدا در لبه رایانه لوحی قرار دارد.\n\nفشار دادن دکمه روشن/خاموش، صفحهنمایش را خاموش میکند."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"حسگر اثر انگشت روی دکمه روشن/خاموش قرار دارد. این همان دکمه مسطحی است که کنار دکمه برآمده صدا در لبه دستگاه قرار دارد.\n\nفشار دادن دکمه روشن/خاموش، صفحهنمایش را خاموش میکند."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"حسگر اثر انگشت روی دکمه روشن/خاموش قرار دارد. این همان دکمه مسطحی است که کنار دکمه برآمده صدا در لبه تلفن قرار دارد.\n\nفشار دادن دکمه روشن/خاموش، صفحهنمایش را خاموش میکند."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"حسگر اثر انگشت روی دکمه روشن/خاموش قرار دارد. این همان دکمه مسطحی است که در کنار دکمه برآمده صدا در لبه رایانه لوحی قرار دارد."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"حسگر اثر انگشت روی دکمه روشن/خاموش قرار دارد. این همان دکمه مسطحی است که در کنار دکمه برآمده صدا در لبه دستگاه قرار دارد."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"حسگر اثر انگشت روی دکمه روشن/خاموش قرار دارد. این همان دکمه مسطحی است که در کنار دکمه برآمده صدا در لبه تلفن قرار دارد."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"برای گزینههای بیشتر، قفل تلفن را باز کنید"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"برای گزینههای بیشتر، قفل رایانه لوحی را باز کنید"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"برای گزینههای بیشتر، قفل دستگاه را باز کنید"</string>
diff --git a/packages/SystemUI/res-product/values-fi/strings.xml b/packages/SystemUI/res-product/values-fi/strings.xml
index da3592dd..c6db4fe 100644
--- a/packages/SystemUI/res-product/values-fi/strings.xml
+++ b/packages/SystemUI/res-product/values-fi/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Yritit avata puhelimen lukituksen virheellisillä tiedoilla <xliff:g id="NUMBER">%d</xliff:g> kertaa. Työprofiili ja kaikki sen data poistetaan."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään avaamaan tabletin lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Piirsit lukituksenpoistokuvion väärin <xliff:g id="NUMBER_0">%1$d</xliff:g> kertaa. Jos piirrät kuvion väärin vielä <xliff:g id="NUMBER_1">%2$d</xliff:g> kertaa, sinua pyydetään avaamaan puhelimesi lukitus sähköpostitilin avulla.\n\n Yritä uudelleen <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunnin kuluttua."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Sormenjälkitunnistin on virtapainikkeessa. Se on litteä painike koholla olevan äänenvoimakkuuspainikkeen vieressä tabletin sivussa.\n\nJos painat virtapainiketta, näyttö sammuu."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Sormenjälkitunnistin on virtapainikkeessa. Se on litteä painike koholla olevan äänenvoimakkuuspainikkeen vieressä laitteen sivussa.\n\nJos painat virtapainiketta, näyttö sammuu."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Sormenjälkitunnistin on virtapainikkeessa. Se on litteä painike koholla olevan äänenvoimakkuuspainikkeen vieressä puhelimen sivussa.\n\nJos painat virtapainiketta, näyttö sammuu."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Sormenjälkitunnistin on virtapainikkeessa. Se on litteä painike koholla olevan äänenvoimakkuuspainikkeen vieressä tabletin sivussa."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Sormenjälkitunnistin on virtapainikkeessa. Se on litteä painike koholla olevan äänenvoimakkuuspainikkeen vieressä laitteen sivussa."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Sormenjälkitunnistin on virtapainikkeessa. Se on litteä painike koholla olevan äänenvoimakkuuspainikkeen vieressä puhelimen sivussa."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Avaa puhelimen lukitus, niin näet enemmän vaihtoehtoja"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Avaa tabletin lukitus, niin näet enemmän vaihtoehtoja"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Avaa laitteen lukitus, niin näet enemmän vaihtoehtoja"</string>
diff --git a/packages/SystemUI/res-product/values-fr-rCA/strings.xml b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
index bc01dde..3862796 100644
--- a/packages/SystemUI/res-product/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res-product/values-fr-rCA/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Vous avez tenté de déverrouiller ce téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel sera supprimé, ce qui entraîne la suppression de toutes ses données."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de courriel.\n\nVeuillez réessayer dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Le capteur d\'empreintes digitales est situé sur l\'interrupteur. Il s\'agit du bouton plat situé à côté du bouton de volume surélevé, sur le bord de la tablette.\n\nEn appuyant sur l\'interrupteur, vous éteignez l\'écran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Le capteur d\'empreintes digitales est situé sur l\'interrupteur. Il s\'agit du bouton plat situé à côté du bouton de volume surélevé, sur le bord de l\'appareil.\n\nEn appuyant sur l\'interrupteur, vous éteignez l\'écran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Le capteur d\'empreintes digitales est situé sur l\'interrupteur. Il s\'agit du bouton plat situé à côté du bouton de volume surélevé, sur le bord du téléphone.\n\nEn appuyant sur l\'interrupteur, vous éteignez l\'écran."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Le capteur d\'empreintes digitales est situé sur l\'interrupteur. Il s\'agit du bouton plat situé à côté du bouton de volume surélevé, sur le bord de la tablette."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Le capteur d\'empreintes digitales est situé sur l\'interrupteur. Il s\'agit du bouton plat situé à côté du bouton de volume surélevé, sur le bord de l\'appareil."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Le capteur d\'empreintes digitales est situé sur l\'interrupteur. Il s\'agit du bouton plat situé à côté du bouton de volume surélevé, sur le bord du téléphone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Déverrouillez votre téléphone pour afficher davantage d\'options"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Déverrouillez votre tablette pour afficher davantage d\'options"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Déverrouillez votre appareil pour afficher davantage d\'options"</string>
diff --git a/packages/SystemUI/res-product/values-fr/strings.xml b/packages/SystemUI/res-product/values-fr/strings.xml
index 0fc6fda..d874882 100644
--- a/packages/SystemUI/res-product/values-fr/strings.xml
+++ b/packages/SystemUI/res-product/values-fr/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Vous avez tenté de déverrouiller le téléphone à <xliff:g id="NUMBER">%d</xliff:g> reprises. Le profil professionnel et toutes les données associées vont être supprimés."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre tablette à l\'aide d\'un compte de messagerie électronique.\n\nRéessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Vous avez dessiné un schéma de déverrouillage incorrect à <xliff:g id="NUMBER_0">%1$d</xliff:g> reprises. Si vous échouez encore <xliff:g id="NUMBER_1">%2$d</xliff:g> fois, vous devrez déverrouiller votre téléphone à l\'aide d\'un compte de messagerie électronique.\n\nRéessayez dans <xliff:g id="NUMBER_2">%3$d</xliff:g> secondes."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Le lecteur d\'empreinte digitale se trouve sur le bouton Marche/Arrêt. C\'est le bouton plat à côté du bouton de volume en relief sur un bord de la tablette.\n\nAppuyer sur le bouton Marche/Arrêt éteint l\'écran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Le lecteur d\'empreinte digitale se trouve sur le bouton Marche/Arrêt. C\'est le bouton plat à côté du bouton de volume en relief sur un bord de l\'appareil.\n\nAppuyer sur le bouton Marche/Arrêt éteint l\'écran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Le lecteur d\'empreinte digitale se trouve sur le bouton Marche/Arrêt. C\'est le bouton plat à côté du bouton de volume en relief sur un bord du téléphone.\n\nAppuyer sur le bouton Marche/Arrêt éteint l\'écran."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Le lecteur d\'empreinte digitale est sur le bouton Marche/Arrêt. C\'est le bouton plat à côté du bouton de volume en relief sur un bord de la tablette."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Le lecteur d\'empreinte digitale est sur le bouton Marche/Arrêt. C\'est le bouton plat à côté du bouton de volume en relief sur un bord de l\'appareil."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Le lecteur d\'empreinte digitale est sur le bouton Marche/Arrêt. C\'est le bouton plat à côté du bouton de volume en relief sur un bord du téléphone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Déverrouillez votre téléphone pour obtenir plus d\'options"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Déverrouillez votre tablette pour obtenir plus d\'options"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Déverrouillez votre appareil pour obtenir plus d\'options"</string>
diff --git a/packages/SystemUI/res-product/values-gl/strings.xml b/packages/SystemUI/res-product/values-gl/strings.xml
index c27408e..b3e03ca 100644
--- a/packages/SystemUI/res-product/values-gl/strings.xml
+++ b/packages/SystemUI/res-product/values-gl/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Tentaches desbloquear o teléfono <xliff:g id="NUMBER">%d</xliff:g> veces de forma incorrecta. Quitarase o perfil de traballo e, por conseguinte, todos os seus datos."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear a tableta a través dunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Debuxaches o padrón de desbloqueo <xliff:g id="NUMBER_0">%1$d</xliff:g> veces de forma incorrecta. Se realizas <xliff:g id="NUMBER_1">%2$d</xliff:g> intentos incorrectos máis, terás que desbloquear o teléfono a través dunha conta de correo electrónico.\n\n Téntao de novo en <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"O sensor de impresión dixital está no botón de acendido. É o botón plano que está ao lado do botón de volume con relevo, no lateral da tableta.\n\nAo premer o botón de acendido, apágase a pantalla."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"O sensor de impresión dixital está no botón de acendido. É o botón plano que está ao lado do botón de volume con relevo, no lateral do dispositivo.\n\nAo premer o botón de acendido, apágase a pantalla."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"O sensor de impresión dixital está no botón de acendido. É o botón plano que está ao lado do botón de volume con relevo, no lateral do teléfono.\n\nAo premer o botón de acendido, apágase a pantalla."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"O sensor de impresión dixital está no botón de acendido. É o botón plano que se atopa a carón do botón de volume con relevo, no lateral da tableta."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"O sensor de impresión dixital está no botón de acendido. É o botón plano que se atopa a carón do botón de volume con relevo, no lateral do dispositivo."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"O sensor de impresión dixital está no botón de acendido. É o botón plano que se atopa a carón do botón de volume con relevo, no lateral do teléfono."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloquea o teléfono para ver máis opcións"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloquea a tableta para ver máis opcións"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloquea o dispositivo para ver máis opcións"</string>
diff --git a/packages/SystemUI/res-product/values-gu/strings.xml b/packages/SystemUI/res-product/values-gu/strings.xml
index f7a2256..4621be3 100644
--- a/packages/SystemUI/res-product/values-gu/strings.xml
+++ b/packages/SystemUI/res-product/values-gu/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"તમે ફોનને <xliff:g id="NUMBER">%d</xliff:g> વખત ખોટી રીતે અનલૉક કરવાનો પ્રયાસ કર્યો છે. આ કાર્યાલયની પ્રોફાઇલ કાઢી નાખવામાં આવશે, જે તમામ પ્રોફાઇલ ડેટાને ડિલીટ કરી દેશે."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, તમને એક ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ટૅબ્લેટને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરી પ્રયાસ કરો."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"તમે તમારી અનલૉક પૅટર્ન <xliff:g id="NUMBER_0">%1$d</xliff:g> વખત ખોટી રીતે દોરી છે. વધુ <xliff:g id="NUMBER_1">%2$d</xliff:g> અસફળ પ્રયાસો પછી, તમને ઇમેઇલ એકાઉન્ટનો ઉપયોગ કરીને તમારા ફોનને અનલૉક કરવાનું કહેવામાં આવશે.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> સેકન્ડમાં ફરીથી પ્રયાસ કરો."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"ફિંગરપ્રિન્ટ સેન્સર પાવર બટન પર છે. તે ટૅબ્લેટની કિનારીએ આવેલા ઉપસેલા વૉલ્યૂમ બટનની બાજુમાં આવેલું સપાટ બટન છે.\n\nપાવર બટન દબાવવાથી સ્ક્રીન બંધ થાય છે."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"ફિંગરપ્રિન્ટ સેન્સર પાવર બટન પર છે. તે ડિવાઇસની કિનારીએ આવેલા ઉપસેલા વૉલ્યૂમ બટનની બાજુમાં આવેલું સપાટ બટન છે.\n\nપાવર બટન દબાવવાથી સ્ક્રીન બંધ થાય છે."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"ફિંગરપ્રિન્ટ સેન્સર પાવર બટન પર છે. તે ફોનની કિનારીએ આવેલા ઉપસેલા વૉલ્યૂમ બટનની બાજુમાં આવેલું સપાટ બટન છે.\n\nપાવર બટન દબાવવાથી સ્ક્રીન બંધ થાય છે."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ફિંગરપ્રિન્ટ સેન્સર પાવર બટન પર છે. તે ટૅબ્લેટની કિનારીએ આવેલા ઉપસેલા વૉલ્યૂમ બટનની બાજુમાં આવેલું સપાટ બટન છે."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ફિંગરપ્રિન્ટ સેન્સર પાવર બટન પર છે. તે ડિવાઇસની કિનારીએ આવેલા ઉપસેલા વૉલ્યૂમ બટનની બાજુમાં આવેલું સપાટ બટન છે."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ફિંગરપ્રિન્ટ સેન્સર પાવર બટન પર છે. તે ફોનની કિનારીએ આવેલા ઉપસેલા વૉલ્યૂમ બટનની બાજુમાં આવેલું સપાટ બટન છે."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"વધુ વિકલ્પો માટે તમારા ફોનને અનલૉક કરો"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"વધુ વિકલ્પો માટે તમારા ટૅબ્લેટને અનલૉક કરો"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"વધુ વિકલ્પો માટે તમારા ડિવાઇસને અનલૉક કરો"</string>
diff --git a/packages/SystemUI/res-product/values-hi/strings.xml b/packages/SystemUI/res-product/values-hi/strings.xml
index 0fa377d..4c69df50 100644
--- a/packages/SystemUI/res-product/values-hi/strings.xml
+++ b/packages/SystemUI/res-product/values-hi/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"आप फ़ोन को अनलॉक करने के लिए <xliff:g id="NUMBER">%d</xliff:g> बार गलत पासवर्ड डाल चुके हैं. इसकी वजह से वर्क प्रोफ़ाइल को हटा दिया जाएगा जिससे उपयोगकर्ता की प्रोफ़ाइल का सारा डेटा मिट जाएगा."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"आपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से बनाया है. इसलिए, <xliff:g id="NUMBER_1">%2$d</xliff:g> और गलत पैटर्न बनाने के बाद, टैबलेट को अनलॉक करने के लिए आपसे ईमेल खाते का इस्तेमाल करने को कहा जाएगा.\n\n अनलॉक करने के लिए <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"आपने लॉक खोलने के पैटर्न को <xliff:g id="NUMBER_0">%1$d</xliff:g> बार गलत तरीके से बनाया है. इसलिए, <xliff:g id="NUMBER_1">%2$d</xliff:g> और गलत पैटर्न बनाने के बाद, आपसे फ़ोन को अनलॉक करने के लिए ईमेल खाते का इस्तेमाल करने को कहा जाएगा.\n\n अनलॉक करने के लिए <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंड में फिर से कोशिश करें."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"फ़िंगरप्रिंट सेंसर, पावर बटन पर होता है. यह टैबलेट के किनारे पर मौजूद एक फ़्लैट बटन होता है, जो कि आपको आवाज़ कम या ज़्यादा करने वाले उभरे हुए बटन के नीचे मिलेगा.\n\nपावर बटन दबाने से स्क्रीन बंद हो जाती है."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"फ़िंगरप्रिंट सेंसर, पावर बटन पर होता है. यह डिवाइस के किनारे पर मौजूद एक फ़्लैट बटन होता है, जो कि आपको आवाज़ कम या ज़्यादा करने वाले उभरे हुए बटन के नीचे मिलेगा.\n\nपावर बटन दबाने से स्क्रीन बंद हो जाती है."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"फ़िंगरप्रिंट सेंसर, पावर बटन पर होता है. यह फ़ोन के किनारे पर मौजूद एक फ़्लैट बटन होता है, जो कि आपको आवाज़ कम या ज़्यादा करने वाले उभरे हुए बटन के नीचे मिलेगा.\n\nपावर बटन दबाने से स्क्रीन बंद हो जाती है."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"फ़िंगरप्रिंट सेंसर, पावर बटन पर होता है. यह टैबलेट के किनारे पर मौजूद एक फ़्लैट बटन होता है, जो कि आपको आवाज़ कम या ज़्यादा करने वाले उभरे हुए बटन के बगल में मिलेगा."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"फ़िंगरप्रिंट सेंसर, पावर बटन पर होता है. यह डिवाइस के किनारे पर मौजूद एक फ़्लैट बटन होता है, जो कि आपको आवाज़ कम या ज़्यादा करने वाले उभरे हुए बटन के बगल में मिलेगा."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"फ़िंगरप्रिंट सेंसर, पावर बटन पर होता है. यह फ़ोन के किनारे पर मौजूद एक फ़्लैट बटन होता है, जो कि आपको आवाज़ कम या ज़्यादा करने वाले उभरे हुए बटन के बगल में मिलेगा."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ज़्यादा विकल्प देखने के लिए, अपना फ़ोन अनलॉक करें"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ज़्यादा विकल्प देखने के लिए, अपना टैबलेट अनलॉक करें"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ज़्यादा विकल्प देखने के लिए, अपना डिवाइस अनलॉक करें"</string>
diff --git a/packages/SystemUI/res-product/values-hr/strings.xml b/packages/SystemUI/res-product/values-hr/strings.xml
index f467291..a7bd4b0 100644
--- a/packages/SystemUI/res-product/values-hr/strings.xml
+++ b/packages/SystemUI/res-product/values-hr/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Neuspješno ste pokušali otključati telefon <xliff:g id="NUMBER">%d</xliff:g> put/a. Radni će se profil ukloniti, a time će se izbrisati i svi njegovi podaci."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja morat ćete otključati tablet pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Netočno ste iscrtali uzorak za otključavanje <xliff:g id="NUMBER_0">%1$d</xliff:g> put/a. Nakon još <xliff:g id="NUMBER_1">%2$d</xliff:g> pokušaja morat ćete otključati telefon pomoću računa e-pošte.\n\n Pokušajte ponovo za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Senzor otiska prsta nalazi se na tipki za uključivanje/isključivanje. To je ravni gumb pored izdignutog gumba za glasnoću na rubu tableta.\n\nPritiskom na tipku za uključivanje/isključivanje isključuje se zaslon."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Senzor otiska prsta nalazi se na tipki za uključivanje/isključivanje. To je ravni gumb pored izdignutog gumba za glasnoću na rubu uređaja.\n\nPritiskom na tipku za uključivanje/isključivanje isključuje se zaslon."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Senzor otiska prsta nalazi se na tipki za uključivanje/isključivanje. To je ravni gumb pored izdignutog gumba za glasnoću na rubu telefona.\n\nPritiskom na tipku za uključivanje/isključivanje isključuje se zaslon."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzor otiska prsta nalazi se na tipki za uključivanje/isključivanje. To je ravni gumb pored izdignutog gumba za glasnoću na rubu tableta."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzor otiska prsta nalazi se na tipki za uključivanje/isključivanje. To je ravni gumb pored izdignutog gumba za glasnoću na rubu uređaja."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzor otiska prsta nalazi se na tipki za uključivanje/isključivanje. To je ravni gumb pored izdignutog gumba za glasnoću na rubu telefona."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Za više opcija otključajte telefon"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Za više opcija otključajte tablet"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Za više opcija otključajte uređaj"</string>
diff --git a/packages/SystemUI/res-product/values-hu/strings.xml b/packages/SystemUI/res-product/values-hu/strings.xml
index d5f44e9..75c10e9 100644
--- a/packages/SystemUI/res-product/values-hu/strings.xml
+++ b/packages/SystemUI/res-product/values-hu/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> alkalommal próbálkozott sikertelenül a telefon zárolásának feloldásával. A rendszer eltávolítja a munkaprofilt, és ezzel a profil összes adata törlődik."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után e-mail-fiók használatával kell feloldania táblagépét.\n\nPróbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"<xliff:g id="NUMBER_0">%1$d</xliff:g> alkalommal helytelenül rajzolta le a feloldási mintát. További <xliff:g id="NUMBER_1">%2$d</xliff:g> sikertelen kísérlet után e-mail-fiók használatával kell feloldania telefonját.\n\nPróbálja újra <xliff:g id="NUMBER_2">%3$d</xliff:g> másodperc múlva."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Az ujjlenyomat-érzékelő a bekapcsológombon található. A kiemelkedő hangerőgomb melletti lapos gomb a táblagép szélén.\n\nA bekapcsológomb lenyomásával kikapcsol a képernyő."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Az ujjlenyomat-érzékelő a bekapcsológombon található. A kiemelkedő hangerőgomb melletti lapos gomb az eszköz szélén.\n\nA bekapcsológomb lenyomásával kikapcsol a képernyő."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Az ujjlenyomat-érzékelő a bekapcsológombon található. A kiemelkedő hangerőgomb melletti lapos gomb a telefon szélén.\n\nA bekapcsológomb lenyomásával kikapcsol a képernyő."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Az ujjlenyomat-érzékelő a bekapcsológombon található. Ez a kiemelkedő hangerőgomb melletti lapos gomb a táblagép szélén."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Az ujjlenyomat-érzékelő a bekapcsológombon található. Ez a kiemelkedő hangerőgomb melletti lapos gomb az eszköz szélén."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Az ujjlenyomat-érzékelő a bekapcsológombon található. Ez a kiemelkedő hangerőgomb melletti lapos gomb a telefon szélén."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"További lehetőségekért oldja fel a telefont"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"További lehetőségekért oldja fel a táblagépet"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"További lehetőségekért oldja fel az eszközt"</string>
diff --git a/packages/SystemUI/res-product/values-hy/strings.xml b/packages/SystemUI/res-product/values-hy/strings.xml
index 74d115b..3ebc72f 100644
--- a/packages/SystemUI/res-product/values-hy/strings.xml
+++ b/packages/SystemUI/res-product/values-hy/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Դուք կատարել եք հեռախոսն ապակողպելու <xliff:g id="NUMBER">%d</xliff:g> անհաջող փորձ: Աշխատանքային պրոֆիլը կհեռացվի, և պրոֆիլի բոլոր տվյալները կջնջվեն:"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Դուք կատարել եք ապակողպման նախշը մուտքագրելու <xliff:g id="NUMBER_0">%1$d</xliff:g> անհաջող փորձ: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզանից կպահանջվի ապակողպել պլանշետը էլփոստի հաշվի միջոցով։\n\n Խնդրում ենք կրկին փորձել <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Դուք <xliff:g id="NUMBER_0">%1$d</xliff:g> անգամ սխալ եք հավաքել ձեր ապակողպման նմուշը: Եվս <xliff:g id="NUMBER_1">%2$d</xliff:g> անհաջող փորձից հետո ձեզ կառաջարկվի ապակողպել հեռախոսը` օգտագործելով էլփոստի հաշիվ:\n\n Կրկին փորձեք <xliff:g id="NUMBER_2">%3$d</xliff:g> վայրկյանից:"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Մատնահետքերի սկաները սնուցման կոճակի վրա է։ Այն հարթ կոճակն է՝ ձայնի ուժգնության ուռուցիկ կոճակի կողքին, պլանշետի եզրային մասում։\n\nՍնուցման կոճակի սեղմումով էկրանն անջատվում է։"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Մատնահետքերի սկաները սնուցման կոճակի վրա է։ Այն հարթ կոճակն է՝ ձայնի ուժգնության ուռուցիկ կոճակի կողքին, սարքի եզրային մասում։\n\nՍնուցման կոճակի սեղմումով էկրանն անջատվում է։"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Մատնահետքերի սկաները սնուցման կոճակի վրա է։ Այն հարթ կոճակ է՝ ձայնի ուժգնության ուռուցիկ կոճակի կողքին, հեռախոսի եզրային մասում։\n\nՍնուցման կոճակի սեղմումով էկրանն անջատվում է։"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Մատնահետքերի սկաները սնուցման կոճակի վրա է։ Այն հարթ կոճակ է ձայնի ուժգնության ուռուցիկ կոճակի կողքին՝ պլանշետի եզրային մասում։"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Մատնահետքերի սկաները սնուցման կոճակի վրա է։ Այն հարթ կոճակ է ձայնի ուժգնության ուռուցիկ կոճակի կողքին՝ սարքի եզրային մասում։"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Մատնահետքերի սկաները սնուցման կոճակի վրա է։ Այն հարթ կոճակ է ձայնի ուժգնության ուռուցիկ կոճակի կողքին՝ հեռախոսի եզրային մասում։"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ապակողպեք ձեր հեռախոսը՝ լրացուցիչ կարգավորումները տեսնելու համար"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ապակողպեք ձեր պլանշետը՝ լրացուցիչ կարգավորումները տեսնելու համար"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ապակողպեք ձեր սարքը՝ լրացուցիչ կարգավորումները տեսնելու համար"</string>
diff --git a/packages/SystemUI/res-product/values-in/strings.xml b/packages/SystemUI/res-product/values-in/strings.xml
index d4363b8..af1895c 100644
--- a/packages/SystemUI/res-product/values-in/strings.xml
+++ b/packages/SystemUI/res-product/values-in/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Anda telah <xliff:g id="NUMBER">%d</xliff:g> kali berupaya membuka kunci ponsel dengan tidak benar. Profil kerja akan dihapus, sehingga semua data profil akan dihapus."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, Anda akan diminta membuka kunci tablet menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Anda telah <xliff:g id="NUMBER_0">%1$d</xliff:g> kali salah menggambar pola pembuka kunci. Setelah <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi upaya yang tidak berhasil, Anda akan diminta membuka kunci ponsel menggunakan akun email.\n\n Coba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> detik."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Sensor sidik jari ada di tombol daya. Tombol ini berupa tombol datar di samping tombol volume timbul di tepi tablet.\n\nMenekan tombol daya akan menonaktifkan layar."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Sensor sidik jari ada di tombol daya. Tombol ini berupa tombol datar di samping tombol volume timbul di tepi perangkat.\n\nMenekan tombol daya akan menonaktifkan layar."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Sensor sidik jari ada di tombol daya. Tombol ini berupa tombol datar di samping tombol volume timbul di tepi ponsel.\n\nMenekan tombol daya akan menonaktifkan layar."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Sensor sidik jari ada di tombol daya. Tombol ini berupa tombol datar di samping tombol volume timbul di tepi tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Sensor sidik jari ada di tombol daya. Tombol ini berupa tombol datar di samping tombol volume timbul di tepi perangkat."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Sensor sidik jari ada di tombol daya. Tombol ini berupa tombol datar di samping tombol volume timbul di tepi ponsel."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Buka kunci ponsel untuk melihat opsi lainnya"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Buka kunci tablet untuk melihat opsi lainnya"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Buka kunci perangkat untuk melihat opsi lainnya"</string>
diff --git a/packages/SystemUI/res-product/values-is/strings.xml b/packages/SystemUI/res-product/values-is/strings.xml
index 4923f1b..1e42255 100644
--- a/packages/SystemUI/res-product/values-is/strings.xml
+++ b/packages/SystemUI/res-product/values-is/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Þú hefur gert <xliff:g id="NUMBER">%d</xliff:g> árangurslausar tilraunir til að opna símann. Vinnusniðið verður fjarlægt, með þeim afleiðingum að öllum gögnum þess verður eytt."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verðurðu beðin(n) um að opna spjaldtölvuna með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Þú hefur teiknað rangt opnunarmynstur <xliff:g id="NUMBER_0">%1$d</xliff:g> sinnum. Eftir <xliff:g id="NUMBER_1">%2$d</xliff:g> árangurslausar tilraunir í viðbót verðurðu beðin(n) um að opna símann með tölvupóstreikningi.\n\n Reyndu aftur eftir <xliff:g id="NUMBER_2">%3$d</xliff:g> sekúndur."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Fingrafaralesarinn er á aflrofanum. Það er flati hnappurinn við hliðina á upphleypta hljóðstyrkshnappnum á hlið spjaldtölvunnar.\n\nÞegar ýtt er á aflrofann slokknar á skjánum."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Fingrafaralesarinn er á aflrofanum. Það er flati hnappurinn við hliðina á upphleypta hljóðstyrkshnappnum á hlið tækisins.\n\nÞegar ýtt er á aflrofann slokknar á skjánum."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Fingrafaralesarinn er á aflrofanum. Það er flati hnappurinn við hliðina á upphleypta hljóðstyrkshnappnum á hlið símans.\n\nÞegar ýtt er á aflrofann slokknar á skjánum."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Fingrafaralesarinn er á aflrofanum. Það er flati hnappurinn við hliðina á upphleypta hljóðstyrkshnappnum á hlið spjaldtölvunnar."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Fingrafaralesarinn er á aflrofanum. Það er flati hnappurinn við hliðina á upphleypta hljóðstyrkshnappnum á hlið tækisins."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Fingrafaralesarinn er á aflrofanum. Það er flati hnappurinn við hliðina á upphleypta hljóðstyrkshnappnum á hlið símans."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Taktu símann úr lás til að fá fleiri valkosti"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Taktu spjaldtölvuna úr lás til að fá fleiri valkosti"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Taktu tækið úr lás til að fá fleiri valkosti"</string>
diff --git a/packages/SystemUI/res-product/values-it/strings.xml b/packages/SystemUI/res-product/values-it/strings.xml
index 7718e28..982afb9 100644
--- a/packages/SystemUI/res-product/values-it/strings.xml
+++ b/packages/SystemUI/res-product/values-it/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Hai tentato di sbloccare il telefono senza riuscirci per <xliff:g id="NUMBER">%d</xliff:g> volte. Il profilo di lavoro verrà rimosso e verranno quindi eliminati tutti i dati associati."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il tablet con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"<xliff:g id="NUMBER_0">%1$d</xliff:g> tentativi errati di inserimento della sequenza di sblocco. Dopo altri <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativi falliti, ti verrà chiesto di sbloccare il telefono con un account email.\n\n Riprova tra <xliff:g id="NUMBER_2">%3$d</xliff:g> secondi."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale del tablet.\n\nSe premi il tasto di accensione viene disattivato lo schermo."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale del dispositivo.\n\nSe premi il tasto di accensione viene disattivato lo schermo."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale del telefono.\n\nSe premi il tasto di accensione viene disattivato lo schermo."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale del tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale del dispositivo."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Il sensore di impronte digitali si trova sul tasto di accensione. Si tratta del tasto piatto accanto al tasto del volume in rilievo sulla parte laterale del telefono."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Sblocca il telefono per visualizzare altre opzioni"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Sblocca il tablet per visualizzare altre opzioni"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Sblocca il dispositivo per visualizzare altre opzioni"</string>
diff --git a/packages/SystemUI/res-product/values-iw/strings.xml b/packages/SystemUI/res-product/values-iw/strings.xml
index b32f21b..71779f30 100644
--- a/packages/SystemUI/res-product/values-iw/strings.xml
+++ b/packages/SystemUI/res-product/values-iw/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ניסית לבטל את נעילת הטלפון <xliff:g id="NUMBER">%d</xliff:g> פעמים. פרופיל העבודה יוסר וכל נתוני הפרופיל יימחקו."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, ,תישלח אליך בקשה לבטל את נעילת הטאבלט באמצעות חשבון אימייל.\n\n יש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"שרטטת קו ביטול נעילה שגוי <xliff:g id="NUMBER_0">%1$d</xliff:g> פעמים. לאחר <xliff:g id="NUMBER_1">%2$d</xliff:g> ניסיונות כושלים נוספים, תישלח אליך בקשה לבטל את נעילת הטלפון באמצעות חשבון אימייל.\n\n יש לנסות שוב בעוד <xliff:g id="NUMBER_2">%3$d</xliff:g> שניות."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"חיישן טביעת האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בפינת הטאבלט.\n\nלחיצה על לחצן ההפעלה מכבה את המסך."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"חיישן טביעת האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בפינת המכשיר.\n\nלחיצה על לחצן ההפעלה מכבה את המסך."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"חיישן טביעת האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בפינת הטלפון.\n\nלחיצה על לחצן ההפעלה מכבה את המסך."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"חיישן טביעות האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בשולי הטאבלט."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"חיישן טביעות האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בשולי המכשיר."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"חיישן טביעות האצבע נמצא על לחצן ההפעלה. זה הלחצן השטוח ליד הלחצן הבולט של עוצמת הקול בשולי הטלפון."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"לאפשרויות נוספות, יש לבטל את נעילת הטלפון"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"לאפשרויות נוספות, יש לבטל את נעילת הטאבלט"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"לאפשרויות נוספות, יש לבטל את נעילת המכשיר"</string>
diff --git a/packages/SystemUI/res-product/values-ja/strings.xml b/packages/SystemUI/res-product/values-ja/strings.xml
index 19e00d1..68f030b 100644
--- a/packages/SystemUI/res-product/values-ja/strings.xml
+++ b/packages/SystemUI/res-product/values-ja/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"スマートフォンのロック解除に <xliff:g id="NUMBER">%d</xliff:g> 回失敗しました。仕事用プロファイルは削除され、プロファイルのデータはすべて消去されます。"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回間違えると、タブレットのロック解除にメール アカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後にもう一度お試しください。"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ロック解除パターンの入力を <xliff:g id="NUMBER_0">%1$d</xliff:g> 回間違えました。あと <xliff:g id="NUMBER_1">%2$d</xliff:g> 回間違えると、スマートフォンのロック解除にメール アカウントが必要になります。\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後にもう一度お試しください。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"指紋認証センサーは電源ボタンに内蔵されています。タブレットの端にある盛り上がった音量ボタンの横のフラットなボタンです。\n\n電源ボタンを押すと画面が OFF になります。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"指紋認証センサーは電源ボタンに内蔵されています。デバイスの端にある盛り上がった音量ボタンの横のフラットなボタンです。\n\n電源ボタンを押すと画面が OFF になります。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"指紋認証センサーは電源ボタンに内蔵されています。スマートフォンの端にある盛り上がった音量ボタンの横のフラットなボタンです。\n\n電源ボタンを押すと画面が OFF になります。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指紋認証センサーは電源ボタンに内蔵されています。タブレット側面のボタンのうち、音量ボタンの横にあるフラットなボタンです。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指紋認証センサーは電源ボタンに内蔵されています。デバイス側面のボタンのうち、音量ボタンの横にあるフラットなボタンです。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指紋認証センサーは電源ボタンに内蔵されています。スマートフォン側面のボタンのうち、音量ボタンの横にあるフラットなボタンです。"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"スマートフォンのロックを解除してその他のオプションを表示する"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"タブレットのロックを解除してその他のオプションを表示する"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"デバイスのロックを解除してその他のオプションを表示する"</string>
diff --git a/packages/SystemUI/res-product/values-ka/strings.xml b/packages/SystemUI/res-product/values-ka/strings.xml
index fe6fcbd..34fc24c 100644
--- a/packages/SystemUI/res-product/values-ka/strings.xml
+++ b/packages/SystemUI/res-product/values-ka/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"თქვენ არასწორად ცადეთ ტელეფონის განბლოკვა <xliff:g id="NUMBER">%d</xliff:g>-ჯერ. ამის გამო, სამსახურის პროფილი ამოიშლება, რაც პროფილის ყველა მონაცემის წაშლას გამოიწვევს."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ მოგთხოვთ, ტაბლეტი თქვენი ელფოსტის ანგარიშის მეშვეობით განბლოკოთ.\n\n ცადეთ ხელახლა <xliff:g id="NUMBER_2">%3$d</xliff:g> წამში."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"თქვენ არასწორად დახატეთ თქვენი განბლოკვის ნიმუში <xliff:g id="NUMBER_0">%1$d</xliff:g>-ჯერ. კიდევ <xliff:g id="NUMBER_1">%2$d</xliff:g> წარუმატებელი მცდელობის შემდეგ მოგთხოვთ, ტელეფონი თქვენი ელფოსტის ანგარიშის მეშვეობით განბლოკოთ.\n\n ცადეთ ხელახლა <xliff:g id="NUMBER_2">%3$d</xliff:g> წამში."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"თითის ანაბეჭდის სენსორი ჩართვის ღილაკზეა. ეს არის ბრტყელი ღილაკი ხმის აწევის ღილაკის გვერდით ტაბლეტის კიდეზე.\n\nჩართვის ღილაკზე დაწკაპუნება გამორთავს ეკრანს."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"თითის ანაბეჭდის სენსორი ჩართვის ღილაკზეა. ეს არის ბრტყელი ღილაკი ხმის აწევის ღილაკის გვერდით მოწყობილობის კიდეზე.\n\nჩართვის ღილაკზე დაწკაპუნება გამორთავს ეკრანს."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"თითის ანაბეჭდის სენსორი ჩართვის ღილაკზეა. ეს არის ბრტყელი ღილაკი ხმის აწევის ღილაკის გვერდით ტელეფონის კიდეზე.\n\nჩართვის ღილაკზე დაწკაპუნება გამორთავს ეკრანს."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"თითის ანაბეჭდის სენსორი ჩართვის ღილაკზეა. ეს არის ბრტყელი ღილაკი ხმის აწევის ღილაკის გვერდით, ტაბლეტის კიდეში."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"თითის ანაბეჭდის სენსორი ჩართვის ღილაკზეა. ეს არის ბრტყელი ღილაკი ხმის აწევის ღილაკის გვერდით, მოწყობილობის კიდეში."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"თითის ანაბეჭდის სენსორი ჩართვის ღილაკზეა. ეს არის ბრტყელი ღილაკი ხმის აწევის ღილაკის გვერდით, ტელეფონის კიდეში."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"მეტი ვარიანტის სანახავად განბლოკეთ თქვენი ტელეფონი"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"მეტი ვარიანტის სანახავად განბლოკეთ თქვენი ტაბლეტი"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"მეტი ვარიანტის სანახავად განბლოკეთ თქვენი მოწყობილობა"</string>
diff --git a/packages/SystemUI/res-product/values-kk/strings.xml b/packages/SystemUI/res-product/values-kk/strings.xml
index 3f94907..73b637e 100644
--- a/packages/SystemUI/res-product/values-kk/strings.xml
+++ b/packages/SystemUI/res-product/values-kk/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Телефон құлпын ашуға <xliff:g id="NUMBER">%d</xliff:g> рет сәтсіз әрекет жасалды. Жұмыс профилі өшіріліп, оның бүкіл деректері жойылады."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін планшетті аккаунт арқылы ашу сұралады. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Құлыпты ашу өрнегі <xliff:g id="NUMBER_0">%1$d</xliff:g> рет қате енгізілді. <xliff:g id="NUMBER_1">%2$d</xliff:g> әрекет қалды. Одан кейін телефонды аккаунт арқылы ашу сұралады. \n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундтан кейін әрекетті қайталаңыз."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Саусақ ізін оқу сканері қуат түймесінде орналасқан. Ол – планшеттің шетіндегі шығыңқы дыбыс деңгейі түймесінің жанында орналасқан жалпақ түйме.\n\nҚуат түймесі басылса, экран өшеді."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Саусақ ізін оқу сканері қуат түймесінде орналасқан. Ол – құрылғының шетіндегі шығыңқы дыбыс деңгейі түймесінің жанында орналасқан жалпақ түйме.\n\nҚуат түймесі басылса, экран өшеді."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Саусақ ізін оқу сканері қуат түймесінде орналасқан. Ол – телефонның шетіндегі шығыңқы дыбыс деңгейі түймесінің жанында орналасқан жалпақ түйме.\n\nҚуат түймесі басылса, экран өшеді."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Саусақ ізін оқу сканері қуат түймесінде орналасқан. Ол – планшет шетіндегі шығыңқы дыбыс деңгейі түймесінің жанында орналасқан жалпақ түйме."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Саусақ ізін оқу сканері қуат түймесінде орналасқан. Ол – құрылғы шетіндегі шығыңқы дыбыс деңгейі түймесінің жанында орналасқан жалпақ түйме."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Саусақ ізін оқу сканері қуат түймесінде орналасқан. Ол – телефон шетіндегі шығыңқы дыбыс деңгейі түймесінің жанында орналасқан жалпақ түйме."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Басқа опцияларды көру үшін телефон құлпын ашыңыз."</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Басқа опцияларды көру үшін планшет құлпын ашыңыз."</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Басқа опцияларды көру үшін құрылғы құлпын ашыңыз."</string>
diff --git a/packages/SystemUI/res-product/values-km/strings.xml b/packages/SystemUI/res-product/values-km/strings.xml
index 46bf9af..611ee94 100644
--- a/packages/SystemUI/res-product/values-km/strings.xml
+++ b/packages/SystemUI/res-product/values-km/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"អ្នកបានព្យាយាមដោះសោទូរសព្ទនេះមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER">%d</xliff:g> ដងហើយ។ កម្រងព័ត៌មានការងារនេះនឹងត្រូវបានលុប ហើយវានឹងលុបទិន្នន័យកម្រងព័ត៌មានទាំងអស់។"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"អ្នកបានគូរលំនាំដោះសោរបស់អ្នកមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ បន្ទាប់ពីមានការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យ អ្នកនឹងត្រូវបានស្នើឱ្យដោះសោថេប្លេតរបស់អ្នក ដោយប្រើគណនីអ៊ីមែល។\n\n សូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_2">%3$d</xliff:g> វិនាទីទៀត។"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"អ្នកបានគូរលំនាំដោះសោរបស់អ្នកមិនត្រឹមត្រូវចំនួន <xliff:g id="NUMBER_0">%1$d</xliff:g> ដងហើយ។ បន្ទាប់ពីមានការព្យាយាមដោះសោចំនួន <xliff:g id="NUMBER_1">%2$d</xliff:g> ដងទៀតមិនទទួលបានជោគជ័យ អ្នកនឹងត្រូវបានស្នើឱ្យដោះសោទូរសព្ទរបស់អ្នកដោយប្រើគណនីអ៊ីមែល។\n\n សូមព្យាយាមម្ដងទៀតក្នុងរយៈពេល <xliff:g id="NUMBER_2">%3$d</xliff:g> វិនាទីទៀត។"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"សេនស័រចាប់ស្នាមម្រាមដៃស្ថិតនៅលើប៊ូតុងថាមពល។ វាជាប៊ូតុងរាបស្មើនៅជាប់នឹងប៊ូតុងកម្រិតសំឡេងដែលលៀនចេញមកនៅលើគែមថេប្លេត។\n\nការចុចប៊ូតុងថាមពលនឹងបិទអេក្រង់។"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"សេនស័រចាប់ស្នាមម្រាមដៃស្ថិតនៅលើប៊ូតុងថាមពល។ វាជាប៊ូតុងរាបស្មើនៅជាប់នឹងប៊ូតុងកម្រិតសំឡេងដែលលៀនចេញមកនៅលើគែមឧបករណ៍។\n\nការចុចប៊ូតុងថាមពលនឹងបិទអេក្រង់។"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"សេនស័រចាប់ស្នាមម្រាមដៃស្ថិតនៅលើប៊ូតុងថាមពល។ វាជាប៊ូតុងរាបស្មើនៅជាប់នឹងប៊ូតុងកម្រិតសំឡេងដែលលៀនចេញមកនៅលើគែមទូរសព្ទ។\n\nការចុចប៊ូតុងថាមពលនឹងបិទអេក្រង់។"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"សេនស័រចាប់ស្នាមម្រាមដៃស្ថិតនៅលើប៊ូតុងថាមពល។ វាជាប៊ូតុងរាបស្មើនៅជាប់នឹងប៊ូតុងកម្រិតសំឡេងដែលលៀនចេញមកនៅលើគែមថេប្លេត។"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"សេនស័រចាប់ស្នាមម្រាមដៃស្ថិតនៅលើប៊ូតុងថាមពល។ វាជាប៊ូតុងរាបស្មើនៅជាប់នឹងប៊ូតុងកម្រិតសំឡេងដែលលៀនចេញមកនៅលើគែមឧបករណ៍។"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"សេនស័រចាប់ស្នាមម្រាមដៃស្ថិតនៅលើប៊ូតុងថាមពល។ វាជាប៊ូតុងរាបស្មើនៅជាប់នឹងប៊ូតុងកម្រិតសំឡេងដែលលៀនចេញមកនៅលើគែមទូរសព្ទ។"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ដោះសោទូរសព្ទរបស់អ្នកសម្រាប់ជម្រើសច្រើនទៀត"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ដោះសោថេប្លេតរបស់អ្នកសម្រាប់ជម្រើសច្រើនទៀត"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ដោះសោឧបករណ៍របស់អ្នកសម្រាប់ជម្រើសច្រើនទៀត"</string>
diff --git a/packages/SystemUI/res-product/values-kn/strings.xml b/packages/SystemUI/res-product/values-kn/strings.xml
index 44bcf55..371c36a 100644
--- a/packages/SystemUI/res-product/values-kn/strings.xml
+++ b/packages/SystemUI/res-product/values-kn/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ಫೋನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಲು ನೀವು <xliff:g id="NUMBER">%d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಪ್ರಯತ್ನಿಸಿದ್ದೀರಿ. ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್ ಅನ್ನು ತೆಗೆದುಹಾಕಲಾಗುತ್ತದೆ, ಇದು ಪ್ರೊಫೈಲ್ನ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸುತ್ತದೆ."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಡ್ರಾ ಮಾಡಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ನಿಮ್ಮ ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡ್ಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ನಿಮ್ಮ ಅನ್ಲಾಕ್ ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ನೀವು <xliff:g id="NUMBER_0">%1$d</xliff:g> ಬಾರಿ ತಪ್ಪಾಗಿ ಡ್ರಾ ಮಾಡಿರುವಿರಿ. <xliff:g id="NUMBER_1">%2$d</xliff:g> ಕ್ಕೂ ಹೆಚ್ಚಿನ ವಿಫಲ ಪ್ರಯತ್ನಗಳ ಬಳಿಕ, ಇಮೇಲ್ ಖಾತೆಯನ್ನು ಬಳಸಿ ನಿಮ್ಮ ಫೋನ್ ಅನ್ಲಾಕ್ ಮಾಡಲು ನಿಮ್ಮನ್ನು ಕೇಳಲಾಗುತ್ತದೆ.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ಸೆಕೆಂಡ್ಗಳಲ್ಲಿ ಪುನಃ ಪ್ರಯತ್ನಿಸಿ."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಪವರ್ ಬಟನ್ನಲ್ಲಿದೆ. ಇದು ಟ್ಯಾಬ್ಲೆಟ್ನ ಅಂಚಿನಲ್ಲಿರುವ ಎತ್ತರಿಸಿದ ವಾಲ್ಯೂಮ್ ಬಟನ್ನ ಪಕ್ಕದಲ್ಲಿರುವ ಚಪ್ಪಟೆ ಬಟನ್ ಆಗಿದೆ.\n\nಪವರ್ ಬಟನ್ ಅನ್ನು ಒತ್ತುವುದರಿಂದ ಸ್ಕ್ರೀನ್ ಆಫ್ ಆಗುತ್ತದೆ."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಪವರ್ ಬಟನ್ನಲ್ಲಿದೆ. ಇದು ಸಾಧನದ ಅಂಚಿನಲ್ಲಿರುವ ಎತ್ತರಿಸಿದ ವಾಲ್ಯೂಮ್ ಬಟನ್ನ ಪಕ್ಕದಲ್ಲಿರುವ ಚಪ್ಪಟೆ ಬಟನ್ ಆಗಿದೆ.\n\nಪವರ್ ಬಟನ್ ಅನ್ನು ಒತ್ತುವುದರಿಂದ ಸ್ಕ್ರೀನ್ ಆಫ್ ಆಗುತ್ತದೆ."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಪವರ್ ಬಟನ್ನಲ್ಲಿದೆ. ಇದು ಫೋನ್ ಅಂಚಿನಲ್ಲಿರುವ ಎತ್ತರಿಸಿದ ವಾಲ್ಯೂಮ್ ಬಟನ್ನ ಪಕ್ಕದಲ್ಲಿರುವ ಚಪ್ಪಟೆ ಬಟನ್ ಆಗಿದೆ.\n\nಪವರ್ ಬಟನ್ ಅನ್ನು ಒತ್ತುವುದರಿಂದ ಸ್ಕ್ರೀನ್ ಆಫ್ ಆಗುತ್ತದೆ."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಪವರ್ ಬಟನ್ನಲ್ಲಿದೆ. ಇದು ಟ್ಯಾಬ್ಲೆಟ್ನ ಅಂಚಿನಲ್ಲಿರುವ ಎತ್ತರಿಸಿದ ವಾಲ್ಯೂಮ್ ಬಟನ್ನ ಪಕ್ಕದಲ್ಲಿರುವ ಫ್ಲಾಟ್ ಬಟನ್ ಆಗಿದೆ."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಪವರ್ ಬಟನ್ನಲ್ಲಿದೆ. ಇದು ಸಾಧನದ ಅಂಚಿನಲ್ಲಿರುವ ಎತ್ತರಿಸಿದ ವಾಲ್ಯೂಮ್ ಬಟನ್ನ ಪಕ್ಕದಲ್ಲಿರುವ ಫ್ಲಾಟ್ ಬಟನ್ ಆಗಿದೆ."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಸೆನ್ಸರ್ ಪವರ್ ಬಟನ್ನಲ್ಲಿದೆ. ಇದು ಫೋನ್ನ ಅಂಚಿನಲ್ಲಿರುವ ಎತ್ತರಿಸಿದ ವಾಲ್ಯೂಮ್ ಬಟನ್ನ ಪಕ್ಕದಲ್ಲಿರುವ ಫ್ಲಾಟ್ ಬಟನ್ ಆಗಿದೆ."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ನಿಮ್ಮ ಫೋನ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ಹೆಚ್ಚಿನ ಆಯ್ಕೆಗಳಿಗಾಗಿ ನಿಮ್ಮ ಸಾಧನವನ್ನು ಅನ್ಲಾಕ್ ಮಾಡಿ"</string>
diff --git a/packages/SystemUI/res-product/values-ko/strings.xml b/packages/SystemUI/res-product/values-ko/strings.xml
index d9ca699..b262452 100644
--- a/packages/SystemUI/res-product/values-ko/strings.xml
+++ b/packages/SystemUI/res-product/values-ko/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"휴대전화 잠금 해제에 <xliff:g id="NUMBER">%d</xliff:g>번 실패했습니다. 직장 프로필과 모든 프로필 데이터가 삭제됩니다."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"잠금 해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 태블릿을 잠금 해제해야 합니다.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g>초 후에 다시 시도해 주세요."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"잠금 해제 패턴을 <xliff:g id="NUMBER_0">%1$d</xliff:g>회 잘못 그렸습니다. <xliff:g id="NUMBER_1">%2$d</xliff:g>회 더 실패하면 이메일 계정을 사용하여 휴대전화를 잠금 해제해야 합니다.\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g>초 후에 다시 시도해 주세요."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"지문 센서는 전원 버튼에 있습니다. 태블릿 옆면의 튀어나온 볼륨 버튼 옆에 있는 평평한 버튼입니다.\n\n전원 버튼을 누르면 화면이 꺼집니다."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"지문 센서는 전원 버튼에 있습니다. 기기 옆면의 튀어나온 볼륨 버튼 옆에 있는 평평한 버튼입니다.\n\n전원 버튼을 누르면 화면이 꺼집니다."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"지문 센서는 전원 버튼에 있습니다. 휴대전화 옆면의 튀어나온 볼륨 버튼 옆에 있는 평평한 버튼입니다.\n\n전원 버튼을 누르면 화면이 꺼집니다."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"지문 센서는 전원 버튼에 있습니다. 태블릿 옆면에 있는 튀어나온 볼륨 버튼 옆의 평평한 버튼입니다."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"지문 센서는 전원 버튼에 있습니다. 기기 옆면에 있는 튀어나온 볼륨 버튼 옆의 평평한 버튼입니다."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"지문 센서는 전원 버튼에 있습니다. 휴대전화 옆면에 있는 튀어나온 볼륨 버튼 옆의 평평한 버튼입니다."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"더 많은 옵션을 확인하려면 휴대전화를 잠금 해제하세요."</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"더 많은 옵션을 확인하려면 태블릿을 잠금 해제하세요."</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"더 많은 옵션을 확인하려면 기기를 잠금 해제하세요."</string>
diff --git a/packages/SystemUI/res-product/values-ky/strings.xml b/packages/SystemUI/res-product/values-ky/strings.xml
index 9e22bfe..0f6acfc 100644
--- a/packages/SystemUI/res-product/values-ky/strings.xml
+++ b/packages/SystemUI/res-product/values-ky/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Телефондун кулпусун <xliff:g id="NUMBER">%d</xliff:g> жолу туура эмес ачууга аракет жасадыңыз. Жумуш профили өчүрүлүп, андагы бардык нерселер өчүрүлөт."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин планшетиңизди бөгөттөн электрондук почтаңыз аркылуу чыгаруу талап кылынат.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракеттениңиз."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Графикалык ачкычты <xliff:g id="NUMBER_0">%1$d</xliff:g> жолу туура эмес тарттыңыз. Дагы <xliff:g id="NUMBER_1">%2$d</xliff:g> ийгиликсиз аракеттен кийин телефонуңузду бөгөттөн электрондук почтаңыз аркылуу чыгаруу талап кылынат.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секунддан кийин кайра аракеттениңиз."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Манжа изинин сенсору кубат баскычында жайгашкан. Бул планшеттин четиндеги үндү катуулатуу/акырындатуу баскычынын жанындагы жалпак баскыч.\n\nКубат баскычы басылса, экран өчөт."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Манжа изинин сенсору кубат баскычында жайгашкан. Ал түзмөктүн четиндеги үндү катуулатуу/акырындатуу баскычынын жанындагы жалпак баскыч.\n\nКубат баскычы басылса, экран өчөт."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Манжа изинин сенсору кубат баскычында жайгашкан. Ал телефондун четиндеги үндү катуулатуу/акырындатуу баскычынын жанындагы жалпак баскыч.\n\nКубат баскычы басылса, экран өчөт."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Манжа изинин сенсору кубат баскычында жайгашкан. Бул планшеттин четиндеги үндү катуулатуу/акырындатуу баскычынын (көтөрүлгөн) жанындагы жалпак баскыч."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Манжа изинин сенсору кубат баскычында жайгашкан. Бул түзмөктүн четиндеги үндү катуулатуу/акырындатуу баскычынын (көтөрүлгөн) жанындагы жалпак баскыч."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Манжа изинин сенсору кубат баскычында жайгашкан. Бул телефондун четиндеги үндү катуулатуу/акырындатуу баскычынын (көтөрүлгөн) жанындагы жалпак баскыч."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Дагы башка параметрлерди көрүү үчүн телефонуңуздун кулпусун ачыңыз"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Дагы башка параметрлерди көрүү үчүн планшетиңиздин кулпусун ачыңыз"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Дагы башка параметрлерди көрүү үчүн түзмөгүңүздүн кулпусун ачыңыз"</string>
diff --git a/packages/SystemUI/res-product/values-lo/strings.xml b/packages/SystemUI/res-product/values-lo/strings.xml
index b022567..fee741d 100644
--- a/packages/SystemUI/res-product/values-lo/strings.xml
+++ b/packages/SystemUI/res-product/values-lo/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ທ່ານພະຍາຍາມປົດລັອກໂທລະສັບຜິດ <xliff:g id="NUMBER">%d</xliff:g> ເທື່ອແລ້ວ. ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກຈະຖືກລຶບອອກ, ເຊິ່ງຈະລຶບຂໍ້ມູນໂປຣໄຟລ໌ທັງໝົດອອກນຳ."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດລັອກແທັບເລັດຂອງທ່ານດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ອີເມວຂອງທ່ານ.\n\n ກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_2">%3$d</xliff:g> ວິນາທີ."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ທ່ານແຕ້ມຮູບແບບປົດລັອກຜິດ <xliff:g id="NUMBER_0">%1$d</xliff:g> ເທື່ອແລ້ວ. ຫຼັງຈາກແຕ້ມຜິດອີກ <xliff:g id="NUMBER_1">%2$d</xliff:g> ເທື່ອ, ທ່ານຈະຖືກຖາມໃຫ້ປົດໂທລະສັບຂອງທ່ານດ້ວຍການເຂົ້າສູ່ລະບົບໂດຍໃຊ້ບັນຊີອີເມວ.\n\n ກະລຸນາລອງໃໝ່ໃນອີກ <xliff:g id="NUMBER_2">%3$d</xliff:g> ວິນາທີ."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"ເຊັນເຊີລາຍນິ້ວມືແມ່ນຢູ່ປຸ່ມເປີດປິດ. ມັນເປັນປຸ່ມຮາບພຽງທີ່ຢູ່ຖັດຈາກປຸ່ມລະດັບສຽງທີ່ຍົກຂຶ້ນມາຢູ່ຂອບຂອງແທັບເລັດ.\n\nການກົດປຸ່ມເປີດປິດຈະປິດໜ້າຈໍ."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"ເຊັນເຊີລາຍນິ້ວມືແມ່ນຢູ່ປຸ່ມເປີດປິດ. ມັນເປັນປຸ່ມຮາບພຽງທີ່ຢູ່ຖັດຈາກປຸ່ມລະດັບສຽງທີ່ຍົກຂຶ້ນມາຢູ່ຂອບຂອງອຸປະກອນ.\n\nການກົດປຸ່ມເປີດປິດຈະປິດໜ້າຈໍ."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"ເຊັນເຊີລາຍນິ້ວມືແມ່ນຢູ່ປຸ່ມເປີດປິດ. ມັນເປັນປຸ່ມຮາບພຽງທີ່ຢູ່ຖັດຈາກປຸ່ມລະດັບສຽງທີ່ຍົກຂຶ້ນມາຢູ່ຂອບຂອງໂທລະສັບ.\n\nການກົດປຸ່ມເປີດປິດຈະປິດໜ້າຈໍ."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ເຊັນເຊີລາຍນິ້ວມືແມ່ນຢູ່ປຸ່ມເປີດປິດ. ມັນເປັນປຸ່ມແປໆທີ່ຢູ່ຖັດຈາກປຸ່ມລະດັບສຽງຢູ່ຂອບຂອງແທັບເລັດ."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ເຊັນເຊີລາຍນິ້ວມືແມ່ນຢູ່ປຸ່ມເປີດປິດ. ມັນເປັນປຸ່ມແປໆທີ່ຢູ່ຖັດຈາກປຸ່ມລະດັບສຽງຢູ່ຂອບຂອງອຸປະກອນ."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ເຊັນເຊີລາຍນິ້ວມືແມ່ນຢູ່ປຸ່ມເປີດປິດ. ມັນເປັນປຸ່ມແປໆທີ່ຢູ່ຖັດຈາກປຸ່ມລະດັບສຽງຢູ່ຂອບຂອງໂທລະສັບ."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ປົດລັອກໂທລະສັບຂອງທ່ານເພື່ອໃຊ້ຕົວເລືອກເພີ່ມເຕີມ"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ປົດລັອກແທັບເລັດຂອງທ່ານເພື່ອໃຊ້ຕົວເລືອກເພີ່ມເຕີມ"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ປົດລັອກອຸປະກອນຂອງທ່ານເພື່ອໃຊ້ຕົວເລືອກເພີ່ມເຕີມ"</string>
diff --git a/packages/SystemUI/res-product/values-lt/strings.xml b/packages/SystemUI/res-product/values-lt/strings.xml
index 945a45e..3035e4f 100644
--- a/packages/SystemUI/res-product/values-lt/strings.xml
+++ b/packages/SystemUI/res-product/values-lt/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> kart. nesėkmingai bandėte atrakinti telefoną. Darbo profilis bus pašalintas ir visi profilio duomenys bus ištrinti."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti planšetinį kompiuterį naudodami el. pašto paskyrą.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"<xliff:g id="NUMBER_0">%1$d</xliff:g> kart. netinkamai nupiešėte atrakinimo piešinį. Po dar <xliff:g id="NUMBER_1">%2$d</xliff:g> nesėkm. band. būsite paprašyti atrakinti telefoną naudodami el. pašto paskyrą.\n\n Bandykite dar kartą po <xliff:g id="NUMBER_2">%3$d</xliff:g> sek."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Piršto atspaudo jutiklis yra ant maitinimo mygtuko. Tai yra plokščias mygtukas šalia iškilusio garsumo mygtuko ant planšetinio kompiuterio krašto.\n\nPaspaudus maitinimo mygtuką išjungiamas ekranas."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Piršto atspaudo jutiklis yra ant maitinimo mygtuko. Tai yra plokščias mygtukas šalia iškilusio garsumo mygtuko ant įrenginio krašto.\n\nPaspaudus maitinimo mygtuką išjungiamas ekranas."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Piršto atspaudo jutiklis yra ant maitinimo mygtuko. Tai yra plokščias mygtukas šalia iškilusio garsumo mygtuko ant telefono krašto.\n\nPaspaudus maitinimo mygtuką išjungiamas ekranas."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Piršto atspaudo jutiklis yra ant maitinimo mygtuko. Tai yra plokščias mygtukas šalia iškilusio garsumo mygtuko ant planšetinio kompiuterio krašto."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Piršto atspaudo jutiklis yra ant maitinimo mygtuko. Tai yra plokščias mygtukas šalia iškilusio garsumo mygtuko ant įrenginio krašto."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Piršto atspaudo jutiklis yra ant maitinimo mygtuko. Tai yra plokščias mygtukas šalia iškilusio garsumo mygtuko ant telefono krašto."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Atrakinkite telefoną, kad galėtumėte naudoti daugiau parinkčių"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Atrakinkite planšetinį kompiuterį, kad galėtumėte naudoti daugiau parinkčių"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Atrakinkite įrenginį, kad galėtumėte naudoti daugiau parinkčių"</string>
diff --git a/packages/SystemUI/res-product/values-lv/strings.xml b/packages/SystemUI/res-product/values-lv/strings.xml
index a7842bd..8e9c064d 100644
--- a/packages/SystemUI/res-product/values-lv/strings.xml
+++ b/packages/SystemUI/res-product/values-lv/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Jūs <xliff:g id="NUMBER">%d</xliff:g> reizi(-es) nesekmīgi mēģinājāt atbloķēt tālruni. Darba profils tiks noņemts, kā arī visi profila dati tiks dzēsti."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nepareizi norādījāt atbloķēšanas kombināciju. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> neveiksmīga(-iem) mēģinājuma(-iem) planšetdators būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Jūs <xliff:g id="NUMBER_0">%1$d</xliff:g> reizi(-es) nepareizi norādījāt atbloķēšanas kombināciju. Pēc vēl <xliff:g id="NUMBER_1">%2$d</xliff:g> nesekmīga(-iem) mēģinājuma(-iem) tālrunis būs jāatbloķē, izmantojot e-pasta kontu.\n\nMēģiniet vēlreiz pēc <xliff:g id="NUMBER_2">%3$d</xliff:g> sekundes(-ēm)."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Pirksta nospieduma sensors atrodas uz barošanas pogas. Barošanas poga ir plakanā poga, kas atrodas blakus augstākai skaļuma pogai planšetdatora sānos.\n\nNospiežot barošanas pogu, tiek izslēgts ekrāns."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Pirksta nospieduma sensors atrodas uz barošanas pogas. Barošanas poga ir plakanā poga, kas atrodas blakus augstākai skaļuma pogai ierīces sānos.\n\nNospiežot barošanas pogu, tiek izslēgts ekrāns."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Pirksta nospieduma sensors atrodas uz barošanas pogas. Barošanas poga ir plakanā poga, kas atrodas blakus augstākai skaļuma pogai tālruņa sānos.\n\nNospiežot barošanas pogu, tiek izslēgts ekrāns."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Pirksta nospieduma sensors atrodas uz barošanas pogas. Tā ir plakanā poga, kas atrodas blakus augstākai skaļuma pogai planšetdatora sānos."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Pirksta nospieduma sensors atrodas uz barošanas pogas. Tā ir plakanā poga, kas atrodas blakus augstākai skaļuma pogai ierīces sānos."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Pirksta nospieduma sensors atrodas uz barošanas pogas. Tā ir plakanā poga, kas atrodas blakus augstākai skaļuma pogai tālruņa sānos."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Atbloķējiet tālruni, lai skatītu citas opcijas."</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Atbloķējiet planšetdatoru, lai skatītu citas opcijas."</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Atbloķējiet ierīci, lai skatītu citas opcijas."</string>
diff --git a/packages/SystemUI/res-product/values-mk/strings.xml b/packages/SystemUI/res-product/values-mk/strings.xml
index 23649d3..6d34f97 100644
--- a/packages/SystemUI/res-product/values-mk/strings.xml
+++ b/packages/SystemUI/res-product/values-mk/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Погрешно се обидовте да го отклучите телефонот <xliff:g id="NUMBER">%d</xliff:g> пати. Работниот профил ќе се отстрани, со што ќе се избришат сите податоци на профилот."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Погрешно ја употребивте вашата шема на отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, ќе побараме да го отклучите таблетот со сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Погрешно ја употребивте вашата шема на отклучување <xliff:g id="NUMBER_0">%1$d</xliff:g> пати. По уште <xliff:g id="NUMBER_1">%2$d</xliff:g> неуспешни обиди, ќе побараме да го отклучите телефонот со сметка на е-пошта.\n\n Обидете се повторно за <xliff:g id="NUMBER_2">%3$d</xliff:g> секунди."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Сензорот за отпечатоци се наоѓа на копчето за вклучување. Тоа е рамното копче веднаш до подигнатото копче за јачина на звук на работ на таблетот.\n\nАко го притиснете копчето за вклучување, ќе се исклучи екранот."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Сензорот за отпечатоци се наоѓа на копчето за вклучување. Тоа е рамното копче веднаш до подигнатото копче за јачина на звук на работ на уредот.\n\nАко го притиснете копчето за вклучување, ќе се исклучи екранот."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Сензорот за отпечатоци се наоѓа на копчето за вклучување. Тоа е рамното копче веднаш до подигнатото копче за јачина на звук на работ на телефонот.\n\nАко го притиснете копчето за вклучување, ќе се исклучи екранот."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сензорот за отпечатоци се наоѓа на копчето за вклучување. Тоа е рамното копче веднаш до подигнатото копче за јачина на звук на работ од таблетот."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сензорот за отпечатоци се наоѓа на копчето за вклучување. Тоа е рамното копче веднаш до подигнатото копче за јачина на звук на работ од уредот."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сензорот за отпечатоци се наоѓа на копчето за вклучување. Тоа е рамното копче веднаш до подигнатото копче за јачина на звук на работ од телефонот."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Отклучето го вашиот телефон за повеќе опции"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Отклучето го вашиот таблет за повеќе опции"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Отклучето го вашиот уред за повеќе опции"</string>
diff --git a/packages/SystemUI/res-product/values-ml/strings.xml b/packages/SystemUI/res-product/values-ml/strings.xml
index 23a8a50..d1e7b4b 100644
--- a/packages/SystemUI/res-product/values-ml/strings.xml
+++ b/packages/SystemUI/res-product/values-ml/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"നിങ്ങൾ <xliff:g id="NUMBER">%d</xliff:g> തവണ തെറ്റായ രീതിയിൽ ഫോൺ അൺലോക്ക് ചെയ്യാൻ ശ്രമിച്ചു. ഔദ്യോഗിക പ്രൊഫൈൽ നീക്കം ചെയ്യപ്പെടുകയും, അതുവഴി എല്ലാ പ്രൊഫൈൽ ഡാറ്റയും ഇല്ലാതാകുകയും ചെയ്യും."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായ രീതിയിൽ അൺലോക്ക് പാറ്റേൺ വരച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഒരു ഇമെയിൽ അക്കൗണ്ടുപയോഗിച്ച് ടാബ്ലെറ്റ് അൺലോക്ക് ചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> സെക്കന്റ് കഴിഞ്ഞ് വീണ്ടും ശ്രമിക്കുക."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"നിങ്ങൾ <xliff:g id="NUMBER_0">%1$d</xliff:g> തവണ തെറ്റായ രീതിയിൽ അൺലോക്ക് പാറ്റേൺ വരച്ചു. <xliff:g id="NUMBER_1">%2$d</xliff:g> ശ്രമങ്ങൾ കൂടി പരാജയപ്പെട്ടാൽ, ഒരു ഇമെയിൽ അക്കൗണ്ടുപയോഗിച്ച് ഫോൺ അൺലോക്ക് ചെയ്യാൻ നിങ്ങളോട് ആവശ്യപ്പെടും.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> സെക്കന്റ് കഴിഞ്ഞ് വീണ്ടും ശ്രമിക്കുക."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"പവർ ബട്ടണിലാണ് ഫിംഗർപ്രിന്റ് സെൻസർ ഉള്ളത്. ടാബ്ലെറ്റിന്റെ അരികിൽ ഉയർന്ന് നിൽക്കുന്ന ശബ്ദ ബട്ടണിന്റെ അടുത്തുള്ള പരന്ന ബട്ടൺ ആണ് ഇത്.\n\nപവർ ബട്ടൺ അമർത്തുമ്പോൾ സ്ക്രീൻ ഓഫാകും."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"പവർ ബട്ടണിലാണ് ഫിംഗർപ്രിന്റ് സെൻസർ ഉള്ളത്. ഉപകരണത്തിന്റെ അരികിൽ ഉയർന്ന് നിൽക്കുന്ന ശബ്ദ ബട്ടണിന്റെ അടുത്തുള്ള പരന്ന ബട്ടൺ ആണ് ഇത്.\n\nപവർ ബട്ടൺ അമർത്തുമ്പോൾ സ്ക്രീൻ ഓഫാകും."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"പവർ ബട്ടണിലാണ് ഫിംഗർപ്രിന്റ് സെൻസർ ഉള്ളത്. ഫോണിന്റെ അരികിൽ ഉയർന്ന് നിൽക്കുന്ന ശബ്ദ ബട്ടണിന്റെ അടുത്തുള്ള പരന്ന ബട്ടൺ ആണ് ഇത്.\n\nപവർ ബട്ടൺ അമർത്തുമ്പോൾ സ്ക്രീൻ ഓഫാകും."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"പവർ ബട്ടണിലാണ് ഫിംഗർപ്രിന്റ് സെൻസർ ഉള്ളത്. ടാബ്ലെറ്റിന്റെ അറ്റത്ത് ഉയർന്ന് നിൽക്കുന്ന ശബ്ദ ബട്ടണിന്റെ അടുത്തുള്ള പരന്ന ബട്ടൺ ആണ് ഇത്."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"പവർ ബട്ടണിലാണ് ഫിംഗർപ്രിന്റ് സെൻസർ ഉള്ളത്. ഉപകരണത്തിന്റെ അറ്റത്ത് ഉയർന്ന് നിൽക്കുന്ന ശബ്ദ ബട്ടണിന്റെ അടുത്തുള്ള പരന്ന ബട്ടൺ ആണ് ഇത്."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"പവർ ബട്ടണിലാണ് ഫിംഗർപ്രിന്റ് സെൻസർ ഉള്ളത്. ഫോണിന്റെ അറ്റത്ത് ഉയർന്ന് നിൽക്കുന്ന ശബ്ദ ബട്ടണിന്റെ അടുത്തുള്ള പരന്ന ബട്ടൺ ആണ് ഇത്."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് നിങ്ങളുടെ ഫോൺ അൺലോക്ക് ചെയ്യുക"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് നിങ്ങളുടെ ടാബ്ലെറ്റ് അൺലോക്ക് ചെയ്യുക"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"കൂടുതൽ ഓപ്ഷനുകൾക്ക് നിങ്ങളുടെ ഉപകരണം അൺലോക്ക് ചെയ്യുക"</string>
diff --git a/packages/SystemUI/res-product/values-mn/strings.xml b/packages/SystemUI/res-product/values-mn/strings.xml
index f0fce01..1cc1a1c 100644
--- a/packages/SystemUI/res-product/values-mn/strings.xml
+++ b/packages/SystemUI/res-product/values-mn/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Та утасны түгжээг тайлах оролдлогыг <xliff:g id="NUMBER">%d</xliff:g> удаа буруу хийсэн байна. Ажлын профайлыг устгах бөгөөд ингэснээр профайлын бүх өгөгдлийг устгах болно."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Та тайлах хээгээ <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу зурсан байна. Дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу зурсны дараа та имэйл бүртгэл ашиглан таблетынхаа түгжээг тайлах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундийн дараа дахин оролдоно уу."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Та тайлах хээгээ <xliff:g id="NUMBER_0">%1$d</xliff:g> удаа буруу зурсан байна. Дахин <xliff:g id="NUMBER_1">%2$d</xliff:g> удаа буруу зурсны дараа та имэйл бүртгэл ашиглан утасныхаа түгжээг тайлах шаардлагатай болно.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> секундийн дараа дахин оролдоно уу."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Хурууны хээ мэдрэгч асаах/унтраах товчин дээр байдаг. Энэ нь таблетын ирмэг дээрх дууны түвшний товгор товчлуурын хажууд байх хавтгай товчлуур юм.\n\nАсаах/унтраах товчийг дарснаар дэлгэц унтарна."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Хурууны хээ мэдрэгч асаах/унтраах товчин дээр байдаг. Энэ нь төхөөрөмжийн ирмэг дээрх дууны түвшний товгор товчлуурын хажууд байх хавтгай товчлуур юм.\n\nАсаах/унтраах товчийг дарснаар дэлгэц унтарна."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Хурууны хээ мэдрэгч асаах/унтраах товчин дээр байдаг. Энэ нь утасны ирмэг дээрх дууны түвшний товгор товчлуурын хажууд байх хавтгай товчлуур юм.\n\nАсаах/унтраах товчийг дарснаар дэлгэц унтарна."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Хурууны хээ мэдрэгч асаах/унтраах товчин дээр байдаг. Энэ нь таблетын ирмэг дээрх дууны түвшний товгор товчлуурын хажууд байх хавтгай товчлуур юм."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Хурууны хээ мэдрэгч асаах/унтраах товчин дээр байдаг. Энэ нь төхөөрөмжийн ирмэг дээрх дууны түвшний товгор товчлуурын хажууд байх хавтгай товчлуур юм."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Хурууны хээ мэдрэгч асаах/унтраах товчин дээр байдаг. Энэ нь утасны ирмэг дээрх дууны түвшний товгор товчлуурын хажууд байх хавтгай товчлуур юм."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Бусад сонголтыг харахын тулд утасныхаа түгжээг тайлна уу"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Бусад сонголтыг харахын тулд таблетынхаа түгжээг тайлна уу"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Бусад сонголтыг харахын тулд төхөөрөмжийнхөө түгжээг тайлна уу"</string>
diff --git a/packages/SystemUI/res-product/values-mr/strings.xml b/packages/SystemUI/res-product/values-mr/strings.xml
index e76b185..feb9604 100644
--- a/packages/SystemUI/res-product/values-mr/strings.xml
+++ b/packages/SystemUI/res-product/values-mr/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"तुम्ही फोन अनलॉक करण्याचा <xliff:g id="NUMBER">%d</xliff:g> वेळा चुकीच्या पद्धतीने प्रयत्न केला आहे. कार्य प्रोफाइल काढली जाईल, त्यामुळे सर्व प्रोफाइल डेटा हटवला जाईल."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा टॅबलेट अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"तुम्ही तुमचा अनलॉक पॅटर्न <xliff:g id="NUMBER_0">%1$d</xliff:g> वेळा चुकीच्या पद्धतीने काढला आहे. आणखी <xliff:g id="NUMBER_1">%2$d</xliff:g> अयशस्वी प्रयत्नांनंतर, तुम्हाला ईमेल खाते वापरून तुमचा फोन अनलॉक करण्यास सांगितले जाईल.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकंदांमध्ये पुन्हा प्रयत्न करा."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"फिंगरप्रिंट सेन्सर हे पॉवर बटणावर आहे. हे टॅबलेटच्या कडेला वरती आलेल्या व्हॉल्यूम बटणाच्या बाजूला असलेले सपाट बटण आहे.\n\nपॉवर बटण प्रेस केल्याने स्क्रीन बंद होते."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"फिंगरप्रिंट सेन्सर हे पॉवर बटणावर आहे. हे डिव्हाइसच्या कडेला वरती आलेल्या व्हॉल्यूम बटणाच्या बाजूला असलेले सपाट बटण आहे.\n\nपॉवर बटण प्रेस केल्याने स्क्रीन बंद होते."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"फिंगरप्रिंट सेन्सर हे पॉवर बटणावर आहे. हे फोनच्या कडेला वरती आलेल्या व्हॉल्यूम बटणाच्या बाजूला असलेले सपाट बटण आहे.\n\nपॉवर बटण प्रेस केल्याने स्क्रीन बंद होते."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"फिंगरप्रिंट सेन्सर हे पॉवर बटणावर आहे. टॅबलेटच्या कडेला वर आलेल्या व्हॉल्यूम बटणाच्या बाजूला असलेले सपाट बटण म्हणजे पॉवर बटण."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"फिंगरप्रिंट सेन्सर हे पॉवर बटणावर आहे. डिव्हाइसच्या कडेला वरती आलेल्या व्हॉल्यूम बटणाच्या बाजूला असलेले सपाट बटण म्हणजे पॉवर बटण."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"फिंगरप्रिंट सेन्सर हे पॉवर बटणावर आहे. फोनच्या कडेला वर आलेल्या व्हॉल्यूम बटणाच्या बाजूला असलेले सपाट बटण म्हणजे पॉवर बटण."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"आणखी पर्यायांसाठी तुमचा फोन अनलॉक करा"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"आणखी पर्यायांसाठी तुमचा टॅबलेट अनलॉक करा"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"आणखी पर्यायांसाठी तुमचे डिव्हाइस अनलॉक करा"</string>
diff --git a/packages/SystemUI/res-product/values-ms/strings.xml b/packages/SystemUI/res-product/values-ms/strings.xml
index 1db5ded..e1e6976 100644
--- a/packages/SystemUI/res-product/values-ms/strings.xml
+++ b/packages/SystemUI/res-product/values-ms/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Anda telah salah membuka kunci telefon sebanyak <xliff:g id="NUMBER">%d</xliff:g> kali. Profil kerja ini akan dialih keluar sekali gus memadamkan semua data profil."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, anda akan diminta membuka kunci tablet anda menggunakan akaun e-mel.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Anda telah tersilap lukis corak buka kunci sebanyak <xliff:g id="NUMBER_0">%1$d</xliff:g> kali. Selepas <xliff:g id="NUMBER_1">%2$d</xliff:g> lagi percubaan yang gagal, anda akan diminta membuka kunci telefon anda menggunakan akaun e-mel.\n\n Cuba lagi dalam <xliff:g id="NUMBER_2">%3$d</xliff:g> saat."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Penderia cap jari berada pada butang kuasa. Penderia cap jari ialah butang rata yang terletak bersebelahan butang kelantangan yang timbul pada bahagian tepi tablet.\n\nPenekanan butang kuasa akan mematikan skrin."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Penderia cap jari berada pada butang kuasa. Penderia cap jari ialah butang rata yang terletak bersebelahan butang kelantangan yang timbul pada bahagian tepi peranti.\n\nPenekanan butang kuasa akan mematikan skrin."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Penderia cap jari berada pada butang kuasa. Penderia cap jari ialah butang rata yang terletak bersebelahan butang kelantangan yang timbul pada bahagian tepi telefon.\n\nPenekanan butang kuasa akan mematikan skrin."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Penderia cap jari berada pada butang kuasa. Penderia cap jari ialah butang leper yang terletak bersebelahan butang kelantangan timbul pada bahagian tepi tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Penderia cap jari berada pada butang kuasa. Penderia cap jari ialah butang leper yang terletak bersebelahan butang kelantangan timbul pada bahagian tepi peranti."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Penderia cap jari berada pada butang kuasa. Penderia cap jari ialah butang leper yang terletak bersebelahan butang kelantangan timbul pada bahagian tepi telefon."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Buka kunci telefon anda untuk mendapatkan lagi pilihan"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Buka kunci tablet anda untuk mendapatkan lagi pilihan"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Buka kunci peranti anda untuk mendapatkan lagi pilihan"</string>
diff --git a/packages/SystemUI/res-product/values-my/strings.xml b/packages/SystemUI/res-product/values-my/strings.xml
index 7b56302..4ec1ff6 100644
--- a/packages/SystemUI/res-product/values-my/strings.xml
+++ b/packages/SystemUI/res-product/values-my/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ဖုန်းကို <xliff:g id="NUMBER">%d</xliff:g> ကြိမ် မှားယွင်းစွာ လော့ခ်ဖွင့်ရန် ကြိုးစားခဲ့ပါသည်။ အလုပ်ပရိုဖိုင်ကို ဖယ်ရှားလိုက်မည်ဖြစ်ပြီး ပရိုဖိုင်ဒေတာ အားလုံးကိုလည်း ဖျက်လိုက်ပါမည်။"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"သင်သည် သင်၏ လော့ခ်ဖွင့်ခြင်းပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းပြီးသည့်နောက်တွင် သင့်အီးမေးလ်အကောင့်အား အသုံးပြု၍ တက်ဘလက်ကို လော့ခ်ဖွင့်ရန် တောင်းဆိုသွားပါမည်။\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"သင်သည် သင်၏ လော့ခ်ဖွင့်ခြင်းပုံစံကို <xliff:g id="NUMBER_0">%1$d</xliff:g> ကြိမ် မှားယွင်းစွာ ဆွဲခဲ့ပါသည်။ <xliff:g id="NUMBER_1">%2$d</xliff:g> ကြိမ် ထပ်မံမှားယွင်းပြီးသည့်နောက်တွင် သင့်အီးမေးလ်အကောင့်အား အသုံးပြု၍ ဖုန်းကို လော့ခ်ဖွင့်ရန် တောင်းဆိုသွားပါမည်။\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> စက္ကန့်အကြာတွင် ထပ်စမ်းကြည့်ပါ။"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"လက်ဗွေ အာရုံခံကိရိယာသည် ဖွင့်ပိတ်ခလုတ်ပေါ်တွင် ရှိသည်။ တက်ဘလက်ဘေးဘက်ရှိ မြင့်တက်နေသည့်အသံထိန်း ခလုတ်၏ ကပ်လျက်ရှိ ခလုတ်ပြားဖြစ်သည်။\n\nဖွင့်ပိတ်ခလုတ်ကိုနှိပ်ပါက ဖန်သားပြင်ပိတ်သွားမည်။"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"လက်ဗွေ အာရုံခံကိရိယာသည် ဖွင့်ပိတ်ခလုတ်ပေါ်တွင် ရှိသည်။ စက်ဘေးဘက်ရှိ မြင့်တက်နေသည့်အသံထိန်း ခလုတ်၏ ကပ်လျက်ရှိ ခလုတ်ပြားဖြစ်သည်။\n\nဖွင့်ပိတ်ခလုတ်ကိုနှိပ်ပါက ဖန်သားပြင်ပိတ်သွားမည်။"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"လက်ဗွေ အာရုံခံကိရိယာသည် ဖွင့်ပိတ်ခလုတ်ပေါ်တွင် ရှိသည်။ ဖုန်းဘေးဘက်ရှိ မြင့်တက်နေသည့်အသံထိန်း ခလုတ်၏ ကပ်လျက်ရှိ ခလုတ်ပြားဖြစ်သည်။\n\nဖွင့်ပိတ်ခလုတ်ကိုနှိပ်ပါက ဖန်သားပြင်ပိတ်သွားမည်။"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"လက်ဗွေ အာရုံခံကိရိယာသည် ဖွင့်ပိတ်ခလုတ်ပေါ်တွင် ရှိသည်။ တက်ဘလက်၏ဘေးဘက်ရှိ အသံထိန်းခလုတ်ဖုသီးနှင့် ကပ်လျက်မှ ခလုတ်ပြားဖြစ်သည်။"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"လက်ဗွေ အာရုံခံကိရိယာသည် ဖွင့်ပိတ်ခလုတ်ပေါ်တွင် ရှိသည်။ စက်၏ဘေးဘက်ရှိ အသံထိန်းခလုတ်ဖုသီးနှင့် ကပ်လျက်မှ ခလုတ်ပြားဖြစ်သည်။"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"လက်ဗွေ အာရုံခံကိရိယာသည် ဖွင့်ပိတ်ခလုတ်ပေါ်တွင် ရှိသည်။ ဖုန်း၏ဘေးဘက်ရှိ အသံထိန်းခလုတ်ဖုသီးနှင့် ကပ်လျက်မှ ခလုတ်ပြားဖြစ်သည်။"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"နောက်ထပ် ထိန်းချုပ်မှုများအတွက် သင့်ဖုန်းကို လော့ခ်ဖွင့်ပါ"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"နောက်ထပ် ထိန်းချုပ်မှုများအတွက် သင့်တက်ဘလက်ကို လော့ခ်ဖွင့်ပါ"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"နောက်ထပ် ထိန်းချုပ်မှုများအတွက် သင့်စက်ကို လော့ခ်ဖွင့်ပါ"</string>
diff --git a/packages/SystemUI/res-product/values-nb/strings.xml b/packages/SystemUI/res-product/values-nb/strings.xml
index 621b393..4b16a43 100644
--- a/packages/SystemUI/res-product/values-nb/strings.xml
+++ b/packages/SystemUI/res-product/values-nb/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Du har gjort feil i forsøket på å låse opp telefonen <xliff:g id="NUMBER">%d</xliff:g> ganger. Jobbprofilen blir fjernet, og alle profildataene blir slettet."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Du har tegnet opplåsingsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk blir du bedt om å låse opp nettbrettet via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Du har tegnet opplåsingsmønsteret feil <xliff:g id="NUMBER_0">%1$d</xliff:g> ganger. Etter ytterligere <xliff:g id="NUMBER_1">%2$d</xliff:g> nye mislykkede forsøk blir du bedt om å låse opp telefonen via en e-postkonto.\n\n Prøv på nytt om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Fingeravtrykkssensoren er på av/på-knappen. Det er den flate knappen ved siden av den opphøyde volumknappen på kanten av nettbrettet.\n\nHvis du trykker på av/på-knappen, slås skjermen av."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Fingeravtrykkssensoren er på av/på-knappen. Det er den flate knappen ved siden av den opphøyde volumknappen på kanten av enheten.\n\nHvis du trykker på av/på-knappen, slås skjermen av."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Fingeravtrykkssensoren er på av/på-knappen. Det er den flate knappen ved siden av den opphøyde volumknappen på kanten av telefonen.\n\nHvis du trykker på av/på-knappen, slås skjermen av."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Fingeravtrykkssensoren er på av/på-knappen. Det er den flate knappen ved siden av den hevede volumknappen på siden av nettbrettet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Fingeravtrykkssensoren er på av/på-knappen. Det er den flate knappen ved siden av den hevede volumknappen på siden av enheten."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Fingeravtrykkssensoren er på av/på-knappen. Det er den flate knappen ved siden av den hevede volumknappen på siden av telefonen."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Lås opp telefonen din for å få flere alternativer"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Lås opp nettbrettet ditt for å få flere alternativer"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Lås opp enheten din for å få flere alternativer"</string>
diff --git a/packages/SystemUI/res-product/values-ne/strings.xml b/packages/SystemUI/res-product/values-ne/strings.xml
index 5a56c54..7276e23 100644
--- a/packages/SystemUI/res-product/values-ne/strings.xml
+++ b/packages/SystemUI/res-product/values-ne/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"तपाईंले <xliff:g id="NUMBER">%d</xliff:g> पटक गलत तरिकाले फोन अनलक गर्ने प्रयास गर्नुभएको छ। कार्य प्रोफाइललाई यसका सबै डेटा मेटिने गरी हटाइने छ।"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> पटक असफल प्रयास गरेपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो ट्याब्लेट अनलक गर्न आग्रह गरिने छ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"तपाईंले <xliff:g id="NUMBER_0">%1$d</xliff:g> पटक आफ्नो अनलक गर्ने ढाँचा गलत रूपमा कोर्नुभयो। थप <xliff:g id="NUMBER_1">%2$d</xliff:g> पटक असफल प्रयास गरेपछि, तपाईंलाई एउटा इमेल खाता प्रयोग गरेर आफ्नो फोन अनलक गर्न आग्रह गरिने छ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> सेकेन्डमा फेरि प्रयास गर्नुहोस्।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"फिंगरप्रिन्ट सेन्सर पावर बटनमा छ। यो बटन ट्याब्लेटको किनारामा रहेको थोरै उचालिएको भोल्युम बटनको छेउमा रहेको समतल बटन हो।\n\nतपाईंले पावर बटन थिच्नुभयो भने स्क्रिन अफ हुन्छ।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"फिंगरप्रिन्ट सेन्सर पावर बटनमा छ। यो बटन डिभाइसको किनारामा रहेको थोरै उचालिएको भोल्युम बटनको छेउमा रहेको समतल बटन हो।\n\nतपाईंले पावर बटन थिच्नुभयो भने स्क्रिन अफ हुन्छ।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"फिंगरप्रिन्ट सेन्सर पावर बटनमा छ। यो बटन फोनको किनारामा रहेको थोरै उचालिएको भोल्युम बटनको छेउमा रहेको समतल बटन हो।\n\nतपाईंले पावर बटन थिच्नुभयो भने स्क्रिन अफ हुन्छ।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"फिंगरप्रिन्ट सेन्सर पावर बटनमा हुन्छ। यो ट्याब्लेटको किनारामा रहेको थोरै उचालिएको भोल्युम बटनको छेउमा रहेको चेप्टो बटन नै पावर बटन हो।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"फिंगरप्रिन्ट सेन्सर पावर बटनमा हुन्छ। यो डिभाइसको किनारामा रहेको थोरै उचालिएको भोल्युम बटनको छेउमा रहेको चेप्टो बटन नै पावर बटन हो।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"फिंगरप्रिन्ट सेन्सर पावर बटनमा हुन्छ। यो फोनको किनारामा रहेको थोरै उचालिएको भोल्युम बटनको छेउमा रहेको चेप्टो बटन नै पावर बटन हो।"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"थप विकल्पहरू हेर्न आफ्नो फोन अनलक गर्नुहोस्"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"थप विकल्पहरू हेर्न आफ्नो ट्याब्लेट अनलक गर्नुहोस्"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"थप विकल्पहरू हेर्न आफ्नो डिभाइस अनलक गर्नुहोस्"</string>
diff --git a/packages/SystemUI/res-product/values-nl/strings.xml b/packages/SystemUI/res-product/values-nl/strings.xml
index b2343c3..6109e17 100644
--- a/packages/SystemUI/res-product/values-nl/strings.xml
+++ b/packages/SystemUI/res-product/values-nl/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Je hebt <xliff:g id="NUMBER">%d</xliff:g> mislukte pogingen ondernomen om de telefoon te ontgrendelen. Het werkprofiel wordt verwijderd, waardoor alle profielgegevens worden verwijderd."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt je gevraagd je tablet te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Je hebt je ontgrendelingspatroon <xliff:g id="NUMBER_0">%1$d</xliff:g> keer onjuist getekend. Na nog eens <xliff:g id="NUMBER_1">%2$d</xliff:g> mislukte pogingen wordt je gevraagd je telefoon te ontgrendelen via een e-mailaccount.\n\n Probeer het over <xliff:g id="NUMBER_2">%3$d</xliff:g> seconden opnieuw."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Je vindt de vingerafdruksensor onder de aan/uit-knop. Het is de platte knop naast de verhoogde volumeknop aan de zijkant van de tablet.\n\nAls je op de aan/uit-knop drukt, gaat het scherm uit."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Je vindt de vingerafdruksensor onder de aan/uit-knop. Het is de platte knop naast de verhoogde volumeknop aan de zijkant van het apparaat.\n\nAls je op de aan/uit-knop drukt, gaat het scherm uit."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Je vindt de vingerafdruksensor onder de aan/uit-knop. Het is de platte knop naast de verhoogde volumeknop aan de zijkant van de telefoon.\n\nAls je op de aan/uit-knop drukt, gaat het scherm uit."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Je vindt de vingerafdruksensor onder de aan/uit-knop. Het is de platte knop naast de verhoogde volumeknop aan de zijkant van de tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Je vindt de vingerafdruksensor onder de aan/uit-knop. Het is de platte knop naast de verhoogde volumeknop aan de zijkant van het apparaat."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Je vindt de vingerafdruksensor onder de aan/uit-knop. Het is de platte knop naast de verhoogde volumeknop aan de zijkant van de telefoon."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ontgrendel je telefoon voor meer opties"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ontgrendel je tablet voor meer opties"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ontgrendel je apparaat voor meer opties"</string>
diff --git a/packages/SystemUI/res-product/values-or/strings.xml b/packages/SystemUI/res-product/values-or/strings.xml
index 85efb09..dde1aa8 100644
--- a/packages/SystemUI/res-product/values-or/strings.xml
+++ b/packages/SystemUI/res-product/values-or/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ଆପଣ ଫୋନ୍କୁ ଅନ୍ଲକ୍ କରିବାକୁ<xliff:g id="NUMBER">%d</xliff:g>ଥର ଭୁଲ ପ୍ରୟାସ କରିଛନ୍ତି। କାର୍ଯ୍ୟ ପ୍ରୋଫାଇଲ୍ ବାହାର କରିଦିଆଯିବ, ଯାହା ଫଳରେ ସମସ୍ତ ପ୍ରୋଫାଇଲ୍ ଡାଟା ଡିଲିଟ୍ ହେବ।"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ଆପଣ ଆପଣଙ୍କ ଅନ୍ଲକ୍ ପାଟର୍ନକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଡ୍ର କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ ଆପଣଙ୍କୁ ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ଆପଣଙ୍କ ଟାବ୍ଲୋଟ୍କୁ ଅନ୍ଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ଆପଣ ଆପଣଙ୍କ ଅନ୍ଲକ୍ ପାଟର୍ନକୁ <xliff:g id="NUMBER_0">%1$d</xliff:g>ଥର ଭୁଲ ଭାବେ ଡ୍ର କରିଛନ୍ତି। ଆଉ <xliff:g id="NUMBER_1">%2$d</xliff:g>ଟି ଭୁଲ ପ୍ରୟାସ ପରେ ଆପଣଙ୍କୁ ଏକ ଇମେଲ୍ ଆକାଉଣ୍ଟ ବ୍ୟବହାର କରି ଆପଣଙ୍କ ଫୋନ୍କୁ ଅନ୍ଲକ୍ କରିବା ପାଇଁ କୁହାଯିବ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ସେକେଣ୍ଡ ପରେ ପୁଣି ଚେଷ୍ଟା କରନ୍ତୁ।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"ଟିପଚିହ୍ନ ସେନ୍ସର ପାୱାର ବଟନରେ ଅଛି। ଟାବଲେଟର ଧାରରେ ଥିବା ବଢ଼ାଯାଇଥିବା ଭଲ୍ୟୁମ ବଟନ ପାଖରେ ଏହା ଫ୍ଲାଟ ବଟନ ଅଟେ।\n\nପାୱାର ବଟନକୁ ଦବାଇବା ଦ୍ୱାରା ସ୍କ୍ରିନ ବନ୍ଦ ହୋଇଥାଏ।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"ଟିପଚିହ୍ନ ସେନ୍ସର ପାୱାର ବଟନରେ ଅଛି। ଡିଭାଇସର ଧାରରେ ଥିବା ବଢ଼ାଯାଇଥିବା ଭଲ୍ୟୁମ ବଟନ ପାଖରେ ଏହା ଫ୍ଲାଟ ବଟନ ଅଟେ।\n\nପାୱାର ବଟନକୁ ଦବାଇବା ଦ୍ୱାରା ସ୍କ୍ରିନ ବନ୍ଦ ହୋଇଥାଏ।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"ଟିପଚିହ୍ନ ସେନ୍ସର ପାୱାର ବଟନରେ ଅଛି। ଫୋନର ଧାରରେ ଥିବା ବଢ଼ାଯାଇଥିବା ଭଲ୍ୟୁମ ବଟନ ପାଖରେ ଏହା ଫ୍ଲାଟ ବଟନ ଅଟେ।\n\nପାୱାର ବଟନକୁ ଦବାଇବା ଦ୍ୱାରା ସ୍କ୍ରିନ ବନ୍ଦ ହୋଇଥାଏ।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ଟିପଚିହ୍ନ ସେନ୍ସର ପାୱାର ବଟନରେ ଅଛି। ଏହା ଟାବଲେଟର ଧାରରେ ବଢ଼ାଯାଇଥିବା ଭଲ୍ୟୁମ ବଟନ ପାଖରେ ଥିବା ଫ୍ଲାଟ ବଟନ ଅଟେ।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ଟିପଚିହ୍ନ ସେନ୍ସର ପାୱାର ବଟନରେ ଅଛି। ଏହା ଡିଭାଇସର ଧାରରେ ବଢ଼ାଯାଇଥିବା ଭଲ୍ୟୁମ ବଟନ ପାଖରେ ଥିବା ଫ୍ଲାଟ ବଟନ ଅଟେ।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ଟିପଚିହ୍ନ ସେନ୍ସର ପାୱାର ବଟନରେ ଅଛି। ଏହା ଫୋନର ଧାରରେ ବଢ଼ାଯାଇଥିବା ଭଲ୍ୟୁମ ବଟନ ପାଖରେ ଥିବା ଫ୍ଲାଟ ବଟନ ଅଟେ।"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଆପଣଙ୍କ ଫୋନ୍ ଅନଲକ୍ କରନ୍ତୁ"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଆପଣଙ୍କ ଟାବଲେଟ୍ ଅନଲକ୍ କରନ୍ତୁ"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ଅଧିକ ବିକଳ୍ପ ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସ୍ ଅନଲକ୍ କରନ୍ତୁ"</string>
diff --git a/packages/SystemUI/res-product/values-pa/strings.xml b/packages/SystemUI/res-product/values-pa/strings.xml
index 149e58f..38fd890 100644
--- a/packages/SystemUI/res-product/values-pa/strings.xml
+++ b/packages/SystemUI/res-product/values-pa/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ਤੁਸੀਂ <xliff:g id="NUMBER">%d</xliff:g> ਵਾਰ ਗਲਤ ਢੰਗ ਨਾਲ ਫ਼ੋਨ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਦੀ ਕੋਸ਼ਿਸ਼ ਕੀਤੀ ਹੈ। ਕਾਰਜ ਪ੍ਰੋਫਾਈਲ ਹਟਾ ਦਿੱਤਾ ਜਾਵੇਗਾ, ਜਿਸ ਨਾਲ ਸਾਰਾ ਪ੍ਰੋਫਾਈਲ ਡਾਟਾ ਮਿਟ ਜਾਵੇਗਾ।"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਉਲੀਕਿਆ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣੇ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਵੇਗਾ।\n\n<xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ਤੁਸੀਂ <xliff:g id="NUMBER_0">%1$d</xliff:g> ਵਾਰ ਆਪਣਾ ਅਣਲਾਕ ਪੈਟਰਨ ਗਲਤ ਢੰਗ ਨਾਲ ਡ੍ਰਾ ਕੀਤਾ ਹੈ। <xliff:g id="NUMBER_1">%2$d</xliff:g> ਹੋਰ ਅਸਫਲ ਕੋਸ਼ਿਸ਼ਾਂ ਤੋਂ ਬਾਅਦ, ਤੁਹਾਨੂੰ ਇੱਕ ਈਮੇਲ ਖਾਤਾ ਵਰਤਦੇ ਹੋਏ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਕਰਨ ਲਈ ਕਿਹਾ ਜਾਏਗਾ।\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> ਸਕਿੰਟਾਂ ਵਿੱਚ ਦੁਬਾਰਾ ਕੋਸ਼ਿਸ਼ ਕਰੋ।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਪਾਵਰ ਬਟਨ \'ਤੇ ਹੈ। ਇਹ ਟੈਬਲੈੱਟ ਦੇ ਕਿਨਾਰੇ \'ਤੇ ਅਜਿਹਾ ਸਮਤਲ ਬਟਨ ਹੁੰਦਾ ਹੈ ਜੋ ਉੱਭਰੇ ਹੋਏ ਅਵਾਜ਼ ਬਟਨ ਦੇ ਅੱਗੇ ਹੁੰਦਾ ਹੈ।\n\nਪਾਵਰ ਬਟਨ ਦਬਾਉਣ ਨਾਲ ਸਕ੍ਰੀਨ ਬੰਦ ਹੋ ਜਾਂਦੀ ਹੈ।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਪਾਵਰ ਬਟਨ \'ਤੇ ਹੈ। ਇਹ ਡੀਵਾਈਸ ਦੇ ਕਿਨਾਰੇ \'ਤੇ ਅਜਿਹਾ ਸਮਤਲ ਬਟਨ ਹੁੰਦਾ ਹੈ ਜੋ ਉੱਭਰੇ ਹੋਏ ਅਵਾਜ਼ ਬਟਨ ਦੇ ਅੱਗੇ ਹੁੰਦਾ ਹੈ।\n\nਪਾਵਰ ਬਟਨ ਦਬਾਉਣ ਨਾਲ ਸਕ੍ਰੀਨ ਬੰਦ ਹੋ ਜਾਂਦੀ ਹੈ।"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਪਾਵਰ ਬਟਨ \'ਤੇ ਹੈ। ਇਹ ਫ਼ੋਨ ਦੇ ਕਿਨਾਰੇ \'ਤੇ ਅਜਿਹਾ ਸਮਤਲ ਬਟਨ ਹੁੰਦਾ ਹੈ ਜੋ ਉੱਭਰੇ ਹੋਏ ਅਵਾਜ਼ ਬਟਨ ਦੇ ਅੱਗੇ ਹੁੰਦਾ ਹੈ।\n\nਪਾਵਰ ਬਟਨ ਦਬਾਉਣ ਨਾਲ ਸਕ੍ਰੀਨ ਬੰਦ ਹੋ ਜਾਂਦੀ ਹੈ।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਪਾਵਰ ਬਟਨ \'ਤੇ ਹੈ। ਇਹ ਟੈਬਲੈੱਟ ਦੇ ਕਿਨਾਰੇ \'ਤੇ ਅਜਿਹਾ ਸਮਤਲ ਬਟਨ ਹੁੰਦਾ ਹੈ ਜੋ ਉੱਭਰੇ ਹੋਏ ਅਵਾਜ਼ ਬਟਨ ਦੇ ਅੱਗੇ ਹੁੰਦਾ ਹੈ।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਪਾਵਰ ਬਟਨ \'ਤੇ ਹੈ। ਇਹ ਡੀਵਾਈਸ ਦੇ ਕਿਨਾਰੇ \'ਤੇ ਅਜਿਹਾ ਸਮਤਲ ਬਟਨ ਹੁੰਦਾ ਹੈ ਜੋ ਉੱਭਰੇ ਹੋਏ ਅਵਾਜ਼ ਬਟਨ ਦੇ ਅੱਗੇ ਹੁੰਦਾ ਹੈ।"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ਫਿੰਗਰਪ੍ਰਿੰਟ ਸੈਂਸਰ ਪਾਵਰ ਬਟਨ \'ਤੇ ਹੈ। ਇਹ ਫ਼ੋਨ ਦੇ ਕਿਨਾਰੇ \'ਤੇ ਅਜਿਹਾ ਸਮਤਲ ਬਟਨ ਹੁੰਦਾ ਹੈ ਜੋ ਉੱਭਰੇ ਹੋਏ ਅਵਾਜ਼ ਬਟਨ ਦੇ ਅੱਗੇ ਹੁੰਦਾ ਹੈ।"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਆਪਣਾ ਫ਼ੋਨ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਆਪਣਾ ਟੈਬਲੈੱਟ ਅਣਲਾਕ ਕਰੋ"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ਹੋਰ ਵਿਕਲਪਾਂ ਲਈ ਆਪਣਾ ਡੀਵਾਈਸ ਅਣਲਾਕ ਕਰੋ"</string>
diff --git a/packages/SystemUI/res-product/values-pl/strings.xml b/packages/SystemUI/res-product/values-pl/strings.xml
index dcd2736..7dc2ded 100644
--- a/packages/SystemUI/res-product/values-pl/strings.xml
+++ b/packages/SystemUI/res-product/values-pl/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Po raz <xliff:g id="NUMBER">%d</xliff:g> próbowano nieprawidłowo odblokować telefon. Profil służbowy zostanie usunięty, co spowoduje skasowanie wszystkich jego danych."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowano wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie tabletu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Po raz <xliff:g id="NUMBER_0">%1$d</xliff:g> nieprawidłowo narysowano wzór odblokowania. Po kolejnych <xliff:g id="NUMBER_1">%2$d</xliff:g> nieudanych próbach konieczne będzie odblokowanie telefonu przy użyciu konta e-mail.\n\n Spróbuj ponownie za <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Czytnik linii papilarnych znajduje się na przycisku zasilania. To płaski przycisk przy uniesionym przycisku głośności na krawędzi tabletu.\n\nNaciśnięcie przycisku zasilania wyłącza ekran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Czytnik linii papilarnych znajduje się na przycisku zasilania. To płaski przycisk przy uniesionym przycisku głośności na krawędzi urządzenia.\n\nNaciśnięcie przycisku zasilania wyłącza ekran."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Czytnik linii papilarnych znajduje się na przycisku zasilania. To płaski przycisk przy uniesionym przycisku głośności na krawędzi telefonu.\n\nNaciśnięcie przycisku zasilania wyłącza ekran."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Czytnik linii papilarnych znajduje się na przycisku zasilania. To płaski przycisk przy uniesionym przycisku głośności na krawędzi tabletu."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Czytnik linii papilarnych znajduje się na przycisku zasilania. To płaski przycisk przy uniesionym przycisku głośności na krawędzi urządzenia."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Czytnik linii papilarnych znajduje się na przycisku zasilania. To płaski przycisk przy uniesionym przycisku głośności na krawędzi telefonu."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Odblokuj telefon, by wyświetlić więcej opcji"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Odblokuj tablet, by wyświetlić więcej opcji"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Odblokuj urządzenie, by wyświetlić więcej opcji"</string>
diff --git a/packages/SystemUI/res-product/values-pt-rBR/strings.xml b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
index 3190721..53efe3e 100644
--- a/packages/SystemUI/res-product/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res-product/values-pt-rBR/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use uma conta de e-mail para desbloquear o tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use uma conta de e-mail para desbloquear o smartphone.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do tablet.\n\nAo pressionar o botão liga/desliga, a tela é desativada."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do dispositivo.\n\nAo pressionar o botão liga/desliga, a tela é desativada."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do smartphone.\n\nAo pressionar o botão liga/desliga, a tela é desativada."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do dispositivo."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do smartphone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueie seu smartphone para ver mais opções"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueie seu tablet para ver mais opções"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie seu dispositivo para ver mais opções"</string>
diff --git a/packages/SystemUI/res-product/values-pt-rPT/strings.xml b/packages/SystemUI/res-product/values-pt-rPT/strings.xml
index a801da1..29a2001 100644
--- a/packages/SystemUI/res-product/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res-product/values-pt-rPT/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Tentou desbloquear incorretamente o telemóvel <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que eliminará todos os dados do mesmo."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o tablet através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Desenhou o padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Após mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas sem êxito, ser-lhe-á pedido para desbloquear o telemóvel através de uma conta de email.\n\n Tente novamente dentro de <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"O sensor de impressões digitais encontra-se no botão ligar/desligar. É o botão plano junto ao botão de volume com relevo na extremidade do tablet.\n\nPremir o botão ligar/desligar desativa o ecrã."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"O sensor de impressões digitais encontra-se no botão ligar/desligar. É o botão plano junto ao botão de volume com relevo na extremidade do dispositivo.\n\nPremir o botão ligar/desligar desativa o ecrã."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"O sensor de impressões digitais encontra-se no botão ligar/desligar. É o botão plano junto ao botão de volume com relevo na extremidade do telemóvel.\n\nPremir o botão ligar/desligar desativa o ecrã."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"O sensor de impressões digitais encontra-se no botão ligar/desligar. É o botão sem relevo junto ao botão de volume com relevo na extremidade do tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"O sensor de impressões digitais encontra-se no botão ligar/desligar. É o botão sem relevo junto ao botão de volume com relevo na extremidade do dispositivo."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"O sensor de impressões digitais encontra-se no botão ligar/desligar. É o botão sem relevo junto ao botão de volume com relevo na extremidade do telemóvel."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueie o telemóvel para obter mais opções."</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueie o tablet para obter mais opções."</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie o dispositivo para obter mais opções."</string>
diff --git a/packages/SystemUI/res-product/values-pt/strings.xml b/packages/SystemUI/res-product/values-pt/strings.xml
index 3190721..53efe3e 100644
--- a/packages/SystemUI/res-product/values-pt/strings.xml
+++ b/packages/SystemUI/res-product/values-pt/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Você tentou desbloquear o smartphone incorretamente <xliff:g id="NUMBER">%d</xliff:g> vezes. O perfil de trabalho será removido, o que excluirá todos os dados do perfil."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use uma conta de e-mail para desbloquear o tablet.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Você desenhou seu padrão de desbloqueio incorretamente <xliff:g id="NUMBER_0">%1$d</xliff:g> vezes. Se fizer mais <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativas incorretas, será solicitado que você use uma conta de e-mail para desbloquear o smartphone.\n\n Tente novamente em <xliff:g id="NUMBER_2">%3$d</xliff:g> segundos."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do tablet.\n\nAo pressionar o botão liga/desliga, a tela é desativada."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do dispositivo.\n\nAo pressionar o botão liga/desliga, a tela é desativada."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do smartphone.\n\nAo pressionar o botão liga/desliga, a tela é desativada."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do dispositivo."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"O sensor de impressão digital fica no botão liga/desliga. Ele é plano e está ao lado do botão de volume na borda do smartphone."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Desbloqueie seu smartphone para ver mais opções"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Desbloqueie seu tablet para ver mais opções"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Desbloqueie seu dispositivo para ver mais opções"</string>
diff --git a/packages/SystemUI/res-product/values-ro/strings.xml b/packages/SystemUI/res-product/values-ro/strings.xml
index 101ebe7f..cd08dee 100644
--- a/packages/SystemUI/res-product/values-ro/strings.xml
+++ b/packages/SystemUI/res-product/values-ro/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Ai făcut <xliff:g id="NUMBER">%d</xliff:g> încercări incorecte de deblocare a telefonului. Profilul de serviciu va fi eliminat, iar toate datele profilului vor fi șterse."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Ai desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, ți se va solicita să deblochezi tableta cu ajutorul unui cont de e-mail.\n\n Încearcă din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> secunde."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Ai desenat incorect modelul pentru deblocare de <xliff:g id="NUMBER_0">%1$d</xliff:g> ori. După încă <xliff:g id="NUMBER_1">%2$d</xliff:g> încercări nereușite, ți se va solicita să deblochezi telefonul cu ajutorul unui cont de e-mail.\n\n Încearcă din nou peste <xliff:g id="NUMBER_2">%3$d</xliff:g> secunde."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Senzorul de amprentă se află pe butonul de pornire. Este butonul plat de lângă butonul de volum în relief de pe marginea tabletei.\n\nDacă apeși butonul de pornire, ecranul se va dezactiva."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Senzorul de amprentă se află pe butonul de pornire. Este butonul plat de lângă butonul de volum în relief de pe marginea dispozitivului.\n\nDacă apeși butonul de pornire, ecranul se va dezactiva."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Senzorul de amprentă se află pe butonul de pornire. Este butonul plat de lângă butonul de volum în relief de pe marginea telefonului.\n\nDacă apeși butonul de pornire, ecranul se va dezactiva."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzorul de amprentă se află pe butonul de pornire. Este butonul plat de lângă butonul de volum în relief de pe marginea tabletei."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzorul de amprentă se află pe butonul de pornire. Este butonul plat de lângă butonul de volum în relief de pe marginea dispozitivului."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzorul de amprentă se află pe butonul de pornire. Este butonul plat de lângă butonul de volum în relief de pe marginea telefonului."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Deblochează telefonul pentru mai multe opțiuni"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Deblochează tableta pentru mai multe opțiuni"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Deblochează dispozitivul pentru mai multe opțiuni"</string>
diff --git a/packages/SystemUI/res-product/values-ru/strings.xml b/packages/SystemUI/res-product/values-ru/strings.xml
index 32e18c4..1649c02 100644
--- a/packages/SystemUI/res-product/values-ru/strings.xml
+++ b/packages/SystemUI/res-product/values-ru/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Вы несколько раз (<xliff:g id="NUMBER">%d</xliff:g>) не смогли разблокировать телефон. Рабочий профиль и все его данные будут удалены."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Вы несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>) ввели неверный графический ключ. Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи вам будет предложено разблокировать планшет с помощью аккаунта электронной почты.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Вы несколько раз (<xliff:g id="NUMBER_0">%1$d</xliff:g>) ввели неверный графический ключ. Осталось попыток: <xliff:g id="NUMBER_1">%2$d</xliff:g>. В случае неудачи вам будет предложено разблокировать телефон с помощью аккаунта электронной почты.\n\nПовторите попытку через <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Сканер отпечатков пальцев находится на кнопке питания. Это плоская кнопка рядом с приподнятой кнопкой регулировки громкости на боковой стороне устройства.\n\nНажав кнопку питания, вы выключите экран."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Сканер отпечатков пальцев находится на кнопке питания. Это плоская кнопка рядом с приподнятой кнопкой регулировки громкости на боковой стороне устройства.\n\nНажав кнопку питания, вы выключите экран."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Сканер отпечатков пальцев находится на кнопке питания. Это плоская кнопка рядом с приподнятой кнопкой регулировки громкости на боковой стороне устройства.\n\nНажав кнопку питания, вы выключите экран."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сканер отпечатков пальцев находится на кнопке питания. Она плоская и расположена рядом с приподнятой кнопкой регулировки громкости на боковой стороне планшета."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сканер отпечатков пальцев находится на кнопке питания. Она плоская и расположена рядом с приподнятой кнопкой регулировки громкости на боковой стороне устройства."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сканер отпечатков пальцев находится на кнопке питания. Она плоская и расположена рядом с приподнятой кнопкой регулировки громкости на боковой стороне телефона."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Чтобы посмотреть дополнительные параметры, разблокируйте телефон."</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Чтобы посмотреть дополнительные параметры, разблокируйте планшет."</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Чтобы посмотреть дополнительные параметры, разблокируйте устройство."</string>
diff --git a/packages/SystemUI/res-product/values-si/strings.xml b/packages/SystemUI/res-product/values-si/strings.xml
index bbd7aa5..4ab2a4b 100644
--- a/packages/SystemUI/res-product/values-si/strings.xml
+++ b/packages/SystemUI/res-product/values-si/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"ඔබ දුරකථනය අගුළු හැරීමට <xliff:g id="NUMBER">%d</xliff:g> වරක් වැරදියට උත්සාහ කර ඇත. කාර්යාල පැතිකඩ ඉවත් කරනු ඇති අතර, එය සියලු පැතිකඩ දත්ත මකනු ඇත."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"ඔබ අගුළු ඇරිමේ රටාව <xliff:g id="NUMBER_0">%1$d</xliff:g> වතාවක් වැරදියට ඇඳ ඇත. තවත් අසාර්ථක උත්සාහ <xliff:g id="NUMBER_1">%2$d</xliff:g> කින් පසුව, ඊ-තැපැල් ගිණුම භාවිතා කරමින් ඔබගේ ටැබ්ලටයේ අගුළු ඇරීමට ඔබට පවසනු ඇත.\n\n නැවත තත්පර <xliff:g id="NUMBER_2">%3$d</xliff:g> කින් උත්සාහ කරන්න."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"ඔබ වැරදියට <xliff:g id="NUMBER_0">%1$d</xliff:g> වතාවක් ඔබගේ අගුළු හැරීමේ රටාව ඇඳ ඇත. අසාර්ථක උත්සහ කිරීම් <xliff:g id="NUMBER_1">%2$d</xliff:g> න් පසුව, ඔබගේ ඊ-තැපැල් ලිපිනය භාවිතයෙන් ඔබගේ දුරකථනය අගුළු හැරීමට ඔබගෙන් අසයි.\n\n තත්පර <xliff:g id="NUMBER_2">%3$d</xliff:g> න් පසුව නැවත උත්සහ කරන්න."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"ඇඟිලි සලකුණු සංවේදකය බල බොත්තම මත ඇත. එය ටැබ්ලටයෙහි කෙළවරේ ඇති ඉහළ හඬ පරිමා බොත්තම අසල ඇති පැතලි බොත්තමයි.\n\nබල බොත්තම එබීම තිරය ක්රියා විරහිත කරයි."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"ඇඟිලි සලකුණු සංවේදකය බල බොත්තම මත ඇත. එය උපාංගයෙහි කෙළවරේ ඇති ඉහළ හඬ පරිමා බොත්තම අසල ඇති පැතලි බොත්තමයි.\n\nබල බොත්තම එබීම තිරය ක්රියා විරහිත කරයි."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"ඇඟිලි සලකුණු සංවේදකය බල බොත්තම මත ඇත. එය දුරකථනයෙහි කෙළවරේ ඇති ඉහළ හඬ පරිමා බොත්තම අසල ඇති පැතලි බොත්තමයි.\n\nබල බොත්තම එබීම තිරය ක්රියා විරහිත කරයි."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"ඇඟිලි සලකුණු සංවේදකය බල බොත්තම මත ඇත. එය ටැබ්ලටයෙහි කෙළවර ඇති ඉහළ හඬ පරිමා බොත්තම අසල ඇති පැතලි බොත්තමයි."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"ඇඟිලි සලකුණු සංවේදකය බල බොත්තම මත ඇත. එය උපාංගයෙහි කෙළවර ඇති ඉහළ හඬ පරිමා බොත්තම අසල ඇති පැතලි බොත්තමයි."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"ඇඟිලි සලකුණු සංවේදකය බල බොත්තම මත ඇත. එය දුරකථනයෙහි කෙළවර ඇති ඉහළ හඬ පරිමා බොත්තම අසල ඇති පැතලි බොත්තමයි."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"තව විකල්ප සඳහා ඔබේ දුරකථනය අගුලු හරින්න"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"තව විකල්ප සඳහා ඔබේ ටැබ්ලට් පරිගණකය අගුලු හරින්න"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"තව විකල්ප සඳහා ඔබේ උපාංගය අගුලු හරින්න"</string>
diff --git a/packages/SystemUI/res-product/values-sk/strings.xml b/packages/SystemUI/res-product/values-sk/strings.xml
index 4a142081..21bcc2a 100644
--- a/packages/SystemUI/res-product/values-sk/strings.xml
+++ b/packages/SystemUI/res-product/values-sk/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Telefón ste sa pokúsili <xliff:g id="NUMBER">%d</xliff:g>‑krát nesprávne odomknúť. Pracovný profil bude odstránený spolu so všetkými údajmi."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g>‑krát ste nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie tabletu pomocou e‑mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Už ste <xliff:g id="NUMBER_0">%1$d</xliff:g>‑krát nesprávne nakreslili svoj bezpečnostný vzor. Po <xliff:g id="NUMBER_1">%2$d</xliff:g> ďalších neúspešných pokusoch sa zobrazí výzva na odomknutie telefónu pomocou e‑mailového účtu.\n\n Skúste to znova o <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Senzor odtlačkov prstov je na vypínači. Ide o ploché tlačidlo vedľa vypuklého tlačidla hlasitosti na okraji tabletu.\n\nStlačením vypínača vypnete obrazovku."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Senzor odtlačkov prstov je na vypínači. Ide o ploché tlačidlo vedľa vypuklého tlačidla hlasitosti na okraji zariadenia.\n\nStlačením vypínača vypnete obrazovku."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Senzor odtlačkov prstov je na vypínači. Ide o ploché tlačidlo vedľa vypuklého tlačidla hlasitosti na okraji telefónu.\n\nStlačením vypínača vypnete obrazovku."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Senzor odtlačkov prstov je na vypínači. Je to ploché tlačidlo vedľa vypuklého tlačidla hlasitosti na okraji tabletu."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Senzor odtlačkov prstov je na vypínači. Je to ploché tlačidlo vedľa vypuklého tlačidla hlasitosti na okraji zariadenia."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Senzor odtlačkov prstov je na vypínači. Je to ploché tlačidlo vedľa vypuklého tlačidla hlasitosti na okraji telefónu."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Ak chcete zobraziť ďalšie možnosti, odomknite telefón"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Ak chcete zobraziť ďalšie možnosti, odomknite tablet"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Ak chcete zobraziť ďalšie možnosti, odomknite zariadenie"</string>
diff --git a/packages/SystemUI/res-product/values-sl/strings.xml b/packages/SystemUI/res-product/values-sl/strings.xml
index 8119335..95191a4 100644
--- a/packages/SystemUI/res-product/values-sl/strings.xml
+++ b/packages/SystemUI/res-product/values-sl/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Telefon ste neuspešno poskusili odkleniti <xliff:g id="NUMBER">%d</xliff:g>-krat. Delovni profil bo odstranjen in vsi podatki profila bodo izbrisani."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Če ga neuspešno poskusite vnesti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani, da tablični računalnik odklenete z e-poštnim računom.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Vzorec za odklepanje ste <xliff:g id="NUMBER_0">%1$d</xliff:g>-krat napačno vnesli. Če ga neuspešno poskusite vnesti še <xliff:g id="NUMBER_1">%2$d</xliff:g>-krat, boste pozvani, da telefon odklenete z e-poštnim računom.\n\nPoskusite znova čez <xliff:g id="NUMBER_2">%3$d</xliff:g> s."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Tipalo prstnih odtisov je na gumbu za vklop. To je ploski gumb ob izbočenem gumbu za glasnost na robu tabličnega računalnika.\n\nČe pritisnete gumb za vklop, se zaslon izklopi."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Tipalo prstnih odtisov je na gumbu za vklop. To je ploski gumb ob izbočenem gumbu za glasnost na robu naprave.\n\nČe pritisnete gumb za vklop, se zaslon izklopi."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Tipalo prstnih odtisov je na gumbu za vklop. To je ploski gumb ob izbočenem gumbu za glasnost na robu telefona.\n\nČe pritisnete gumb za vklop, se zaslon izklopi."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Tipalo prstnih odtisov je na gumbu za vklop. To je ploski gumb ob izbočenem gumbu za glasnost na robu tabličnega računalnika."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Tipalo prstnih odtisov je na gumbu za vklop. To je ploski gumb ob izbočenem gumbu za glasnost na robu naprave."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Tipalo prstnih odtisov je na gumbu za vklop. To je ploski gumb ob izbočenem gumbu za glasnost na robu telefona."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Za več možnosti odklenite telefon"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Za več možnosti odklenite tablični računalnik"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Za več možnosti odklenite napravo"</string>
diff --git a/packages/SystemUI/res-product/values-sq/strings.xml b/packages/SystemUI/res-product/values-sq/strings.xml
index 0b7b77d..435966eb 100644
--- a/packages/SystemUI/res-product/values-sq/strings.xml
+++ b/packages/SystemUI/res-product/values-sq/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Ke tentuar <xliff:g id="NUMBER">%d</xliff:g> herë pa sukses për ta shkyçur telefonin. Profili i punës do të hiqet, gjë që do të fshijë të gjitha të dhënat e profilit."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd të shkyçjes. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh tabletin duke përdorur një llogari email-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Ke vizatuar <xliff:g id="NUMBER_0">%1$d</xliff:g> herë pa sukses motivin tënd. Pas <xliff:g id="NUMBER_1">%2$d</xliff:g> tentativave të tjera të pasuksesshme, do të të duhet ta shkyçësh telefonin duke përdorur një llogari email-i.\n\n Provo sërish për <xliff:g id="NUMBER_2">%3$d</xliff:g> sekonda."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Sensori i gjurmës së gishtit është në butonin e energjisë. Ai është butoni i rrafshët pranë butonit të ngritur të volumit në anë të tabletit.\n\nShtypja e butonit të energjisë e fik ekranin."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Sensori i gjurmës së gishtit është në butonin e energjisë. Ai është butoni i rrafshët pranë butonit të ngritur të volumit në anë të pajisjes.\n\nShtypja e butonit të energjisë e fik ekranin."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Sensori i gjurmës së gishtit është në butonin e energjisë. Ai është butoni i rrafshët pranë butonit të ngritur të volumit në anë të telefonit.\n\nShtypja e butonit të energjisë e fik ekranin."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Sensori i gjurmës së gishtit është në butonin e energjisë. Ai është butoni i rrafshët pranë butonit të ngritur të volumit në anë të tabletit."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Sensori i gjurmës së gishtit është në butonin e energjisë. Ai është butoni i rrafshët pranë butonit të ngritur të volumit në anë të pajisjes."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Sensori i gjurmës së gishtit është në butonin e energjisë. Ai është butoni i rrafshët pranë butonit të ngritur të volumit në anë të telefonit."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Shkyçe telefonin për më shumë opsione"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Shkyçe tabletin për më shumë opsione"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Shkyçe pajisjen për më shumë opsione"</string>
diff --git a/packages/SystemUI/res-product/values-sr/strings.xml b/packages/SystemUI/res-product/values-sr/strings.xml
index 00269da..4c458a4 100644
--- a/packages/SystemUI/res-product/values-sr/strings.xml
+++ b/packages/SystemUI/res-product/values-sr/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Погрешно сте покушали да откључате телефон <xliff:g id="NUMBER">%d</xliff:g> пута. Уклонићемо пословни профил, чиме се бришу сви подаци са профила."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате таблет помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Нетачно сте нацртали шаблон за откључавање <xliff:g id="NUMBER_0">%1$d</xliff:g> пута. Ако погрешно покушате још <xliff:g id="NUMBER_1">%2$d</xliff:g> пута, затражићемо да откључате телефон помоћу имејл налога.\n\n Пробајте поново за <xliff:g id="NUMBER_2">%3$d</xliff:g> сек."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Сензор за отисак прста се налази на дугмету за укључивање. То је равно дугме поред издигнутог дугмета за јачину звука на ивици таблета.\n\nПритиском на дугме за укључивање искључује се екран."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Сензор за отисак прста се налази на дугмету за укључивање. То је равно дугме поред издигнутог дугмета за јачину звука на ивици уређаја.\n\nПритиском на дугме за укључивање искључује се екран."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Сензор за отисак прста се налази на дугмету за укључивање. То је равно дугме поред издигнутог дугмета за јачину звука на ивици телефона.\n\nПритиском на дугме за укључивање искључује се екран."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сензор за отисак прста се налази на дугмету за укључивање. То је равно дугме поред издигнутог дугмета за јачину звука на ивици таблета."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сензор за отисак прста се налази на дугмету за укључивање. То је равно дугме поред издигнутог дугмета за јачину звука на ивици уређаја."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сензор за отисак прста се налази на дугмету за укључивање. То је равно дугме поред издигнутог дугмета за јачину звука на ивици телефона."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Откључајте телефон за још опција"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Откључајте таблет за још опција"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Откључајте уређај за још опција"</string>
diff --git a/packages/SystemUI/res-product/values-sv/strings.xml b/packages/SystemUI/res-product/values-sv/strings.xml
index c0c1a10..e2bbfa1 100644
--- a/packages/SystemUI/res-product/values-sv/strings.xml
+++ b/packages/SystemUI/res-product/values-sv/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Du har försökt låsa upp telefonen på ett felaktigt sätt <xliff:g id="NUMBER">%d</xliff:g> gånger. Jobbprofilen tas bort och all profildata raderas."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök måste du låsa upp surfplattan med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Du har ritat ditt grafiska lösenord fel <xliff:g id="NUMBER_0">%1$d</xliff:g> gånger. Efter ytterligare <xliff:g id="NUMBER_1">%2$d</xliff:g> försök måste du låsa upp telefonen med hjälp av ett e-postkonto.\n\n Försök igen om <xliff:g id="NUMBER_2">%3$d</xliff:g> sekunder."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Fingeravtryckssensorn sitter på av/på-knappen. Det är den platta knappen bredvid den upphöjda volymknappen på kanten av surfplattan.\n\nOm du trycker på av/på-knappen stängs skärmen av."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Fingeravtryckssensorn sitter på av/på-knappen. Det är den platta knappen bredvid den upphöjda volymknappen på kanten av enheten.\n\nOm du trycker på av/på-knappen stängs skärmen av."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Fingeravtryckssensorn sitter på av/på-knappen. Det är den platta knappen bredvid den upphöjda volymknappen på kanten av telefonen.\n\nOm du trycker på av/på-knappen stängs skärmen av."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Fingeravtryckssensorn sitter på av/på-knappen. Det är den platta knappen bredvid den upphöjda volymknappen på surfplattans kant."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Fingeravtryckssensorn sitter på av/på-knappen. Det är den platta knappen bredvid den upphöjda volymknappen på enhetens kant."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Fingeravtryckssensorn sitter på av/på-knappen. Det är den platta knappen bredvid den upphöjda volymknappen på telefonens kant."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Lås upp telefonen för fler alternativ"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Lås upp surfplattan för fler alternativ"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Lås upp enheten för fler alternativ"</string>
diff --git a/packages/SystemUI/res-product/values-sw/strings.xml b/packages/SystemUI/res-product/values-sw/strings.xml
index 8edbede..2ebc3eb 100644
--- a/packages/SystemUI/res-product/values-sw/strings.xml
+++ b/packages/SystemUI/res-product/values-sw/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Umejaribu kufungua simu mara <xliff:g id="NUMBER">%d</xliff:g> bila mafanikio. Wasifu wa kazini utaondolewa, hatua itakayofuta data yote ya wasifu."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Umeweka mchoro usio sahihi wa kufungua skrini mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Baada ya majaribio <xliff:g id="NUMBER_1">%2$d</xliff:g> zaidi bila mafanikio, utaombwa ufungue kompyuta yako kibao kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Umeweka mchoro usio sahihi wa kufungua skrini mara <xliff:g id="NUMBER_0">%1$d</xliff:g>. Ukikosea mara nyingine <xliff:g id="NUMBER_1">%2$d</xliff:g>, utaombwa ufungue simu yako kwa kutumia akaunti ya barua pepe.\n\n Jaribu tena baada ya sekunde <xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Kitambuzi cha alama ya kidole kinapatikana kwenye kitufe cha kuwasha/kuzima. Ni kitufe bapa pembeni pa kitufe cha sauti kilichoinuka kwenye ukingo wa kompyuta kibao.\n\nUkibonyeza kitufe cha kuwasha/kuzima skrini itazima."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Kitambuzi cha alama ya kidole kinapatikana kwenye kitufe cha kuwasha/kuzima. Ni kitufe bapa pembeni pa kitufe cha sauti kilichoinuka kwenye ukingo wa kifaa.\n\nUkibonyeza kitufe cha kuwasha/kuzima skrini itazima."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Kitambuzi cha alama ya kidole kinapatikana kwenye kitufe cha kuwasha/kuzima. Ni kitufe bapa pembeni pa kitufe cha sauti kilichoinuka kwenye ukingo wa simu.\n\nUkibonyeza kitufe cha kuwasha/kuzima skrini itazima."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Kitambuzi cha alama ya kidole kinapatikana kwenye kitufe cha kuwasha/kuzima. Ni kitufe bapa pembeni pa kitufe cha sauti kilichoinuka kwenye ukingo wa kompyuta kibao."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Kitambuzi cha alama ya kidole kinapatikana kwenye kitufe cha kuwasha/kuzima. Ni kitufe bapa pembeni pa kitufe cha sauti kilichoinuka kwenye ukingo wa kifaa."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Kitambuzi cha alama ya kidole kinapatikana kwenye kitufe cha kuwasha/kuzima. Ni kitufe bapa pembeni pa kitufe cha sauti kilichoinuka kwenye ukingo wa simu."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Fungua simu yako ili upate chaguo zaidi"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Fungua kompyuta yako kibao ili upate chaguo zaidi"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Fungua kifaa chako ili upate chaguo zaidi"</string>
diff --git a/packages/SystemUI/res-product/values-ta/strings.xml b/packages/SystemUI/res-product/values-ta/strings.xml
index 84c9f4d..967afed 100644
--- a/packages/SystemUI/res-product/values-ta/strings.xml
+++ b/packages/SystemUI/res-product/values-ta/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"மொபைலை அன்லாக் செய்ய, <xliff:g id="NUMBER">%d</xliff:g> முறை தவறாக முயன்றுவிட்டதனால் பணிக் கணக்கு அகற்றப்படும். இதனால் அதிலுள்ள அனைத்துச் சுயவிவரத் தரவும் நீக்கப்படும்."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"அன்லாக் பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், மின்னஞ்சல் கணக்கைப் பயன்படுத்தி டேப்லெட்டை அன்லாக் செய்யும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"அன்லாக் பேட்டர்னை, <xliff:g id="NUMBER_0">%1$d</xliff:g> முறை தவறாக வரைந்துவிட்டீர்கள். இன்னும் <xliff:g id="NUMBER_1">%2$d</xliff:g> முறை தவறாக வரைந்தால், மின்னஞ்சல் கணக்கைப் பயன்படுத்தி மொபைலை அன்லாக் செய்யும்படி கேட்கப்படுவீர்கள்.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> வினாடிகளில் மீண்டும் முயலவும்."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"\'கைரேகை சென்சார்\' பவர் பட்டனில் உள்ளது. இது டேப்லெட்டின் விளிம்பில் சற்று மேலெழும்பிய ஒலியளவு பட்டனுக்கு அருகில் இருக்கும் தட்டையான பட்டனாகும்.\n\nபவர் பட்டனை அழுத்தினால் திரை ஆஃப் ஆகும்."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"\'கைரேகை சென்சார்\' பவர் பட்டனில் உள்ளது. இது சாதனத்தின் விளிம்பில் சற்று மேலெழும்பிய ஒலியளவு பட்டனுக்கு அருகில் இருக்கும் தட்டையான பட்டனாகும்.\n\nபவர் பட்டனை அழுத்தினால் திரை ஆஃப் ஆகும்."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"\'கைரேகை சென்சார்\' பவர் பட்டனில் உள்ளது. இது மொபைலின் விளிம்பில் சற்று மேலெழும்பிய ஒலியளவு பட்டனுக்கு அருகில் இருக்கும் தட்டையான பட்டனாகும்.\n\nபவர் பட்டனை அழுத்தினால் திரை ஆஃப் ஆகும்."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"\'கைரேகை சென்சார்\' பவர் பட்டனில் உள்ளது. இது டேப்லெட்டின் விளிம்பில் சற்று மேலெழும்பிய ஒலியளவு பட்டனுக்கு அடுத்துள்ள தட்டையான பட்டனாகும்."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"\'கைரேகை சென்சார்\' பவர் பட்டனில் உள்ளது. இது சாதனத்தின் விளிம்பில் சற்று மேலெழும்பிய ஒலியளவு பட்டனுக்கு அடுத்துள்ள தட்டையான பட்டனாகும்."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"\'கைரேகை சென்சார்\' பவர் பட்டனில் உள்ளது. இது மொபைலின் விளிம்பில் சற்று மேலெழும்பிய ஒலியளவு பட்டனுக்கு அடுத்துள்ள தட்டையான பட்டனாகும்."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"மேலும் விருப்பங்களுக்கு மொபைலை அன்லாக் செய்யவும்"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"மேலும் விருப்பங்களுக்கு டேப்லெட்டை அன்லாக் செய்யவும்"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"மேலும் விருப்பங்களுக்குச் சாதனத்தை அன்லாக் செய்யவும்"</string>
diff --git a/packages/SystemUI/res-product/values-te/strings.xml b/packages/SystemUI/res-product/values-te/strings.xml
index 1f66c50..98b2189 100644
--- a/packages/SystemUI/res-product/values-te/strings.xml
+++ b/packages/SystemUI/res-product/values-te/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"మీరు ఫోన్ను అన్లాక్ చేయడానికి <xliff:g id="NUMBER">%d</xliff:g> సార్లు తప్పు ప్రయత్నాలు చేశారు. కార్యాలయ ప్రొఫైల్ తీసివేయబడుతుంది, దీని వలన ప్రొఫైల్ డేటా మొత్తం తొలగించబడుతుంది."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> ప్రయత్నాలలో విఫలమైతే, మీరు ఈమెయిల్ ఖాతాను ఉపయోగించి మీ టాబ్లెట్ను అన్లాక్ చేయాల్సి వస్తుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"మీరు మీ అన్లాక్ నమూనాను <xliff:g id="NUMBER_0">%1$d</xliff:g> సార్లు తప్పుగా గీసారు. మరో <xliff:g id="NUMBER_1">%2$d</xliff:g> ప్రయత్నాలలో విఫలమైతే, మీరు ఈమెయిల్ ఖాతాను ఉపయోగించి మీ ఫోన్ను అన్లాక్ చేయాల్సి వస్తుంది.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"వేలిముద్ర సెన్సార్ పవర్ బటన్పై ఉంది. ఇది టాబ్లెట్ అంచున వాల్యూమ్ పెంచడానికి ఉపయోగించే వాల్యూమ్ బటన్ పక్కన ఉన్న ఫ్లాట్ బటన్.\n\nపవర్ బటన్ను నొక్కితే స్క్రీన్ ఆఫ్ అవుతుంది."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"వేలిముద్ర సెన్సార్ పవర్ బటన్పై ఉంది. ఇది పరికరం అంచున వాల్యూమ్ పెంచడానికి ఉపయోగించే వాల్యూమ్ బటన్ పక్కన ఉన్న ఫ్లాట్ బటన్.\n\nపవర్ బటన్ను నొక్కితే స్క్రీన్ ఆఫ్ అవుతుంది."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"వేలిముద్ర సెన్సార్ పవర్ బటన్పై ఉంది. ఇది ఫోన్ అంచున వాల్యూమ్ పెంచడానికి ఉపయోగించే వాల్యూమ్ బటన్ పక్కన ఉన్న ఫ్లాట్ బటన్.\n\nపవర్ బటన్ను నొక్కితే స్క్రీన్ ఆఫ్ అవుతుంది."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"వేలిముద్ర సెన్సార్ పవర్ బటన్పై ఉంది. ఇది, ఈ టాబ్లెట్ అంచున ఉబ్బెత్తుగా ఉన్న వాల్యూమ్ బటన్ పక్కన ఉన్న ఫ్లాట్ బటన్."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"వేలిముద్ర సెన్సార్ పవర్ బటన్పై ఉంది. ఇది, ఈ పరికరం అంచున ఉబ్బెత్తుగా ఉన్న వాల్యూమ్ బటన్ పక్కన ఉన్న ఫ్లాట్ బటన్."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"వేలిముద్ర సెన్సార్ పవర్ బటన్పై ఉంది. ఇది, ఈ ఫోన్ అంచున ఉబ్బెత్తుగా ఉన్న వాల్యూమ్ బటన్ పక్కన ఉన్న ఫ్లాట్ బటన్."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"మరిన్ని ఆప్షన్ల కోసం మీ ఫోన్ను అన్లాక్ చేయండి"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"మరిన్ని ఆప్షన్ల కోసం మీ టాబ్లెట్ను అన్లాక్ చేయండి"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"మరిన్ని ఆప్షన్ల కోసం మీ పరికరాన్ని అన్లాక్ చేయండి"</string>
diff --git a/packages/SystemUI/res-product/values-th/strings.xml b/packages/SystemUI/res-product/values-th/strings.xml
index e78cbc4..e3d5640 100644
--- a/packages/SystemUI/res-product/values-th/strings.xml
+++ b/packages/SystemUI/res-product/values-th/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"คุณปลดล็อกโทรศัพท์ไม่ถูกต้อง <xliff:g id="NUMBER">%d</xliff:g> ครั้งแล้ว ระบบจะนำโปรไฟล์งานออก ซึ่งจะเป็นการลบข้อมูลทั้งหมดในโปรไฟล์"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกแท็บเล็ตโดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งใน <xliff:g id="NUMBER_2">%3$d</xliff:g> วินาที"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"คุณวาดรูปแบบการปลดล็อกไม่ถูกต้อง <xliff:g id="NUMBER_0">%1$d</xliff:g> ครั้งแล้ว หากทำไม่สำเร็จอีก <xliff:g id="NUMBER_1">%2$d</xliff:g> ครั้ง ระบบจะขอให้คุณปลดล็อกโทรศัพท์โดยใช้บัญชีอีเมล\n\n โปรดลองอีกครั้งในอีก <xliff:g id="NUMBER_2">%3$d</xliff:g> วินาที"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"เซ็นเซอร์ลายนิ้วมืออยู่ที่ปุ่มเปิด/ปิด ซึ่งเป็นปุ่มแบนข้างปุ่มนูนที่ใช้ปรับระดับเสียงตรงบริเวณขอบของแท็บเล็ต\n\nการกดปุ่มเปิด/ปิดจะเป็นการปิดหน้าจอ"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"เซ็นเซอร์ลายนิ้วมืออยู่ที่ปุ่มเปิด/ปิด ซึ่งเป็นปุ่มแบนข้างปุ่มนูนที่ใช้ปรับระดับเสียงตรงบริเวณขอบของอุปกรณ์\n\nการกดปุ่มเปิด/ปิดจะเป็นการปิดหน้าจอ"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"เซ็นเซอร์ลายนิ้วมืออยู่ที่ปุ่มเปิด/ปิด ซึ่งเป็นปุ่มแบนข้างปุ่มนูนที่ใช้ปรับระดับเสียงตรงบริเวณขอบของโทรศัพท์\n\nการกดปุ่มเปิด/ปิดจะเป็นการปิดหน้าจอ"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"เซ็นเซอร์ลายนิ้วมืออยู่ที่ปุ่มเปิด/ปิด ซึ่งเป็นปุ่มแบนข้างปุ่มนูนที่ใช้ปรับระดับเสียงตรงบริเวณขอบของแท็บเล็ต"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"เซ็นเซอร์ลายนิ้วมืออยู่ที่ปุ่มเปิด/ปิด ซึ่งเป็นปุ่มแบนข้างปุ่มนูนที่ใช้ปรับระดับเสียงตรงบริเวณขอบของอุปกรณ์"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"เซ็นเซอร์ลายนิ้วมืออยู่ที่ปุ่มเปิด/ปิด ซึ่งเป็นปุ่มแบนข้างปุ่มนูนที่ใช้ปรับระดับเสียงตรงบริเวณขอบของโทรศัพท์"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"ปลดล็อกโทรศัพท์เพื่อดูตัวเลือกเพิ่มเติม"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"ปลดล็อกแท็บเล็ตเพื่อดูตัวเลือกเพิ่มเติม"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"ปลดล็อกอุปกรณ์เพื่อดูตัวเลือกเพิ่มเติม"</string>
diff --git a/packages/SystemUI/res-product/values-tl/strings.xml b/packages/SystemUI/res-product/values-tl/strings.xml
index 4adad1f..4c286eb 100644
--- a/packages/SystemUI/res-product/values-tl/strings.xml
+++ b/packages/SystemUI/res-product/values-tl/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"<xliff:g id="NUMBER">%d</xliff:g> (na) beses mo nang sinubukang i-unlock ang telepono gamit ang maling password. Aalisin ang profile sa trabaho, na magiging dahilan para ma-delete ang lahat ng data sa profile."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses kang nagkamali sa pagguhit ng iyong pattern sa pag-unlock. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, hihilingin sa iyong i-unlock ang tablet mo gamit ang isang email account.\n\n Subukan ulit sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"<xliff:g id="NUMBER_0">%1$d</xliff:g> (na) beses kang nagkamali sa pagguhit ng iyong pattern sa pag-unlock. Pagkatapos ng <xliff:g id="NUMBER_1">%2$d</xliff:g> pang hindi matagumpay na pagsubok, hihilingin sa iyong i-unlock ang telepono mo gamit ang isang email account.\n\n Subukan ulit sa loob ng <xliff:g id="NUMBER_2">%3$d</xliff:g> (na) segundo."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Nasa power button ang sensor para sa fingerprint. Ito ang flat na button sa tabi ng nakaangat na button ng volume sa gilid ng tablet.\n\nMamamatay ang screen kapag pinindot ang power button."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Nasa power button ang sensor para sa fingerprint. Ito ang flat na button sa tabi ng nakaangat na button ng volume sa gilid ng device.\n\nMamamatay ang screen kapag pinindot ang power button."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Nasa power button ang sensor para sa fingerprint. Ito ang flat na button sa tabi ng nakaangat na button ng volume sa gilid ng telepono.\n\nMamamatay ang screen kapag pinindot ang power button."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Nasa power button ang sensor para sa fingerprint. Ito ang flat na button sa tabi ng nakaangat na button ng volume sa gilid ng tablet."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Nasa power button ang sensor para sa fingerprint. Ito ang flat na button sa tabi ng nakaangat na button ng volume sa gilid ng device."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Nasa power button ang sensor para sa fingerprint. Ito ang flat na button sa tabi ng nakaangat na button ng volume sa gilid ng telepono."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"I-unlock ang iyong telepono para sa higit pang opsyon"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"I-unlock ang iyong tablet para sa higit pang opsyon"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"I-unlock ang iyong device para sa higit pang opsyon"</string>
diff --git a/packages/SystemUI/res-product/values-tr/strings.xml b/packages/SystemUI/res-product/values-tr/strings.xml
index 53c6054..b376e98 100644
--- a/packages/SystemUI/res-product/values-tr/strings.xml
+++ b/packages/SystemUI/res-product/values-tr/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Telefonun kilidini <xliff:g id="NUMBER">%d</xliff:g> kez hatalı bir şekilde açmayı denediniz. İş profili kaldırılacak ve tüm profil verileri silinecektir."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez hatalı çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız tabletinizin kilidini bir e-posta hesabı kullanarak açmanız istenir.\n<xliff:g id="NUMBER_2">%3$d</xliff:g>\n saniye içinde tekrar deneyin."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Kilit açma deseninizi <xliff:g id="NUMBER_0">%1$d</xliff:g> kez yanlış çizdiniz. <xliff:g id="NUMBER_1">%2$d</xliff:g> başarısız deneme daha yaparsanız telefonunuzu bir e-posta hesabı kullanarak açmanız istenir.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> saniye içinde tekrar deneyin."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Parmak izi sensörü güç düğmesinin üzerindedir. Bu sensör, tabletin kenarındaki ses yükseltme düğmesinin yanında bulunan düz düğmedir.\n\nGüç düğmesine bastığınızda ekran kapanır."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Parmak izi sensörü güç düğmesinin üzerindedir. Bu sensör, cihazın kenarındaki ses yükseltme düğmesinin yanında bulunan düz düğmedir.\n\nGüç düğmesine bastığınızda ekran kapanır."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Parmak izi sensörü güç düğmesinin üzerindedir. Bu sensör, telefonun kenarındaki ses yükseltme düğmesinin yanında bulunan düz düğmedir.\n\nGüç düğmesine bastığınızda ekran kapanır."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Parmak izi sensörü güç düğmesinin üzerindedir. Bu sensör, tabletin kenarındaki standart ses düğmesinin yanında bulunan düz düğmedir."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Parmak izi sensörü güç düğmesinin üzerindedir. Bu sensör, cihazın kenarındaki standart ses düğmesinin yanında bulunan düz düğmedir."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Parmak izi sensörü güç düğmesinin üzerindedir. Bu sensör, telefonun kenarındaki standart ses düğmesinin yanında bulunan düz düğmedir."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Diğer seçenekler için telefonunuzun kilidini açın"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Diğer seçenekler için tabletinizin kilidini açın"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Diğer seçenekler için cihazınızın kilidini açın"</string>
diff --git a/packages/SystemUI/res-product/values-uk/strings.xml b/packages/SystemUI/res-product/values-uk/strings.xml
index ef62fff..ed0762b 100644
--- a/packages/SystemUI/res-product/values-uk/strings.xml
+++ b/packages/SystemUI/res-product/values-uk/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Кількість невдалих спроб розблокувати телефон: <xliff:g id="NUMBER">%d</xliff:g>. Буде видалено робочий профіль і всі його дані."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі з\'явиться запит розблокувати планшет за допомогою облікового запису електронної пошти.\n\n Повторіть спробу за <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Ключ розблокування неправильно намальовано стільки разів: <xliff:g id="NUMBER_0">%1$d</xliff:g>. Залишилося спроб: <xliff:g id="NUMBER_1">%2$d</xliff:g>. У разі невдачі з\'явиться запит розблокувати телефон за допомогою облікового запису електронної пошти.\n\n Повторіть спробу за <xliff:g id="NUMBER_2">%3$d</xliff:g> с."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Сканер відбитків пальців розташовано на кнопці живлення. Це плоска кнопка, розташована поруч із кнопкою збільшення гучності на бічній крайці планшета.\n\nЯкщо натиснути кнопку живлення, екран вимкнеться."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Сканер відбитків пальців розташовано на кнопці живлення. Це плоска кнопка, розташована поруч із кнопкою збільшення гучності на бічній крайці пристрою.\n\nЯкщо натиснути кнопку живлення, екран вимкнеться."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Сканер відбитків пальців розташовано на кнопці живлення. Це плоска кнопка, розташована поруч із кнопкою збільшення гучності на бічній крайці телефона.\n\nЯкщо натиснути кнопку живлення, екран вимкнеться."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Сканер відбитків пальців розташовано на кнопці живлення. Це плоска кнопка поруч із випуклою кнопкою гучності на бічній крайці планшета."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Сканер відбитків пальців розташовано на кнопці живлення. Це плоска кнопка поруч із випуклою кнопкою гучності на бічній крайці пристрою."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Сканер відбитків пальців розташовано на кнопці живлення. Це плоска кнопка поруч із випуклою кнопкою гучності на бічній крайці телефона."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Розблокуйте телефон, щоб переглянути інші параметри"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Розблокуйте планшет, щоб переглянути інші параметри"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Розблокуйте пристрій, щоб переглянути інші параметри"</string>
diff --git a/packages/SystemUI/res-product/values-ur/strings.xml b/packages/SystemUI/res-product/values-ur/strings.xml
index e272a33..c706aba 100644
--- a/packages/SystemUI/res-product/values-ur/strings.xml
+++ b/packages/SystemUI/res-product/values-ur/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"آپ نے فون کو غیر مقفل کرنے کیلئے <xliff:g id="NUMBER">%d</xliff:g> بار غلط طریقے سے کوشش کی ہے۔ دفتری پروفائل ہٹا دی جائے گی، جس سے پروفائل کا سبھی ڈیٹا حذف ہو جائے گا۔"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کر کے اپنا ٹیبلیٹ غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"آپ نے اپنا غیر مقفل کرنے کا پیٹرن <xliff:g id="NUMBER_0">%1$d</xliff:g> بار غلط طریقے سے ڈرا کیا ہے۔ <xliff:g id="NUMBER_1">%2$d</xliff:g> مزید ناکام کوششوں کے بعد، آپ سے ایک ای میل اکاؤنٹ استعمال کر کے اپنا فون غیر مقفل کرنے کو کہا جائے گا۔\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> سیکنڈ میں دوبارہ کوشش کریں۔"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"فنگر پرنٹ سینسر پاور بٹن پر موجود ہے۔ یہ ٹیبلیٹ کے کنارے پر ابھرے ہوئے والیوم بٹن کے آگے والا ہموار بٹن ہے۔\n\nپاور بٹن دبانے سے اسکرین آف ہو جاتی ہے۔"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"فنگر پرنٹ سینسر پاور بٹن پر موجود ہے۔ یہ آلے کے کنارے پر ابھرے ہوئے والیوم بٹن کے آگے والا ہموار بٹن ہے۔\n\nپاور بٹن دبانے سے اسکرین آف ہو جاتی ہے۔"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"فنگر پرنٹ سینسر پاور بٹن پر موجود ہے۔ یہ فون کے کنارے پر ابھرے ہوئے والیوم بٹن کے آگے والا ہموار بٹن ہے۔\n\nپاور بٹن دبانے سے اسکرین آف ہو جاتی ہے۔"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"فنگر پرنٹ سینسر پاور بٹن پر موجود ہے۔ یہ ٹیبلیٹ کے کنارے پر ابھرے ہوئے والیوم بٹن کے آگے والا ہموار بٹن ہے۔"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"فنگر پرنٹ سینسر پاور بٹن پر موجود ہے۔ یہ آلے کے کنارے پر ابھرے ہوئے والیوم بٹن کے آگے والا ہموار بٹن ہے۔"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"فنگر پرنٹ سینسر پاور بٹن پر موجود ہے۔ یہ فون کے کنارے پر ابھرے ہوئے والیوم بٹن کے آگے والا ہموار بٹن ہے۔"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"مزید اختیارات کے لیے اپنا فون غیر مقفل کریں"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"مزید اختیارات کے لیے اپنا ٹیبلیٹ غیر مقفل کریں"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"مزید اختیارات کے لیے اپنا آلہ غیر مقفل کریں"</string>
diff --git a/packages/SystemUI/res-product/values-uz/strings.xml b/packages/SystemUI/res-product/values-uz/strings.xml
index d23f541..3afa159 100644
--- a/packages/SystemUI/res-product/values-uz/strings.xml
+++ b/packages/SystemUI/res-product/values-uz/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Siz telefonni qulfdan chiqarish uchun <xliff:g id="NUMBER">%d</xliff:g> marta xato urinish qildingiz. Endi ish profili oʻchirib tashlanadi va undagi barcha maʼlumotlar ham oʻchib ketadi."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato chizildi. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan keyin sizdan emailingizdan foydalanib, planshet qulfini ochishingiz soʻraladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan keyin yana urinib koʻring."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Grafik kalit <xliff:g id="NUMBER_0">%1$d</xliff:g> marta xato chizildi. <xliff:g id="NUMBER_1">%2$d</xliff:g> marta muvaffaqiyatsiz urinishdan keyin sizdan emailngizdan foydalanib, telefon qulfini ochishingiz soʻraladi.\n\n <xliff:g id="NUMBER_2">%3$d</xliff:g> soniyadan keyin qayta urinib koʻring."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Barmoq izi sensori quvvat tugmasida joylashgan. U tekis tugma planshetning yon chekkasida tovush balandligi tugmasining yonida joylashgan\n\nQuvvat tugmasi bosilganda ekran oʻchadi."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Barmoq izi sensori quvvat tugmasida joylashgan. U tekis tugma qurilmaning yon chekkasida tovush balandligi tugmasining yonida joylashgan.\n\nQuvvat tugmasi bosilganda ekran oʻchadi."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Barmoq izi sensori quvvat tugmasida joylashgan. U tekis tugma telefonning yon chekkasida tovush balandligi tugmasining yonida joylashgan\n\nQuvvat tugmasi bosilganda ekran oʻchadi."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Barmoq izi sensori quvvat tugmasida joylashgan. U tekis tugma planshetning yon chekkasida tovush balandligi tugmasining yonida joylashgan."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Barmoq izi sensori quvvat tugmasida joylashgan. U tekis tugma qurilmaning yon chekkasida tovush balandligi tugmasining yonida joylashgan."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Barmoq izi sensori quvvat tugmasida joylashgan. U tekis tugma telefonning yon chekkasida tovush balandligi tugmasining yonida joylashgan."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Boshqa parametrlar uchun telefoningiz qulfini oching"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Boshqa parametrlar uchun planshetingiz qulfini oching"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Boshqa parametrlar uchun qurilmangiz qulfini oching"</string>
diff --git a/packages/SystemUI/res-product/values-vi/strings.xml b/packages/SystemUI/res-product/values-vi/strings.xml
index ff87ea8..6e121c6 100644
--- a/packages/SystemUI/res-product/values-vi/strings.xml
+++ b/packages/SystemUI/res-product/values-vi/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Bạn đã mở khóa điện thoại sai <xliff:g id="NUMBER">%d</xliff:g> lần. Hồ sơ công việc sẽ bị xóa, tức là tất cả dữ liệu hồ sơ sẽ bị xóa."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa máy tính bảng bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Bạn đã vẽ không chính xác hình mở khóa <xliff:g id="NUMBER_0">%1$d</xliff:g> lần. Sau <xliff:g id="NUMBER_1">%2$d</xliff:g> lần thử không thành công nữa, bạn sẽ được yêu cầu mở khóa điện thoại bằng tài khoản email.\n\n Hãy thử lại sau <xliff:g id="NUMBER_2">%3$d</xliff:g> giây."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Cảm biến vân tay nằm trên nút nguồn. Đó là nút phẳng bên cạnh nút tăng âm lượng trên cạnh của máy tính bảng.\n\nKhi bạn nhấn nút nguồn, màn hình sẽ tắt."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Cảm biến vân tay nằm trên nút nguồn. Đó là nút phẳng bên cạnh nút tăng âm lượng trên cạnh của thiết bị.\n\nKhi bạn nhấn nút nguồn, màn hình sẽ tắt."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Cảm biến vân tay nằm trên nút nguồn. Đó là nút phẳng bên cạnh nút tăng âm lượng trên cạnh của điện thoại.\n\nKhi bạn nhấn nút nguồn, màn hình sẽ tắt."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Cảm biến vân tay nằm trên nút nguồn. Đó là nút phẳng cạnh nút âm lượng nhô lên trên cạnh của máy tính bảng."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Cảm biến vân tay nằm trên nút nguồn. Đó là nút phẳng cạnh nút âm lượng nhô lên trên cạnh của thiết bị."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Cảm biến vân tay nằm trên nút nguồn. Đó là nút phẳng cạnh nút âm lượng nhô lên trên cạnh của điện thoại."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Mở khóa điện thoại của bạn để xem thêm tùy chọn"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Mở khóa máy tính bảng của bạn để xem thêm tùy chọn"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Mở khóa thiết bị của bạn để xem thêm tùy chọn"</string>
diff --git a/packages/SystemUI/res-product/values-zh-rCN/strings.xml b/packages/SystemUI/res-product/values-zh-rCN/strings.xml
index f51437e..a60982f 100644
--- a/packages/SystemUI/res-product/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res-product/values-zh-rCN/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"您尝试解锁手机后失败的次数已达 <xliff:g id="NUMBER">%d</xliff:g> 次。系统将移除此工作资料,而这将删除所有的工作资料数据。"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁平板电脑。\n\n请在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒后重试。"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"您已 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次画错解锁图案。如果再尝试 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次后仍不成功,系统就会要求您使用自己的电子邮件帐号解锁手机。\n\n请在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒后重试。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"指纹传感器在电源按钮上。电源按钮是一个扁平按钮,位于平板电脑边缘凸起的音量按钮旁边。\n\n按下电源按钮会关闭屏幕。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"指纹传感器在电源按钮上。电源按钮是一个扁平按钮,位于设备边缘凸起的音量按钮旁边。\n\n按下电源按钮会关闭屏幕。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"指纹传感器在电源按钮上。电源按钮是一个扁平按钮,位于手机边缘凸起的音量按钮旁边。\n\n按下电源按钮会关闭屏幕。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指纹传感器在电源按钮上。电源按钮是一个扁平按钮,位于平板电脑边缘凸起的音量按钮旁边。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指纹传感器在电源按钮上。电源按钮是一个扁平按钮,位于设备边缘凸起的音量按钮旁边。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指纹传感器在电源按钮上。电源按钮是一个扁平按钮,位于手机边缘凸起的音量按钮旁边。"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"解锁手机即可查看更多选项"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"解锁平板电脑即可查看更多选项"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"解锁设备即可查看更多选项"</string>
diff --git a/packages/SystemUI/res-product/values-zh-rHK/strings.xml b/packages/SystemUI/res-product/values-zh-rHK/strings.xml
index 0d529f9..9e55398 100644
--- a/packages/SystemUI/res-product/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res-product/values-zh-rHK/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"您嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。系統將移除此工作設定檔,而所有設定檔資料亦會一併刪除。"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖平板電腦。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"您已畫錯解鎖圖案 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次。如果之後再嘗試 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次仍未成功,系統會要求您透過電郵帳戶解鎖手機。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於平板電腦邊緣凸起的音量按鈕旁。\n\n按下開關按鈕即可關閉螢幕。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於裝置邊緣凸起的音量按鈕旁。\n\n按下開關按鈕即可關閉螢幕。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於手機邊緣凸起的音量按鈕旁。\n\n按下開關按鈕即可關閉螢幕。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於平板電腦邊緣凸起的音量按鈕旁。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於裝置邊緣凸起的音量按鈕旁。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指紋感應器位於開關按鈕上,開關按鈕形狀扁平,位於手機邊緣凸起的音量按鈕旁。"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"解鎖手機以存取更多選項"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"解鎖平板電腦以存取更多選項"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"解鎖裝置以存取更多選項"</string>
diff --git a/packages/SystemUI/res-product/values-zh-rTW/strings.xml b/packages/SystemUI/res-product/values-zh-rTW/strings.xml
index 4715cdbe..ae512e0 100644
--- a/packages/SystemUI/res-product/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res-product/values-zh-rTW/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"你嘗試解鎖手機已失敗 <xliff:g id="NUMBER">%d</xliff:g> 次。你的工作資料夾將遭到移除,所有設定檔資料也會一併遭到刪除。"</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"你的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會要求你透過電子郵件帳戶將平板電腦解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"你的解鎖圖案已畫錯 <xliff:g id="NUMBER_0">%1$d</xliff:g> 次,目前還剩 <xliff:g id="NUMBER_1">%2$d</xliff:g> 次機會。如果失敗次數超過限制,系統會要求你透過電子郵件帳戶將手機解鎖。\n\n請在 <xliff:g id="NUMBER_2">%3$d</xliff:g> 秒後再試一次。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"指紋感應器在電源鍵上。電源鍵形狀扁平,位於平板電腦側邊的調高音量按鈕旁。\n\n按下電源鍵可關閉螢幕。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"指紋感應器在電源鍵上。電源鍵形狀扁平,位於裝置側邊的調高音量按鈕旁。\n\n按下電源鍵可關閉螢幕。"</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"指紋感應器在電源鍵上。電源鍵形狀扁平,位於手機側邊的調高音量按鈕旁。\n\n按下電源鍵可關閉螢幕。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在平板電腦側邊凸起的音量按鈕旁。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在裝置側邊凸起的音量按鈕旁。"</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"指紋感應器在電源鍵上。電源鍵的形狀是扁平的,位在手機側邊凸起的音量按鈕旁。"</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"解鎖手機可查看更多選項"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"解鎖平板電腦可查看更多選項"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"解鎖裝置可查看更多選項"</string>
diff --git a/packages/SystemUI/res-product/values-zu/strings.xml b/packages/SystemUI/res-product/values-zu/strings.xml
index 26a6f4e..6b20014 100644
--- a/packages/SystemUI/res-product/values-zu/strings.xml
+++ b/packages/SystemUI/res-product/values-zu/strings.xml
@@ -40,9 +40,9 @@
<string name="kg_failed_attempts_now_erasing_profile" product="default" msgid="4682221342671290678">"Uzame ngokungalungile ukuvula ifoni izikhathi ezingu-<xliff:g id="NUMBER">%d</xliff:g>. Iphrofayela yomsebenzi izosuswa, okuzosusa yonke idatha yephrofayela."</string>
<string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="1860049973474855672">"Udwebe ngokungalungile iphethini yakho yokuvula ngezikhathi ezingu-<xliff:g id="NUMBER_0">%1$d</xliff:g>. Ngemuva kwemizamo engaphumelelanga kaningi engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuthi uvule ithebulethi yakho usebenzisa i-akhawunti ye-imeyili.\n\nZama futhi kumasekhondi angu-<xliff:g id="NUMBER_2">%3$d</xliff:g>."</string>
<string name="kg_failed_attempts_almost_at_login" product="default" msgid="44112553371516141">"Ukulayisha ungenisa iphathini yakho yokuvula ngendlela engalungile izikhathi ezi-<xliff:g id="NUMBER_0">%1$d</xliff:g> Emva kweminye imizamo engu-<xliff:g id="NUMBER_1">%2$d</xliff:g>, uzocelwa ukuvula ifoni yakho usebenzisa ukungena ngemvume ku-Google\n\n Zame futhi emumva kwengu- <xliff:g id="NUMBER_2">%3$d</xliff:g> imizuzwana."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="1242939073723573315">"Inzwa yesigxivizo somunwe esenkinobhweni yamandla. Yinkinobho eyisicaba eduze kwenkinobho yevolumu ephakanyisiwe emaphethelweni ethebulethi.\n\nUkucindezela inkinobho yamandla kuvala isikrini."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="7305137594359170451">"Inzwa yesigxivizo somunwe esenkinobhweni yamandla. Yinkinobho eyisicaba eduze kwenkinobho yevolumu ephakanyisiwe emaphethelweni edivayisi.\n\nUkucindezela inkinobho yamandla kuvala isikrini."</string>
- <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="3238514774114999081">"Inzwa yesigxivizo somunwe esenkinobhweni yamandla. Yinkinobho eyisicaba eduze kwenkinobho yevolumu ephakanyisiwe emaphethelweni efoni.\n\nUkucindezela inkinobho yamandla kuvala isikrini."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="tablet" msgid="3726972508570143945">"Inzwa yesigxivizo somunwe esenkinobhweni yamandla. Inkinobho eyisicaba eduze kwenkinobho yevolumu ephakanyisiwe emaphethelweni wethebulethi."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="device" msgid="2929467060295094725">"Inzwa yesigxivizo somunwe esenkinobhweni yamandla. Inkinobho eyisicaba eduze kwenkinobho yevolumu ephakanyisiwe emaphethelweni edivayisi."</string>
+ <string name="security_settings_sfps_enroll_find_sensor_message" product="default" msgid="8582726566542997639">"Inzwa yesigxivizo somunwe esenkinobhweni yamandla. Inkinobho eyisicaba eduze kwenkinobho yevolumu ephakanyisiwe emaphethelweni efoni."</string>
<string name="global_action_lock_message" product="default" msgid="7092460751050168771">"Vula ifoni yakho ukuthola okunye okungakhethwa"</string>
<string name="global_action_lock_message" product="tablet" msgid="1024230056230539493">"Vula ithebulethi yakho ukuthola okunye okungakhethwa"</string>
<string name="global_action_lock_message" product="device" msgid="3165224897120346096">"Vula idivayisi yakho ukuthola okunye okungakhethwa"</string>
diff --git a/packages/SystemUI/res/layout/activity_rear_display_education.xml b/packages/SystemUI/res/layout/activity_rear_display_education.xml
index 094807e..c295cfe 100644
--- a/packages/SystemUI/res/layout/activity_rear_display_education.xml
+++ b/packages/SystemUI/res/layout/activity_rear_display_education.xml
@@ -30,6 +30,7 @@
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/rear_display_folded_animation"
+ android:importantForAccessibility="no"
android:layout_width="@dimen/rear_display_animation_width"
android:layout_height="@dimen/rear_display_animation_height"
android:layout_gravity="center"
diff --git a/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml b/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml
index e970bc5..c12bfcc 100644
--- a/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml
+++ b/packages/SystemUI/res/layout/activity_rear_display_education_opened.xml
@@ -31,6 +31,7 @@
<com.airbnb.lottie.LottieAnimationView
android:id="@+id/rear_display_folded_animation"
+ android:importantForAccessibility="no"
android:layout_width="@dimen/rear_display_animation_width"
android:layout_height="@dimen/rear_display_animation_height"
android:layout_gravity="center"
diff --git a/packages/SystemUI/res/layout/chipbar.xml b/packages/SystemUI/res/layout/chipbar.xml
index a317178..762dcdc 100644
--- a/packages/SystemUI/res/layout/chipbar.xml
+++ b/packages/SystemUI/res/layout/chipbar.xml
@@ -55,7 +55,7 @@
android:layout_height="wrap_content"
android:layout_weight="1"
android:textSize="@dimen/chipbar_text_size"
- android:textColor="@android:color/system_accent2_900"
+ android:textColor="@color/chipbar_text_and_icon_color"
android:alpha="0.0"
/>
diff --git a/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml b/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml
index 5b2ec48..0cd0623 100644
--- a/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_home_controls_chip.xml
@@ -14,22 +14,15 @@
~ See the License for the specific language governing permissions and
~ limitations under the License.
-->
-<FrameLayout
+<com.android.systemui.animation.view.LaunchableImageView
xmlns:android="http://schemas.android.com/apk/res/android"
- android:layout_height="wrap_content"
- android:layout_width="wrap_content"
- android:paddingVertical="@dimen/dream_overlay_complication_home_controls_padding">
-
- <com.android.systemui.animation.view.LaunchableImageView
- android:id="@+id/home_controls_chip"
- android:layout_height="@dimen/dream_overlay_bottom_affordance_height"
- android:layout_width="@dimen/dream_overlay_bottom_affordance_width"
- android:layout_gravity="bottom|start"
- android:padding="@dimen/dream_overlay_bottom_affordance_padding"
- android:background="@drawable/dream_overlay_bottom_affordance_bg"
- android:scaleType="fitCenter"
- android:tint="?android:attr/textColorPrimary"
- android:src="@drawable/controls_icon"
- android:contentDescription="@string/quick_controls_title" />
-
-</FrameLayout>
+ android:id="@+id/home_controls_chip"
+ android:layout_height="@dimen/dream_overlay_bottom_affordance_height"
+ android:layout_width="@dimen/dream_overlay_bottom_affordance_width"
+ android:layout_gravity="bottom|start"
+ android:padding="@dimen/dream_overlay_bottom_affordance_padding"
+ android:background="@drawable/dream_overlay_bottom_affordance_bg"
+ android:scaleType="fitCenter"
+ android:tint="?android:attr/textColorPrimary"
+ android:src="@drawable/controls_icon"
+ android:contentDescription="@string/quick_controls_title" />
diff --git a/packages/SystemUI/res/layout/dream_overlay_media_entry_chip.xml b/packages/SystemUI/res/layout/dream_overlay_media_entry_chip.xml
index 50f3ffc..b75c638 100644
--- a/packages/SystemUI/res/layout/dream_overlay_media_entry_chip.xml
+++ b/packages/SystemUI/res/layout/dream_overlay_media_entry_chip.xml
@@ -17,13 +17,12 @@
<ImageView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/media_entry_chip"
- android:layout_height="@dimen/keyguard_affordance_fixed_height"
- android:layout_width="@dimen/keyguard_affordance_fixed_width"
+ android:layout_height="@dimen/dream_overlay_bottom_affordance_height"
+ android:layout_width="@dimen/dream_overlay_bottom_affordance_width"
android:layout_gravity="bottom|start"
- android:scaleType="center"
+ android:scaleType="fitCenter"
+ android:padding="@dimen/dream_overlay_bottom_affordance_padding"
android:tint="?android:attr/textColorPrimary"
android:src="@drawable/ic_music_note"
- android:background="@drawable/keyguard_bottom_affordance_bg"
- android:layout_marginStart="@dimen/keyguard_affordance_horizontal_offset"
- android:layout_marginBottom="@dimen/keyguard_affordance_vertical_offset"
+ android:background="@drawable/dream_overlay_bottom_affordance_bg"
android:contentDescription="@string/controls_media_title" />
diff --git a/packages/SystemUI/res/layout/media_recommendation_view.xml b/packages/SystemUI/res/layout/media_recommendation_view.xml
index a4aeba1..e63aa21 100644
--- a/packages/SystemUI/res/layout/media_recommendation_view.xml
+++ b/packages/SystemUI/res/layout/media_recommendation_view.xml
@@ -31,8 +31,10 @@
<!-- App icon -->
<com.android.internal.widget.CachingIconView
android:id="@+id/media_rec_app_icon"
- android:layout_width="@dimen/qs_media_rec_icon_top_margin"
- android:layout_height="@dimen/qs_media_rec_icon_top_margin"
+ android:layout_width="@dimen/qs_media_rec_album_icon_size"
+ android:layout_height="@dimen/qs_media_rec_album_icon_size"
+ android:minWidth="@dimen/qs_media_rec_album_icon_size"
+ android:minHeight="@dimen/qs_media_rec_album_icon_size"
android:layout_marginStart="@dimen/qs_media_info_spacing"
android:layout_marginTop="@dimen/qs_media_info_spacing"/>
diff --git a/packages/SystemUI/res/layout/media_session_view.xml b/packages/SystemUI/res/layout/media_session_view.xml
index 9d91419..85b6e8d 100644
--- a/packages/SystemUI/res/layout/media_session_view.xml
+++ b/packages/SystemUI/res/layout/media_session_view.xml
@@ -97,7 +97,8 @@
android:background="@drawable/qs_media_light_source"
android:forceHasOverlappingRendering="false"
android:layout_width="wrap_content"
- android:layout_height="@dimen/min_clickable_item_size"
+ android:minHeight="@dimen/min_clickable_item_size"
+ android:layout_height="wrap_content"
android:layout_marginStart="@dimen/qs_center_guideline_padding"
app:layout_constraintEnd_toEndOf="parent"
app:layout_constraintTop_toTopOf="parent"
diff --git a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
index aa655e6..9304ff7 100644
--- a/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
+++ b/packages/SystemUI/res/layout/media_smartspace_recommendations.xml
@@ -40,6 +40,8 @@
android:id="@+id/recommendation_card_icon"
android:layout_width="@dimen/qs_media_app_icon_size"
android:layout_height="@dimen/qs_media_app_icon_size"
+ android:minWidth="@dimen/qs_media_app_icon_size"
+ android:minHeight="@dimen/qs_media_app_icon_size"
android:layout_marginStart="@dimen/qs_media_padding"
android:layout_marginTop="@dimen/qs_media_rec_icon_top_margin"
app:layout_constraintStart_toStartOf="parent"
@@ -53,6 +55,8 @@
android:id="@+id/media_cover1"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:minWidth="@dimen/qs_media_rec_album_size"
+ android:minHeight="@dimen/qs_media_rec_album_size"
app:layout_constraintTop_toTopOf="parent"
app:layout_constraintBottom_toBottomOf="parent"
android:adjustViewBounds="true"
@@ -80,6 +84,8 @@
android:id="@+id/media_cover2"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:minWidth="@dimen/qs_media_rec_album_size"
+ android:minHeight="@dimen/qs_media_rec_album_size"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
style="@style/MediaPlayer.Recommendation.Album"
@@ -105,6 +111,8 @@
android:id="@+id/media_cover3"
android:layout_width="match_parent"
android:layout_height="match_parent"
+ android:minWidth="@dimen/qs_media_rec_album_size"
+ android:minHeight="@dimen/qs_media_rec_album_size"
android:adjustViewBounds="true"
android:background="@drawable/bg_smartspace_media_item"
style="@style/MediaPlayer.Recommendation.Album"
diff --git a/packages/SystemUI/res/layout/multi_shade.xml b/packages/SystemUI/res/layout/multi_shade.xml
new file mode 100644
index 0000000..78ff5f0
--- /dev/null
+++ b/packages/SystemUI/res/layout/multi_shade.xml
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ ~ Copyright (C) 2023 The Android Open Source Project
+ ~
+ ~ Licensed under the Apache License, Version 2.0 (the "License");
+ ~ you may not use this file except in compliance with the License.
+ ~ You may obtain a copy of the License at
+ ~
+ ~ http://www.apache.org/licenses/LICENSE-2.0
+ ~
+ ~ Unless required by applicable law or agreed to in writing, software
+ ~ distributed under the License is distributed on an "AS IS" BASIS,
+ ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ ~ See the License for the specific language governing permissions and
+ ~ limitations under the License.
+ ~
+ -->
+
+<com.android.systemui.multishade.ui.view.MultiShadeView
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent" />
diff --git a/packages/SystemUI/res/layout/notification_conversation_info.xml b/packages/SystemUI/res/layout/notification_conversation_info.xml
index 9b2f0ac..79948da 100644
--- a/packages/SystemUI/res/layout/notification_conversation_info.xml
+++ b/packages/SystemUI/res/layout/notification_conversation_info.xml
@@ -311,7 +311,7 @@
android:clickable="false"
android:focusable="false"
android:ellipsize="end"
- android:maxLines="3"
+ android:maxLines="4"
android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
</com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
@@ -364,7 +364,7 @@
android:clickable="false"
android:focusable="false"
android:ellipsize="end"
- android:maxLines="3"
+ android:maxLines="4"
android:textAppearance="@style/TextAppearance.NotificationImportanceDetail"/>
</com.android.systemui.statusbar.notification.row.ButtonLinearLayout>
diff --git a/packages/SystemUI/res/layout/status_bar_user_chip_container.xml b/packages/SystemUI/res/layout/status_bar_user_chip_container.xml
index b374074..80f5d87 100644
--- a/packages/SystemUI/res/layout/status_bar_user_chip_container.xml
+++ b/packages/SystemUI/res/layout/status_bar_user_chip_container.xml
@@ -24,7 +24,7 @@
android:orientation="horizontal"
android:layout_marginEnd="@dimen/status_bar_user_chip_end_margin"
android:background="@drawable/status_bar_user_chip_bg"
- android:visibility="visible" >
+ android:visibility="gone" >
<ImageView android:id="@+id/current_user_avatar"
android:layout_width="@dimen/status_bar_user_chip_avatar_size"
android:layout_height="@dimen/status_bar_user_chip_avatar_size"
diff --git a/packages/SystemUI/res/layout/super_notification_shade.xml b/packages/SystemUI/res/layout/super_notification_shade.xml
index 4abc176..fe9542b 100644
--- a/packages/SystemUI/res/layout/super_notification_shade.xml
+++ b/packages/SystemUI/res/layout/super_notification_shade.xml
@@ -110,6 +110,13 @@
android:clipChildren="false"
android:clipToPadding="false" />
+ <ViewStub
+ android:id="@+id/multi_shade_stub"
+ android:layout_width="match_parent"
+ android:layout_height="match_parent"
+ android:inflatedId="@+id/multi_shade"
+ android:layout="@layout/multi_shade" />
+
<com.android.systemui.biometrics.AuthRippleView
android:id="@+id/auth_ripple"
android:layout_width="match_parent"
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json
deleted file mode 100644
index 49c1c40..0000000
--- a/packages/SystemUI/res/raw/biometricprompt_rear_landscape_base.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Landscape_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":1,"k":[{"i":{"x":[0.2],"y":[1]},"o":{"x":[0.7],"y":[0]},"t":-129,"s":[-67]},{"t":-29,"s":[0]}],"ix":10},"p":{"a":0,"k":[-75.352,41.307,0],"ix":2,"l":2},"a":{"a":0,"k":[94.648,211.307,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.72,-5.642],[0,0],[-9.394,-0.562],[-0.298,-0.038]],"o":[[-5.153,4.329],[3.882,-16.05],[0.31,0.019],[-0.044,0.75]],"v":[[0.863,12.222],[-8.931,14.755],[8.005,-15.108],[8.931,-15.021]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[81.486,130.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 9","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.459,6.045],[-5.153,4.329],[-0.044,0.75],[3.116,-24.664],[5.23,-22.052],[8.666,11.92],[-2.9,9.135]],"o":[[0,0],[6.72,-5.642],[12.723,1.335],[-2.369,18.762],[-13.993,-5.333],[2.255,-5.502],[1.843,-5.815]],"v":[[-9.99,-18.348],[-0.196,-20.881],[7.872,-48.124],[21.578,-9.331],[12.104,48.124],[-22.574,21.555],[-14.791,-0.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82.545,163.184],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 8","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"black circle matte 4","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"black circle matte 5","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".grey700","cl":"grey700","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json
deleted file mode 100644
index 9ea0d35..0000000
--- a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_base.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Portrait_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":14,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 3","tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":-2,"ix":10},"p":{"a":0,"k":[260.134,83.782,0],"ix":2,"l":2},"a":{"a":0,"k":[302.634,38.782,0],"ix":1,"l":2},"s":{"a":0,"k":[178,178,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-4.262,5.076],[0,0],[-0.424,-7.095],[-0.028,-0.225]],"o":[[3.269,-3.892],[-12.123,2.932],[0.015,0.234],[0.567,-0.034]],"v":[[9.232,0.652],[11.145,-6.746],[-11.412,6.046],[-11.346,6.746]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[241.281,55.033],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[4.565,-1.102],[3.269,-3.892],[0.566,-0.033],[-18.63,2.353],[-16.656,3.951],[9.004,6.546],[6.9,-2.19]],"o":[[0,0],[-4.262,5.076],[1.008,9.61],[14.171,-1.79],[-4.028,-10.569],[-4.156,1.703],[-4.392,1.392]],"v":[[-13.858,-7.546],[-15.771,-0.148],[-36.349,5.946],[-7.047,16.299],[36.349,9.142],[16.281,-17.051],[-0.156,-11.172]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[266.285,55.833],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 4","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":"black circle matte 4","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":"black circle matte 5","parent":14,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey700","cl":"grey700","parent":16,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":16,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
\ No newline at end of file
diff --git a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json b/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json
deleted file mode 100644
index f2b2593..0000000
--- a/packages/SystemUI/res/raw/biometricprompt_rear_portrait_reverse_base.json
+++ /dev/null
@@ -1 +0,0 @@
-{"v":"5.8.1","fr":60,"ip":0,"op":21,"w":340,"h":340,"nm":"BiometricPrompt_Rear_Portrait_Reverse_Base_Foldable","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":3,"nm":"Null 18","sr":1,"ks":{"o":{"a":0,"k":0,"ix":11},"r":{"a":0,"k":270,"ix":10},"p":{"a":0,"k":[169.478,169.749,0],"ix":2,"l":2},"a":{"a":0,"k":[-48.123,-30.19,0],"ix":1,"l":2},"s":{"a":0,"k":[132,132,100],"ix":6,"l":2}},"ao":0,"ip":0,"op":900,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":".grey400","cl":"grey400","parent":13,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"st","c":{"a":0,"k":[0.741176486015,0.75686275959,0.776470601559,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":1,"ix":5},"lc":1,"lj":1,"ml":10,"bm":0,"nm":"Stroke 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"black circle matte","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":4,"ty":4,"nm":".grey904","cl":"grey904","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,35.536,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[0,0],[-2.552,0.087],[0,0]],"o":[[0,0],[0,-3.287],[0,0],[0,0]],"v":[[-2.301,8.869],[-2.301,-3.772],[2.301,-9.806],[2.301,9.806]],"c":false},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":5,"ty":4,"nm":"black circle matte 2","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":6,"ty":4,"nm":".blue401","cl":"blue401","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-62.577,-27.655,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,3.286],[0,0],[-2.552,0.086],[0,0]],"o":[[0,0],[0,-3.286],[0,0],[-2.552,-0.086]],"v":[[-2.301,16.282],[-2.301,-16.281],[2.301,-22.313],[2.301,22.313]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.40000000596,0.615686297417,0.964705884457,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":7,"ty":4,"nm":"black circle matte 3","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":8,"ty":4,"nm":"Finger 2","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-75.352,41.307,0],"ix":2,"l":2},"a":{"a":0,"k":[94.648,211.307,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[6.72,-5.642],[0,0],[-9.394,-0.562],[-0.298,-0.038]],"o":[[-5.153,4.329],[3.882,-16.05],[0.31,0.019],[-0.044,0.75]],"v":[[0.863,12.222],[-8.931,14.755],[8.005,-15.108],[8.931,-15.021]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.792156875134,0.454901963472,0.376470595598,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[81.486,130.081],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 9","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.459,6.045],[-5.153,4.329],[-0.044,0.75],[3.116,-24.664],[5.23,-22.052],[8.666,11.92],[-2.9,9.135]],"o":[[0,0],[6.72,-5.642],[12.723,1.335],[-2.369,18.762],[-13.993,-5.333],[2.255,-5.502],[1.843,-5.815]],"v":[[-9.99,-18.348],[-0.196,-20.881],[7.872,-48.124],[21.578,-9.331],[12.104,48.124],[-22.574,21.555],[-14.791,-0.206]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.713725507259,0.384313732386,0.282352954149,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[82.545,163.184],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 8","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":9,"ty":4,"nm":"black circle matte 4","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":10,"ty":4,"nm":".grey903","cl":"grey903","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-18.345,-92.442,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[24.07,0],[0,0],[-8.27,0],[0,0]],"o":[[0,0],[0,8.269],[0,0],[-14.024,-17.379]],"v":[[-29.778,-14.252],[-29.778,-0.721],[-14.805,14.252],[29.778,14.252]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":11,"ty":4,"nm":"black circle matte 5","parent":13,"td":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[0,0,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":12,"ty":4,"nm":".grey902","cl":"grey902","parent":1,"tt":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-15.947,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[154.053,139.81,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[2.3,0.367],[0,0],[-2.364,0.157],[0,0]],"o":[[0,0],[2.3,-0.367],[0,0],[-2.364,-0.157]],"v":[[-3.5,75.533],[-3.5,-75.533],[3.5,-76.312],[3.5,76.312]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[113.225,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 7","np":1,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"gr","it":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,8.269],[0,0],[2.181,-0.187],[0,0],[-2.23,0],[0,42.252],[10.593,13.127],[0,0]],"o":[[0,0],[-2.23,0],[0,0],[2.181,0.187],[42.252,0],[0,-18.182],[0,0],[-8.27,0]],"v":[[-34.946,-62.973],[-34.946,-76.504],[-41.558,-76.201],[-41.558,76.201],[-34.946,76.504],[41.558,0],[24.61,-48],[-19.973,-48]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.525490224361,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tr","p":{"a":0,"k":[156.824,139.81],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Layer 5","np":1,"cix":2,"bm":0,"ix":2,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":13,"ty":4,"nm":".black 2","cl":"black","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-48.123,-30.19,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":1,"k":[{"i":{"x":[0.2,0.2,0.833],"y":[1,1,1]},"o":{"x":[0.7,0.7,0.167],"y":[0,0,0]},"t":-129,"s":[0,0,100]},{"t":-79,"s":[100,100,100]}],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-42.252,0],[0,42.252],[42.252,0],[0,-42.252]],"o":[[42.252,0],[0,-42.252],[-42.252,0],[0,42.252]],"v":[[0,76.504],[76.504,0],[0,-76.504],[-76.504,0]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0,0,0,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":14,"ty":4,"nm":".grey700","cl":"grey700","parent":15,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[-56.481,-59.936,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[100,100,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[3.767,0],[0,0],[0,-3.767],[0,0],[-3.767,0],[0,0],[0,3.767],[0,0]],"o":[[0,0],[-3.767,0],[0,0],[0,3.767],[0,0],[3.767,0],[0,0],[0,-3.767]],"v":[[46.055,-14.479],[-46.056,-14.479],[-52.876,-7.659],[-52.876,7.658],[-46.056,14.479],[46.055,14.479],[52.876,7.658],[52.876,-7.659]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.372549027205,0.388235300779,0.407843142748,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0},{"ddd":0,"ind":15,"ty":4,"nm":".grey901","cl":"grey901","parent":1,"sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[16.485,2.727,0],"ix":2,"l":2},"a":{"a":0,"k":[0,0,0],"ix":1,"l":2},"s":{"a":0,"k":[50,50,100],"ix":6,"l":2}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[4.184,0],[0,0],[0,0],[0,0],[0,-4.375]],"o":[[0,4.184],[0,0],[0,0],[0,0],[4.375,0],[0,0]],"v":[[114.116,92.129],[106.54,99.705],[7.788,99.705],[7.788,-99.704],[106.161,-99.704],[114.116,-91.749]],"c":true},"ix":2},"nm":"Path 1","mn":"ADBE Vector Shape - Group","hd":false},{"ind":1,"ty":"sh","ix":2,"ks":{"a":0,"k":{"i":[[5.707,0],[0,0],[1.894,-1.05],[0.886,0.346],[0,0],[2.166,0],[0,0],[0,-5.707],[0,0],[0,-1.46],[0,0],[-1.133,-0.038],[0,0],[0,-1.459],[0,0],[-1.133,-0.038],[0,0],[-5.708,0],[0,0],[-1.894,1.05],[-0.846,-0.289],[0,0],[-2.166,0],[0,0],[0,5.706],[0,0]],"o":[[0,0],[-2.166,0],[-0.883,0.354],[0,0],[-1.895,-1.05],[0,0],[-5.708,0],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[-1.133,0.038],[0,0],[0,1.46],[0,0],[0,5.707],[0,0],[2.165,0],[0.833,-0.334],[0,0],[1.894,1.05],[0,0],[5.707,0],[0,0],[0,-5.707]],"v":[[106.16,-102.082],[8.455,-102.082],[2.265,-100.48],[-0.488,-100.468],[-0.519,-100.48],[-6.71,-102.082],[-104.116,-102.082],[-114.45,-91.748],[-114.45,-36.119],[-116.494,-33.44],[-116.494,-18.979],[-114.45,-16.3],[-114.45,-0.877],[-116.494,1.802],[-116.494,28.704],[-114.45,31.383],[-114.45,91.749],[-104.116,102.083],[-6.495,102.083],[-0.305,100.481],[2.294,100.425],[2.395,100.481],[9.872,102.083],[106.161,102.083],[116.494,91.75],[116.494,-91.748]],"c":true},"ix":2},"nm":"Path 2","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[0.501960813999,0.529411792755,0.54509806633,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"Fill 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[100,100],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"Transform"}],"nm":"Group 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":-189,"op":711,"st":-189,"bm":0}],"markers":[{"tm":255,"cm":"","dr":0},{"tm":364,"cm":"","dr":0},{"tm":482,"cm":"","dr":0},{"tm":600,"cm":"","dr":0}]}
\ 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 6657544..8e4cc43 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Vergroot die hele skerm"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Vergroot \'n deel van die skerm"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Wissel"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Maak vergrotinginstellings oop"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Sleep hoek om grootte te verander"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Laat diagonale rollees toe"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Verander grootte"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Linkerhandvatsel"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Regterhandvatsel"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Onderste handvatsel"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Vergrotinginstellings"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Vergrootglasgrootte"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoem"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Medium"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrole bygevoeg.}other{# kontroles bygevoeg.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Verwyder"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Voeg <xliff:g id="APPNAME">%s</xliff:g> by?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Verwyder kontroles vir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"As gunsteling gemerk"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Wys en beheer toestelle van sluitskerm af?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Jy kan vir jou eksterne toestelle kontroles op die sluitskerm byvoeg.\n\nJou toestelprogram kan jou dalk toelaat om sommige toestelle te beheer sonder om jou foon of tablet te ontsluit.\n\nJy kan enige tyd in Instellings veranderings maak."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Beheer toestelle van sluitskerm af?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Jy kan sommige toestelle beheer sonder om jou foon of tablet te ontsluit. Jou toestelapp bepaal watter toestelle op dié manier beheer kan word."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nee, dankie"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ja"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN bevat letters of simbole"</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 1d414aa4..2991118 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ሙሉ ገጽ እይታን ያጉሉ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"የማያ ገጹን ክፍል አጉላ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ማብሪያ/ማጥፊያ"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"የማጉያ ቅንብሮችን ክፈት"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"መጠን ለመቀየር ጠርዙን ይዘው ይጎትቱ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ሰያፍ ሽብለላን ፍቀድ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"መጠን ቀይር"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"የግራ መያዣ"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"የቀኝ መያዣ"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"የታች መያዣ"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"የማጉያ ቅንብሮች"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"የማጉያ መጠን"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"አጉላ"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"መካከለኛ"</string>
@@ -873,10 +871,9 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ቁጥጥር ታክሏል።}one{# ቁጥጥር ታክሏል።}other{# ቁጥጥሮች ታክለዋል።}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ተወግዷል"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ይታከል?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
- <!-- no translation found for controls_panel_remove_app_authorization (5920442084735364674) -->
- <skip />
+ <string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"የ<xliff:g id="APPNAME">%s</xliff:g> መቆጣጠሪያዎች ይወገዱ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ተወዳጅ የተደረገ"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"ተወዳጅ ተደርጓል፣ አቋም <xliff:g id="NUMBER">%d</xliff:g>"</string>
<string name="accessibility_control_not_favorite" msgid="1291760269563092359">"ተወዳጅ አልተደረገም"</string>
@@ -894,15 +891,13 @@
<string name="controls_favorite_other_zone_header" msgid="9089613266575525252">"ሌላ"</string>
<string name="controls_dialog_title" msgid="2343565267424406202">"ወደ የመሣሪያ መቆጣጠሪያዎች ያክሉ"</string>
<string name="controls_dialog_ok" msgid="2770230012857881822">"አክል"</string>
- <!-- no translation found for controls_dialog_remove (3775288002711561936) -->
- <skip />
+ <string name="controls_dialog_remove" msgid="3775288002711561936">"አስወግድ"</string>
<string name="controls_dialog_message" msgid="342066938390663844">"በ<xliff:g id="APP">%s</xliff:g> የተጠቆመ"</string>
<string name="controls_tile_locked" msgid="731547768182831938">"መሣሪያ ተቆልፏል"</string>
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ከማያ ገጽ ቆልፍ ላይ መሳሪያዎች ይታዩ እና ይቆጣጠሩ?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ለውጫዊ መሳሪያዎችዎ መቆጣጠሪያዎችን ወደ ማያ ገጽ ቆልፍ ማከል ይችላሉ።\n\nየእርስዎ መሣሪያ መተግበሪያ የእርስዎን ስልክ ወይም ጡባዊ ሳይከፍቱ አንዳንድ መሣሪያዎችን እንዲቆጣጠሩ ሊፈቅድልዎ ይችላል።\n\nበቅንብሮች ውስጥ በማንኛውም ጊዜ ለውጦችን ማድረግ ይችላሉ።"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"መሳሪያዎች ከማያ ገጽ ቆልፍ ይቆጣጠሩ?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"የእርስዎን ስልክ ወይም ጡባዊ ሳይከፍቱ አንዳንድ መሣሪያዎችን መቆጣጠር ይችላሉ። የእርስዎ መሣሪያ መተግበሪያ የትኞቹን መሣሪያዎች በዚህ መንገድ መቆጣጠር እንደሚቻል ይወስናል።"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"አይ፣ አመሰግናለሁ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"አዎ"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ፒን ፊደሎችን ወይም ምልክቶችን ይይዛል"</string>
@@ -950,8 +945,7 @@
<string name="controls_menu_add" msgid="4447246119229920050">"መቆጣጠሪያዎችን አክል"</string>
<string name="controls_menu_edit" msgid="890623986951347062">"መቆጣጠሪያዎችን ያርትዑ"</string>
<string name="controls_menu_add_another_app" msgid="8661172304650786705">"መተግበሪያ አክል"</string>
- <!-- no translation found for controls_menu_remove (3006525275966023468) -->
- <skip />
+ <string name="controls_menu_remove" msgid="3006525275966023468">"መተግበሪያን አስወግድ"</string>
<string name="media_output_dialog_add_output" msgid="5642703238877329518">"ውጽዓቶችን ያክሉ"</string>
<string name="media_output_dialog_group" msgid="5571251347877452212">"ቡድን"</string>
<string name="media_output_dialog_single_device" msgid="3102758980643351058">"1 መሣሪያ ተመርጧል"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index d6a7a9a..53c0bee 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"تكبير الشاشة كلها"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"تكبير جزء من الشاشة"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"تبديل"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"فتح إعدادات التكبير"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"اسحب الزاوية لتغيير الحجم."</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"السماح بالتمرير القطري"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"تغيير الحجم"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"المقبض الأيسر"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"المقبض الأيمن"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"المقبض السفلي"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"إعدادات التكبير"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"حجم مكبّر الشاشة"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"تكبير/تصغير"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"متوسط"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{تمت إضافة عنصر تحكّم واحد.}zero{تمت إضافة # عنصر تحكّم.}two{تمت إضافة عنصرَي تحكّم.}few{تمت إضافة # عناصر تحكّم.}many{تمت إضافة # عنصر تحكّم.}other{تمت إضافة # عنصر تحكّم.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"تمت الإزالة"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"هل تريد إضافة \"<xliff:g id="APPNAME">%s</xliff:g>\"؟"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"هل تريد إزالة عناصر التحكّم في \"<xliff:g id="APPNAME">%s</xliff:g>\"؟"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"تمت الإضافة إلى المفضّلة"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"هل تريد عرض أجهزتك والتحكم فيها من شاشة القفل؟"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"يمكنك إضافة عناصر تحكم لشاشة القفل الخاصة بأجهزتك الخارجية.\n\nقد يسمح لك تطبيق الجهاز بالتحكم في بعض الأجهزة بدون فتح قفل هاتفك أو جهازك اللوحي.\n\nيمكنك إجراء التغييرات في أي وقت من الإعدادات."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"هل تريد التحكم في الأجهزة من شاشة القفل؟"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"يمكنك التحكّم في بعض الأجهزة بدون فتح قفل هاتفك أو جهازك اللوحي. يحدِّد تطبيق التحكّم بجهاز آخر الأجهزة التي يمكن التحكّم فيها على هذا النحو."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"لا، شكرًا"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"نعم"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"يشتمل رقم التعريف الشخصي على أحرف أو رموز."</string>
diff --git a/packages/SystemUI/res/values-as/strings.xml b/packages/SystemUI/res/values-as/strings.xml
index c90abb7..d076ed4 100644
--- a/packages/SystemUI/res/values-as/strings.xml
+++ b/packages/SystemUI/res/values-as/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"পূৰ্ণ স্ক্ৰীন বিবৰ্ধন কৰক"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্ৰীনৰ কিছু অংশ বিবৰ্ধন কৰক"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ছুইচ"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"বিবৰ্ধন কৰাৰ ছেটিং খোলক"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"আকাৰ সলনি কৰিবলৈ চুককেইটা টানি আনি এৰক"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"কৰ্ণডালৰ দিশত স্ক্ৰ’ল কৰাৰ সুবিধা"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"আকাৰ সলনি কৰক"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"বাওঁফালৰ হেণ্ডেল"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"সোঁফালৰ হেণ্ডেল"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"তলৰ হেণ্ডেল"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"বিবৰ্ধন কৰাৰ ছেটিং"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"বিবৰ্ধকৰ আকাৰ"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"জুম কৰক"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"মধ্যমীয়া"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}one{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}other{# টা নিয়ন্ত্ৰণ যোগ দিয়া হৈছে।}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"আঁতৰোৱা হ’ল"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> যোগ দিবনে?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g>ৰ নিয়ন্ত্ৰণ আঁতৰাবনে?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"প্ৰিয় হিচাপে চিহ্নিত কৰা হ’ল"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"লক স্ক্ৰীনৰ পৰা ডিভাইচসমূহ লক আৰু নিয়ন্ত্ৰণ কৰিবনে?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"আপুনি লক স্ক্ৰীনত আপোনাৰ বাহ্যিক ডিভাইচৰ বাবে নিয়ন্ত্ৰণ যোগ দিব পাৰে।\n\nআপোনাৰ ডিভাইচ এপে আপোনাক আপোনাৰ ফ’ন অথবা টেবলেট আনলক নকৰাকৈ কিছুমান ডিভাইচ নিয়ন্ত্ৰণ কৰাৰ অনুমতি দিব পাৰে। \n\nআপুনি যিকোনো সময়তে ছেটিঙত সালসলনি কৰিব পাৰে।"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"লক স্ক্ৰীনৰ পৰা ডিভাইচসমূহ নিয়ন্ত্ৰণ কৰিবনে?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"আপুনি আপোনাৰ ফ’ন অথবা টেবলেট আনলক নকৰাকৈ কিছুমান ডিভাইচ নিয়ন্ত্ৰণ কৰিব পাৰে।এইধৰণে কোনবোৰ ডিভাইচ নিয়ন্ত্ৰণ কৰিব পাৰি সেয়া আপোনাৰ ডিভাইচ এপে নিৰ্ধাৰণ কৰে।"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"নালাগে, ধন্যবাদ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"হয়"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"পিনত বৰ্ণ অথবা প্ৰতীকসমূহ থাকে"</string>
diff --git a/packages/SystemUI/res/values-az/strings.xml b/packages/SystemUI/res/values-az/strings.xml
index 8970642..e625577 100644
--- a/packages/SystemUI/res/values-az/strings.xml
+++ b/packages/SystemUI/res/values-az/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekranı böyüdün"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekran hissəsinin böyüdülməsi"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Dəyişdirici"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Böyütmə ayarlarını açın"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Ölçüsünü dəyişmək üçün küncündən sürüşdürün"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diaqonal sürüşdürməyə icazə verin"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ölçüsünü dəyişin"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Sol tutacaq"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Sağ tutacaq"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Alt tutacaq"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Böyütmə ayarları"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Böyüdücü ölçüsü"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Orta"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# nizamlayıcı əlavə edilib.}other{# nizamlayıcı əlavə edilib.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Silinib"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> əlavə edilsin?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> nizamlayıcıları silinsin?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Sevimlilərə əlavə edilib"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Kilid ekranından cihazlar göstərilsin və idarə edilsin?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Xarici cihazlarınız üçün kilid ekranına nizamlayıcılar əlavə edə bilərsiniz.\n\nCihaz tətbiqiniz sizə telefon və ya planşetinizin kilidini açmadan bəzi cihazları idarə etməyə imkan verə bilər.\n\nİstənilən vaxt Ayarlarda dəyişiklik edə bilərsiniz."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Cihazları kilid ekranından idarə etmək istəyirsiniz?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Telefon və ya planşetin kilidini açmadan bəzi cihazları idarə edə bilərsiniz. Cihaz tətbiqi hansı cihazların bu qaydada idarə oluna biləcəyini müəyyən edir."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Xeyr, təşəkkür"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Bəli"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN hərflər və ya simvollar ehtiva edir"</string>
diff --git a/packages/SystemUI/res/values-b+sr+Latn/strings.xml b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
index 6dbe85b..4f122ec 100644
--- a/packages/SystemUI/res/values-b+sr+Latn/strings.xml
+++ b/packages/SystemUI/res/values-b+sr+Latn/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećajte ceo ekran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećajte deo ekrana"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Pređi"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otvori podešavanja uvećanja"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Prevucite ugao da biste promenili veličinu"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dozvoli dijagonalno skrolovanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Promeni veličinu"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Leva ručica"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Desna ručica"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Donja ručica"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Podešavanja uvećanja"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Veličina lupe"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zumiranje"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Srednje"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrola je dodata.}one{# kontrola je dodata.}few{# kontrole su dodate.}other{# kontrola je dodato.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite li da dodate <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Želite da uklonite kontrole za <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Označeno je kao omiljeno"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Želite li da prikazujete i kontrolišete uređaje sa zaključanog ekrana?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Možete da dodate kontrole za spoljne uređaje na zaključani ekran.\n\nAplikacija na uređaju može da vam omogući da kontrolišete neke uređaje bez otključavanja telefona ili tableta.\n\nTo možete da promenite kad god želite u Podešavanjima."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Želite li da kontrolišete uređaje sa zaključanog ekrana?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Neke uređaje možete da kontrolišete bez otključavanja telefona ili tableta. Aplikacija na uređaju određuje koji uređaji mogu da se kontrolišu na ovaj način."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, hvala"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Da"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string>
diff --git a/packages/SystemUI/res/values-be/strings.xml b/packages/SystemUI/res/values-be/strings.xml
index 8ff9fc2..4018983 100644
--- a/packages/SystemUI/res/values-be/strings.xml
+++ b/packages/SystemUI/res/values-be/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Павялічыць увесь экран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Павялічыць частку экрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Пераключальнік"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Адкрыць налады павелічэння"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Каб змяніць памер, перацягніце вугал"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дазволіць прагортванне па дыяганалі"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Змяніць памер"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Левы маркер"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Правы маркер"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Ніжні маркер"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Налады павелічэння"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Памер лупы"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Маштаб"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Сярэдні"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Дададзены # элемент кіравання.}one{Дададзена # элемента кіравання.}few{Дададзена # элементы кіравання.}many{Дададзена # элементаў кіравання.}other{Дададзена # элемента кіравання.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Выдалена"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Дадаць праграму \"<xliff:g id="APPNAME">%s</xliff:g>\"?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Выдаліць налады для <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Дададзена ў абранае"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Паказваць прылады і кіраваць імі з экрана блакіроўкі?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Вы можаце дадаць на экран блакіроўкі элементы кіравання знешнімі прыладамі.\n\nДзякуючы праграме на вашай прыладзе вы можаце кіраваць некаторымі прыладамі без разблакіроўкі тэлефона ці планшэта.\n\nУнесці змяненні можна ў любы час у Наладах."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Кіраваць прыладамі з экрана блакіроўкі?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Вы можаце кіраваць некаторымі прыладамі без разблакіроўкі тэлефона ці планшэта. Якімі прыладамі можна кіраваць такім спосабам, вызначае праграма на вашай прыладзе."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Не, дзякуй"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Так"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-код складаецца з літар або знакаў"</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index efa4113d..6a65303 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -239,7 +239,7 @@
<string name="accessibility_quick_settings_rotation" msgid="4800050198392260738">"Автоматично завъртане на екрана"</string>
<string name="quick_settings_location_label" msgid="2621868789013389163">"Местоположение"</string>
<string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Скрийнсейвър"</string>
- <string name="quick_settings_camera_label" msgid="5612076679385269339">"Камера: достъп"</string>
+ <string name="quick_settings_camera_label" msgid="5612076679385269339">"Достъп до камерата"</string>
<string name="quick_settings_mic_label" msgid="8392773746295266375">"Достъп до микрофона"</string>
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Налице"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Блокирано"</string>
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличаване на целия екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличаване на част от екрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Превключване"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Отваряне на настройките за увеличението"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Плъзнете ъгъла за преоразмеряване"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Разрешаване на диагонално превъртане"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Преоразмеряване"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Манипулатор вляво"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Манипулатор вдясно"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Манипулатор в долната част"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Настройки за увеличението"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Размер на лупата"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Промяна на мащаба"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Среден"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавена е # контрола.}other{Добавени са # контроли.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Премахнато"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Да се добави ли <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Да се премахнат ли контролите за <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено като любимо"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Да се показват ли устройствата на заключения екран и да се контролират ли оттам?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Можете да добавите към заключения екран контроли за външните си устройства.\n\nПриложението на устройството ви може да ви дава възможност да управлявате някои устройства, без да отключвате телефона или таблета си.\n\nПо всяко време можете да правите промени в „Настройки“."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Да се контролират ли устройствата от заключения екран?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Имате възможност да контролирате някои устройства, без да отключвате телефона или таблета си. Приложението на устройството ви определя кои устройства могат да бъдат контролирани по този начин."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Не, благодаря"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Да"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ПИН кодът съдържа букви или символи"</string>
diff --git a/packages/SystemUI/res/values-bn/strings.xml b/packages/SystemUI/res/values-bn/strings.xml
index 87e0a1d..373f6b4 100644
--- a/packages/SystemUI/res/values-bn/strings.xml
+++ b/packages/SystemUI/res/values-bn/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"ইউএসবি চালু করুন"</string>
<string name="learn_more" msgid="4690632085667273811">"আরও জানুন"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"স্ক্রিনশট নিন"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"এক্সটেন্ড আনলকের সুবিধা বন্ধ করা আছে"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"একটি ছবি পাঠানো হয়েছে"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"স্ক্রিনশট সেভ করা হচ্ছে..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"অফিস প্রোফাইলে স্ক্রিনশট সেভ করা হচ্ছে…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"সম্পূর্ণ স্ক্রিন বড় করে দেখা"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"স্ক্রিনের কিছুটা অংশ বড় করুন"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"বদল করুন"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"বড় করে দেখার সেটিংস খুলুন"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ছোট বড় করার জন্য কোণ টেনে আনুন"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"কোণাকুণি স্ক্রল করার অনুমতি দেওয়া"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ছোট বড় করা"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"বাঁদিকের হ্যান্ডেল"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"ডানদিকের হ্যান্ডেল"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"নিচের হ্যান্ডেল"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"বড় করে দেখার সেটিংস"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"ম্যাগনিফায়ার সাইজ"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"জুম"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"মাঝারি"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#টি কন্ট্রোল যোগ করা হয়েছে।}one{#টি কন্ট্রোল যোগ করা হয়েছে।}other{#টি কন্ট্রোল যোগ করা হয়েছে।}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"সরানো হয়েছে"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> যোগ করবেন?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g>-এর জন্য নিয়ন্ত্রণ সরিয়ে দেবেন?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"পছন্দসই হিসেবে চিহ্নিত করেছেন"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"লক স্ক্রিন থেকে ডিভাইস দেখতে এবং নিয়ন্ত্রণ করতে চান?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"লক স্ক্রিনে আপনার বাইরের ডিভাইসের জন্য কন্ট্রোল যোগ করা যাবে।\n\nআপনার ফোন বা ট্যাবলেট আনলক না করেই আপনার ডিভাইস অ্যাপ হয়ত কিছু ডিভাইস নিয়ন্ত্রণ করার সুবিধা দেবে\n\nসেটিংস থেকে যেকোনও সময়ে আপনি পরিবর্তন করতে পারবেন।"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"লক স্ক্রিন থেকে ডিভাইস নিয়ন্ত্রণ করতে চান?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"আপনি ফোন বা ট্যাবলেট আনলক না করেই কিছু ডিভাইস নিয়ন্ত্রণ করতে পারবেন। এইভাবে কোন ডিভাইস নিয়ন্ত্রণ করতে পারা যাবে তা আপনার ডিভাইস অ্যাপ ঠিক করে।"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"না থাক"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"হ্যাঁ"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"পিন-এ অক্ষর বা চিহ্ন রয়েছে"</string>
diff --git a/packages/SystemUI/res/values-bs/strings.xml b/packages/SystemUI/res/values-bs/strings.xml
index 1dfaa98..627531a 100644
--- a/packages/SystemUI/res/values-bs/strings.xml
+++ b/packages/SystemUI/res/values-bs/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Omogući USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Saznajte više"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Snimak ekrana"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Produljivanje otključavanja onemogućeno"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"je poslao/la sliku"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Spašavanje snimka ekrana..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Pohranjivanje snimka ekrana na radni profil…"</string>
@@ -834,7 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Uvećavanje prikaza preko cijelog ekrana"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Uvećavanje dijela ekrana"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Prekidač"</string>
- <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otvori postavke povećavanja"</string>
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otvori postavke uvećavanja"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Prevucite ugao da promijenite veličinu"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dozvoli dijagonalno klizanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Promijeni veličinu"</string>
@@ -844,7 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Lijeva ručica"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Desna ručica"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Donja ručica"</string>
- <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Postavke povećavanja"</string>
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Postavke uvećavanja"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Veličina povećala"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zumiranje"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Srednje"</string>
@@ -871,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodana je # kontrola.}one{Dodana je # kontrola.}few{Dodane su # kontrole.}other{Dodano je # kontrola.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Dodati aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Ukloniti kontrole za aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u omiljeno"</string>
@@ -897,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Prikazati uređaje i kontrolirati njima sa zaključanog ekrana?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na zaključani ekran možete dodati kontrole za eksterne uređaje.\n\nAplikacija vašeg uređaja vam može omogućiti da kontrolirate određene uređaje bez otključavanja telefona ili tableta.\n\nPromjene možete izvršiti bilo kada u Postavkama."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Kontrolirati uređaje sa zaključanog ekrana?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Neke uređaje možete kontrolirati bez otključavanja telefona ili tableta. Aplikacija uređaja određuje koji se uređaji mogu kontrolirati na ovaj način."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, hvala"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Da"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index 47876fe..faae1a8 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -240,7 +240,7 @@
<string name="quick_settings_location_label" msgid="2621868789013389163">"Ubicació"</string>
<string name="quick_settings_screensaver_label" msgid="1495003469366524120">"Estalvi de pantalla"</string>
<string name="quick_settings_camera_label" msgid="5612076679385269339">"Accés a la càmera"</string>
- <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accés al micròfon"</string>
+ <string name="quick_settings_mic_label" msgid="8392773746295266375">"Accés al micro"</string>
<string name="quick_settings_camera_mic_available" msgid="1453719768420394314">"Disponible"</string>
<string name="quick_settings_camera_mic_blocked" msgid="4710884905006788281">"Bloquejat"</string>
<string name="quick_settings_media_device_label" msgid="8034019242363789941">"Dispositiu multimèdia"</string>
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Amplia la pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplia una part de la pantalla"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Canvia"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Obre la configuració de l\'ampliació"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrossega el cantó per canviar la mida"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permet el desplaçament en diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Canvia la mida"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Ansa esquerra"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Ansa dreta"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Ansa inferior"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Configuració de l\'ampliació"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Mida de la lupa"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Normal"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S\'ha afegit # control.}many{S\'han afegit # controls.}other{S\'han afegit # controls.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Suprimit"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Vols afegir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Vols suprimir els controls per a <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Afegit als preferits"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Vols mostrar i controlar dispositius a la pantalla de bloqueig?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Pots afegir controls dels teus dispositius externs a la pantalla de bloqueig.\n\nL\'aplicació del dispositiu et pot permetre controlar alguns dispositius sense desbloquejar el telèfon o la tauleta.\n\nPots fer canvis en qualsevol moment a Configuració."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Vols controlar dispositius des de la pantalla de bloqueig?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Pots controlar alguns dispositius sense desbloquejar el telèfon o la tauleta. L\'aplicació del dispositiu determina quins dispositius es poden controlar d\'aquesta manera."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, gràcies"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Sí"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"El PIN conté lletres o símbols"</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 763d7f0..560ee4d 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zvětšit celou obrazovku"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zvětšit část obrazovky"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Přepnout"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otevřít nastavení zvětšení"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Velikost změníte přetažením rohu"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Povolit diagonální posouvání"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Změnit velikost"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Levý úchyt"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Pravý úchyt"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Spodní úchyt"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Nastavení zvětšení"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Velikost lupy"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Změna velikosti zobrazení"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Střední"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Byl přidán # ovládací prvek.}few{Byly přidány # ovládací prvky.}many{Bylo přidáno # ovládacího prvku.}other{Bylo přidáno # ovládacích prvků.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Odstraněno"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Přidat aplikaci <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Odstranit ovládací prvky aplikace <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Přidáno do oblíbených"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Zobrazovat a ovládat zařízení z obrazovky uzamčení?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na obrazovku uzamčení můžete přidat ovládací prvky pro svá externí zařízení.\n\nAplikace zařízení vám může umožnit ovládat některá zařízení bez odemykání telefonu nebo tabletu.\n\nZměny můžete kdykoli provést v Nastavení."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Ovládat zařízení z obrazovky uzamčení?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Některá zařízení můžete ovládat bez odemykání telefonu nebo tabletu. Aplikace zařízení určuje, která zařízení lze tímto způsobem ovládat."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, díky"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ano"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Kód PIN obsahuje písmena nebo symboly"</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index bcd44ea..5f7fc69 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstør hele skærmen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstør en del af skærmen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Skift"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Åbn indstillinger for forstørrelse"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Træk i hjørnet for at justere størrelsen"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Tillad diagonal rulning"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Juster"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Venstre håndtag"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Højre håndtag"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Nedre håndtag"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Indstillinger for forstørrelse"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Lupstørrelse"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mellem"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# styringselement er tilføjet.}one{# styringselement er tilføjet.}other{# styringselementer er tilføjet.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Vil du tilføje <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Vil du fjerne styringselementerne for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Angivet som favorit"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Vil du se og styre enheder via låseskærmen?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Du kan tilføje styringselementer til dine eksterne enheder på låseskærmen.\n\nMed din enhedsapp kan du muligvis styre visse enheder uden at låse op for din telefon eller tablet.\n\nDu kan til enhver tid foretage ændringer i Indstillinger."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Vil du styre enheder via låseskærmen?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Du kan styre visse enheder uden at låse op for din telefon eller tablet. Din enhedsapp bestemmer, hvilke enheder der kan styres på denne måde."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nej tak"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ja"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pinkoden indeholder bogstaver eller symboler"</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index b8d0a96..caac9eb 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ganzen Bildschirm vergrößern"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Teil des Bildschirms vergrößern"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Schalter"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Vergrößerungseinstellungen öffnen"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Zum Anpassen der Größe Ecke ziehen"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonales Scrollen erlauben"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Größe ändern"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Linker Ziehpunkt"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Rechter Ziehpunkt"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Unterer Ziehpunkt"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Vergrößerungseinstellungen"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Lupengröße"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mittel"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# Steuerelement hinzugefügt.}other{# Steuerelemente hinzugefügt.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Entfernt"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> hinzufügen?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Einstellungen für <xliff:g id="APPNAME">%s</xliff:g> entfernen?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Zu Favoriten hinzugefügt"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Geräte auf Sperrbildschirm anzeigen und steuern?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Du kannst dem Sperrbildschirm Steuerelemente für deine externen Geräte hinzufügen.\n\nDie App deines Geräts ermöglicht dir eventuell, einige Geräte zu steuern, ohne dein Smartphone oder Tablet zu entsperren.\n\nDu kannst jederzeit Änderungen in den Einstellungen vornehmen."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Geräte über den Sperrbildschirm steuern?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Du kannst einige Geräte steuern, ohne dass dazu das Smartphone oder Tablet entsperrt werden muss. Die Geräte-App ermittelt, welche Geräte auf diese Weise gesteuert werden können."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nein danke"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ja"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Die PIN enthält Buchstaben oder Symbole"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index d648682..7dd3593 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ενεργοποίηση USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Μάθετε περισσότερα"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Στιγμιότυπο οθόνης"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Το εκτεταμένο ξεκλείδωμα είναι απενεργοποιημένο"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"έστειλε μια εικόνα"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Αποθήκευση στιγμιότυπου οθόνης..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Αποθήκευση στιγμιότ. οθόνης στο προφίλ εργασίας…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Μεγέθυνση πλήρους οθόνης"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Μεγέθυνση μέρους της οθόνης"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Εναλλαγή"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Άνοιγμα ρυθμίσεων μεγιστοποίησης"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Σύρετε τη γωνία για αλλαγή μεγέθους"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Να επιτρέπεται η διαγώνια κύλιση"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Αλλαγή μεγέθους"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Αριστερή λαβή"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Δεξιά λαβή"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Κάτω λαβή"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Ρυθμίσεις μεγιστοποίησης"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Μέγεθος μεγεθυντικού φακού"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Εστίαση"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Μέτριο"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Προστέθηκε # στοιχείο ελέγχου.}other{Προστέθηκαν # στοιχεία ελέγχου.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Καταργήθηκε"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Προσθήκη <xliff:g id="APPNAME">%s</xliff:g>;"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Κατάργηση στοιχείων ελέγχου για την εφαρμογή <xliff:g id="APPNAME">%s</xliff:g>;"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Προστέθηκε στα αγαπημένα"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Εμφάνιση και έλεγχος συσκευών από την οθόνη κλειδώματος;"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Μπορείτε να προσθέσετε στοιχεία ελέγχου για τις εξωτερικές συσκευές σας στην οθόνη κλειδώματος.\n\nΗ εφαρμογή της συσκευής σας μπορεί να σας παρέχει τη δυνατότητα ελέγχου ορισμένων συσκευών χωρίς να ξεκλειδώσετε το τηλέφωνο ή το tablet.\n\nΜπορείτε να κάνετε αλλαγές στις Ρυθμίσεις ανά πάσα στιγμή."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Έλεγχος συσκευών από την οθόνη κλειδώματος;"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Μπορείτε να ελέγχετε ορισμένες συσκευές χωρίς να ξεκλειδώσετε το τηλέφωνο ή το tablet σας. Η εφαρμογή της συσκευής σας καθορίζει ποιες συσκευές μπορούν να ελέγχονται με αυτόν τον τρόπο."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Όχι, ευχαριστώ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ναι"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Το PIN περιέχει γράμματα ή σύμβολα"</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index ffe67fa..f2e0c26 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Enable USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Learn more"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock disabled"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
@@ -871,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
@@ -897,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Show and control devices from the lock screen?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"You can control some devices without unlocking your phone or tablet. Your device app determines which devices can be controlled in this way."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, thanks"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
diff --git a/packages/SystemUI/res/values-en-rCA/strings.xml b/packages/SystemUI/res/values-en-rCA/strings.xml
index da91052..5804699 100644
--- a/packages/SystemUI/res/values-en-rCA/strings.xml
+++ b/packages/SystemUI/res/values-en-rCA/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Enable USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Learn more"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock disabled"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
@@ -871,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <string name="controls_panel_authorization" msgid="4665218066461350247">"<xliff:g id="APPNAME">%s</xliff:g>can choose which controls and content show here."</string>
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> can choose which controls and content show here."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favorited"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index ffe67fa..f2e0c26 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Enable USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Learn more"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock disabled"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
@@ -871,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
@@ -897,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Show and control devices from the lock screen?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"You can control some devices without unlocking your phone or tablet. Your device app determines which devices can be controlled in this way."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, thanks"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index ffe67fa..f2e0c26 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Enable USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Learn more"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock disabled"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
@@ -871,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favourited"</string>
@@ -897,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Show and control devices from the lock screen?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"You can add controls for your external devices to the lock screen.\n\nYour device app may allow you to control some devices without unlocking your phone or tablet.\n\nYou can make changes at any time in Settings."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Control devices from the lock screen?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"You can control some devices without unlocking your phone or tablet. Your device app determines which devices can be controlled in this way."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, thanks"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN contains letters or symbols"</string>
diff --git a/packages/SystemUI/res/values-en-rXC/strings.xml b/packages/SystemUI/res/values-en-rXC/strings.xml
index a577537..0187577 100644
--- a/packages/SystemUI/res/values-en-rXC/strings.xml
+++ b/packages/SystemUI/res/values-en-rXC/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Enable USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Learn more"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock disabled"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"sent an image"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Saving screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Saving screenshot to work profile…"</string>
@@ -871,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control added.}other{# controls added.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removed"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Add <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <string name="controls_panel_authorization" msgid="4665218066461350247">"<xliff:g id="APPNAME">%s</xliff:g>can choose which controls and content show here."</string>
+ <string name="controls_panel_authorization" msgid="7045551688535104194">"<xliff:g id="APPNAME">%s</xliff:g> can choose which controls and content show here."</string>
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remove controls for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favorited"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Favorited, position <xliff:g id="NUMBER">%d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index c00024c..9853c9b 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Habilitar USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Más información"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Captura de pantalla"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desbloqueo ampliado inhabilitado"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"envió una imagen"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Guardando la captura de pantalla..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Guardando cap. de pantalla en perfil de trabajo…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Interruptor"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir la configuración de ampliación"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrastra la esquina para cambiar el tamaño"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir desplazamiento en diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Cambiar tamaño"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Controlador izquierdo"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Controlador derecho"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Controlador inferior"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Configuración de ampliación"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Tamaño de ampliación"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mediano"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Se agregó # control.}many{Se agregaron # controles.}other{Se agregaron # controles.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Quitados"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"¿Quieres agregar <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"¿Quieres quitar los controles para <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Está en favoritos"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"¿Quieres mostrar y controlar dispositivos desde la pantalla de bloqueo?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Puedes agregar controles para dispositivos externos a la pantalla de bloqueo.\n\nLa app de tu dispositivo podría permitirte controlar algunos dispositivos sin desbloquear el teléfono o la tablet.\n\nPuedes realizar cambios en cualquier momento en Configuración."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"¿Quieres controlar dispositivos desde la pantalla de bloqueo?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Puedes controlar algunos dispositivos sin desbloquear el teléfono o la tablet. La app de tu dispositivo determina los que se pueden controlar de esa manera."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, gracias"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Sí"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"El PIN contiene letras o símbolos"</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index 35f55c0..2e5b4d1 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte de la pantalla"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Cambiar"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir ajustes de ampliación"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrastra la esquina para cambiar el tamaño"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir desplazamiento en diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Cambiar tamaño"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Controlador izquierdo"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Controlador derecho"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Controlador inferior"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Ajustes de ampliación"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Tamaño de la lupa"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mediano"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# control añadido.}many{# controles añadidos.}other{# controles añadidos.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Quitado"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"¿Añadir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"¿Quitar los controles de <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Añadido a favoritos"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"¿Mostrar y controlar otros dispositivos en la pantalla de bloqueo?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Puedes añadir controles de tus dispositivos externos a la pantalla de bloqueo.\n\nPuede que la aplicación de tu dispositivo permita que controles algunos dispositivos sin desbloquear tu teléfono o tablet.\n\nPuedes hacer cambios en cualquier momento en Ajustes."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"¿Controlar dispositivos desde la pantalla de bloqueo?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Puedes controlar algunos dispositivos sin desbloquear tu teléfono o tablet. La aplicación de tu dispositivo determina qué dispositivos se pueden controlar de esta forma."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, gracias"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Sí"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"El PIN contiene letras o símbolos"</string>
diff --git a/packages/SystemUI/res/values-et/strings.xml b/packages/SystemUI/res/values-et/strings.xml
index 9b5bc7e..d0f3a46 100644
--- a/packages/SystemUI/res/values-et/strings.xml
+++ b/packages/SystemUI/res/values-et/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Täisekraani suurendamine"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekraanikuva osa suurendamine"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Vaheta"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Ava suurendamisseaded"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Suuruse muutmiseks lohistage nurka"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Luba diagonaalne kerimine"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Muuda suurust"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Vasak käepide"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Parem käepide"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Alumine käepide"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Suurendamisseaded"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Luubi suurus"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Suumi"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Keskmine"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Lisati # juhtnupp.}other{Lisati # juhtnuppu.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Eemaldatud"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Kas lisada <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Kas soovite rakenduse <xliff:g id="APPNAME">%s</xliff:g> juhtelemendid eemaldada?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisatud lemmikuks"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Kas soovite seadmete juhtelemente lukustuskuval kuvada ja kasutada?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Võite lukustuskuvale oma väliste seadmete juhtelemendid lisada.\n\nTeie seadmerakendus võib võimaldada teil teatud seadmeid ilma telefoni või tahvelarvutit avamata hallata.\n\nSaate igal ajal seadetes muudatusi teha."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Kas soovite seadmeid lukustuskuva kaudu hallata?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Võite teatud seadmeid ilma telefoni või tahvelarvutit avamata hallata. Teie seadmerakendus määrab, milliseid seadmeid saab sel viisil hallata."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Tänan, ei"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Jah"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-kood sisaldab tähti või sümboleid"</string>
diff --git a/packages/SystemUI/res/values-eu/strings.xml b/packages/SystemUI/res/values-eu/strings.xml
index 653504a..05c08c8 100644
--- a/packages/SystemUI/res/values-eu/strings.xml
+++ b/packages/SystemUI/res/values-eu/strings.xml
@@ -871,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Kontrolatzeko # aukera gehitu da.}other{Kontrolatzeko # aukera gehitu dira.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Kenduta"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> gehitu nahi duzu?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> kontrolatzeko aukerak kendu nahi dituzu?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Gogokoetan dago"</string>
@@ -897,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Gailuak pantaila blokeatuan ikusi eta kontrolatu nahi dituzu?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Kanpoko gailuak kontrolatzeko aukerak gehi ditzakezu pantaila blokeatuan.\n\nBaliteke telefonoa edo tableta desblokeatu gabe gailu batzuk kontrolatzeko baimena ematea gailuaren aplikazioak.\n\nAldaketak egiteko, joan Ezarpenak atalera."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Gailuak pantaila blokeatuan kontrolatu nahi dituzu?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Gailu batzuk telefonoa edo tableta desblokeatu gabe kontrola ditzakezu. Gailuaren aplikazioak zehaztuko du zein gailu kontrola daitezkeen modu horretan."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ez, eskerrik asko"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Bai"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN kodeak hizkiak edo ikurrak ditu"</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 0474b28..9c9620f 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -86,7 +86,7 @@
<string name="screenshot_share_description" msgid="2861628935812656612">"همرسانی نماگرفت"</string>
<string name="screenshot_scroll_label" msgid="2930198809899329367">"ضبط محتوای بیشتر"</string>
<string name="screenshot_dismiss_description" msgid="4702341245899508786">"رد کردن نماگرفت"</string>
- <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"رد کردن پیام نمایه کاری"</string>
+ <string name="screenshot_dismiss_work_profile" msgid="3101530842987697045">"بستن پیام نمایه کاری"</string>
<string name="screenshot_preview_description" msgid="7606510140714080474">"پیشنمایش نماگرفت"</string>
<string name="screenshot_top_boundary_pct" msgid="2520148599096479332">"مرز بالا <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
<string name="screenshot_bottom_boundary_pct" msgid="3880821519814946478">"مرز پایین <xliff:g id="PERCENT">%1$d</xliff:g> درصد"</string>
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"درشتنمایی تمامصفحه"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"درشتنمایی بخشی از صفحه"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"کلید"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"باز کردن تنظیمات درشتنمایی"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"برای تغییر اندازه، گوشه را بکشید"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"مجاز کردن پیمایش قطری"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"تغییر اندازه"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"دستگیره چپ"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"دستگیره راست"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"دستگیره پایین"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"تنظیمات درشتنمایی"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"اندازه ذرهبین"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"بزرگنمایی"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"متوسط"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنترل اضافه شد.}one{# کنترل اضافه شد.}other{# کنترل اضافه شد.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"حذف شد"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> افزوده شود؟"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"کنترلهای <xliff:g id="APPNAME">%s</xliff:g> برداشته شود؟"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"به موارد دلخواه اضافه شد"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"امکان دیدن و کنترل دستگاهها از صفحه قفل وجود داشته باشد؟"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"میتوانید کنترلهایی برای دستگاههای خارجی به صفحه قفل اضافه کنید.\n\nبرنامه دستگاهتان ممکن است به شما اجازه دهد بعضیاز دستگاهها را بدون باز کردن قفل تلفن یا رایانه لوحیتان کنترل کنید.\n\nهرزمان بخواهید میتوانید در «تنظیمات» تغییراتی اعمال کنید."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"امکان کنترل دستگاهها از صفحه قفل وجود داشته باشد؟"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"میتوانید بعضیاز دستگاهها را بدون باز کردن قفل تلفن یا رایانه لوحیتان کنترل کنید. برنامه دستگاهتان تعیین میکند که کدام دستگاهها را میتوان با این روش کنترل کرد."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"نه متشکرم"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"بله"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"پین شامل حروف یا نماد است"</string>
@@ -1056,7 +1053,7 @@
<string name="clipboard_edit_text_done" msgid="4551887727694022409">"تمام"</string>
<string name="clipboard_overlay_text_copied" msgid="1872624400464891363">"کپی شد"</string>
<string name="clipboard_edit_source" msgid="9156488177277788029">"از <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
- <string name="clipboard_dismiss_description" msgid="3335990369850165486">"رد شدن نوشتار کپیشده"</string>
+ <string name="clipboard_dismiss_description" msgid="3335990369850165486">"بستن نوشتار کپیشده"</string>
<string name="clipboard_edit_text_description" msgid="805254383912962103">"ویرایش نوشتار کپیشده"</string>
<string name="clipboard_edit_image_description" msgid="8904857948976041306">"ویرایش تصویر کپیشده"</string>
<string name="clipboard_send_nearby_description" msgid="4629769637846717650">"ارسال به دستگاهی در اطراف"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 6620ac6..a4fd4d9 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Koko näytön suurennus"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Suurenna osa näytöstä"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Vaihda"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Avaa suurennusasetukset"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Muuta kokoa vetämällä kulmaa"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonaalisen vierittämisen salliminen"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Muuta kokoa"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Vasen kahva"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Oikea kahva"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Alakahva"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Suurennusasetukset"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Suurennuksen koko"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoomaus"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Keskitaso"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# säädin lisätty.}other{# säädintä lisätty.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Poistettu"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Lisätäänkö <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Poistetaanko säätimet: <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Lisätty suosikkeihin"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Haluatko nähdä ja hallita laitteita lukitusnäytöltä?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Voit lisätä lukitusnäytölle ohjaimia ulkoisia laitteita varten.\n\nLaitteen sovellus voi sallia joidenkin laitteiden ohjaamisen avaamatta puhelimen tai tabletin lukitusta.\n\nVoit milloin tahansa tehdä muutoksia asetuksissa."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Haluatko ohjata laitteita lukitusnäytöllä?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Voit ohjata joitakin laitteita avaamatta puhelimen tai tabletin lukitusta. Riippuu laitesovelluksesta, mitä laitteita voi ohjata näin."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ei kiitos"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Kyllä"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-koodi sisältää kirjaimia tai symboleja"</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index cfd5614..8f4c897 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir la totalité de l\'écran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Commutateur"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Ouvrir les paramètres d\'agrandissement"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Faire glisser le coin pour redimensionner"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Autoriser le défilement en diagonale"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionner"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Poignée gauche"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Poignée droite"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Poignée inférieure"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Paramètres d\'agrandissement"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Taille de loupe"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Moyenne"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# de commandes ajoutées.}other{# commandes ajoutées.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Ajouter <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Retirer les commandes pour <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Afficher et contrôler les appareils à partir de l\'écran de verrouillage?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Vous pouvez ajouter des commandes pour vos appareils externes à l\'écran de verrouillage.\n\nL\'application de votre appareil peut vous permettre de contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette.\n\nVous pouvez apporter des modifications à tout moment dans les paramètres."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Contrôler les appareils à partir de l\'écran de verrouillage?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Vous pouvez contrôler certains appareils sans déverrouiller votre téléphone ou votre tablette. L\'application de votre appareil détermine quels appareils peuvent être contrôlés de cette manière."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Non merci"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Oui"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Le NIP contient des lettres ou des symboles"</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 995e218..16140d0 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Agrandir tout l\'écran"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Agrandir une partie de l\'écran"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Changer"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Ouvrir les paramètres d\'agrandissement"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Faire glisser le coin pour redimensionner"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Autoriser le défilement diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionner"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Poignée gauche"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Poignée droite"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Poignée inférieure"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Paramètres d\'agrandissement"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Taille de l\'agrandissement"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Moyen"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# commande ajoutée.}one{# commande ajoutée.}many{# commandes ajoutées.}other{# commandes ajoutées.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Supprimé"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Ajouter <xliff:g id="APPNAME">%s</xliff:g> ?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Supprimer les commandes pour <xliff:g id="APPNAME">%s</xliff:g> ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Ajouté aux favoris"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Afficher et contrôler les appareils depuis l\'écran de verrouillage ?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Vous pouvez ajouter des commandes pour vos appareils externes sur l\'écran de verrouillage.\n\nL\'appli de votre appareil peut vous autoriser à contrôler certains appareils sans déverrouiller votre téléphone ou tablette.\n\nVous pouvez apporter des modifications à tout moment dans les paramètres."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Contrôler des appareils depuis l\'écran de verrouillage ?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Vous pouvez contrôler certains appareils sans déverrouiller votre téléphone ou tablette. L\'appli de votre appareil détermine les appareils qui peuvent être contrôlés de cette manière."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Non, merci"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Oui"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Le code contient des lettres ou des symboles"</string>
diff --git a/packages/SystemUI/res/values-gl/strings.xml b/packages/SystemUI/res/values-gl/strings.xml
index 74d9f9a..815029b 100644
--- a/packages/SystemUI/res/values-gl/strings.xml
+++ b/packages/SystemUI/res/values-gl/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar pantalla completa"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Amplía parte da pantalla"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Cambiar"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir configuración da ampliación"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arrastrar a esquina para cambiar o tamaño"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir desprazamento diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Cambiar tamaño"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Controlador esquerdo"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Controlador dereito"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Controlador inferior"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Configuración da ampliación"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Tamaño da lupa"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mediano"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Engadiuse # control.}other{Engadíronse # controis.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Quitouse"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Queres engadir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Queres quitar os controis de <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Está entre os controis favoritos"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Queres que se mostren dispositivos na pantalla de bloqueo e poder controlalos desde ela?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Podes engadir á pantalla de bloqueo controis para os dispositivos externos.\n\nÉ posible que a aplicación do dispositivo che permita controlar algúns dispositivos sen desbloquear o teléfono ou a tableta.\n\nPodes realizar cambios cando queiras en Configuración."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Queres controlar dispositivos desde a pantalla de bloqueo?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Podes controlar algúns dispositivos sen desbloquear o teléfono ou a tableta. A aplicación do dispositivo determina os dispositivos que se poden controlar deste xeito."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Non, grazas"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Si"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contén letras ou símbolos"</string>
diff --git a/packages/SystemUI/res/values-gu/strings.xml b/packages/SystemUI/res/values-gu/strings.xml
index 50aadc7..3d32c7f 100644
--- a/packages/SystemUI/res/values-gu/strings.xml
+++ b/packages/SystemUI/res/values-gu/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"પૂર્ણ સ્ક્રીનને મોટી કરો"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"સ્ક્રીનનો કોઈ ભાગ મોટો કરો"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"સ્વિચ"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"મોટા કરવાના સેટિંગ ખોલો"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"કદ બદલવા માટે ખૂણો ખેંચો"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ડાયગોનલ સ્ક્રોલિંગને મંજૂરી આપો"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"કદ બદલો"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"ડાબું હૅન્ડલ"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"જમણું હૅન્ડલ"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"નીચેનું હૅન્ડલ"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"મોટા કરવાના સેટિંગ"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"મેગ્નિફાયરનું કદ"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"નાનું-મોટું કરો"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"મધ્યમ"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# નિયંત્રણ ઉમેર્યું.}one{# નિયંત્રણ ઉમેર્યું.}other{# નિયંત્રણ ઉમેર્યા.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"કાઢી નાખ્યું"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ઉમેરીએ?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> માટે નિયંત્રણો કાઢી નાખીએ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"મનપસંદમાં ઉમેર્યું"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"લૉક સ્ક્રીનમાંથી ડિવાઇસ બતાવીએ અને નિયંત્રિત કરીએ?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"તમે તમારા બાહ્ય ડિવાઇસ માટેના નિયંત્રણો લૉક સ્ક્રીન પર ઉમેરી શકો છો.\n\nતમારી ડિવાઇસ ઍપ કદાચ તમને તમારો ફોન કે ટૅબ્લેટ અનલૉક કર્યા વિના અમુક ડિવાઇસ નિયંત્રિત કરવાની મંજૂરી આપી શકે.\n\nતમે ગમે ત્યારે સેટિંગમાં જઈને ફેરફાર કરી શકો છો."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"લૉક સ્ક્રીનમાંથી ડિવાઇસ નિયંત્રિત કરીએ?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"તમે તમારા ફોન કે ટૅબ્લેટને અનલૉક કર્યા વિના અમુક ડિવાઇસ નિયંત્રિત કરી શકો છો. તમારી ડિવાઇસ ઍપ નક્કી કરે છે કે આ રીતે કયા ડિવાઇસને નિયંત્રિત કરવા."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"ના, આભાર"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"હા"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"પિનમાં અક્ષરો અથવા પ્રતીકોનો સમાવેશ થાય છે"</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 046f554..5a88b5d 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फ़ुल स्क्रीन को ज़ूम करें"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीन के किसी हिस्से को ज़ूम करें"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"स्विच"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ज़ूम करने की सुविधा वाली सेटिंग खोलें"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"साइज़ बदलने के लिए, कोने को खींचें और छोड़ें"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"तिरछी दिशा में स्क्रोल करने की अनुमति दें"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"साइज़ बदलें"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"बायां हैंडल"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"दायां हैंडल"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"नीचे का हैंडल"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"ज़ूम करने की सुविधा वाली सेटिंग"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"ज़ूम करने की सुविधा का साइज़"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"ज़ूम करें"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"मध्यम"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कंट्रोल जोड़ा गया.}one{# कंट्रोल जोड़ा गया.}other{# कंट्रोल जोड़े गए.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"हटाया गया"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> को जोड़ना है?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> के लिए कंट्रोल हटाने हैं?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"पसंदीदा बनाया गया"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"क्या डिवाइसों को लॉक स्क्रीन पर देखना है और उन्हें वहीं से कंट्रोल करना है?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"लॉक स्क्रीन पर अपने बाहरी डिवाइसों के लिए कंट्रोल जोड़े जा सकते हैं.\n\nअपने डिवाइस के ऐप्लिकेशन से कुछ डिवाइसों को कंट्रोल किया जा सकता है. इसके लिए, फ़ोन या टैबलेट को अनलॉक नहीं करना पड़ता.\n\nकिसी भी समय सेटिंग में जाकर बदलाव किए जा सकते हैं."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"क्या लॉक स्क्रीन से डिवाइसों को कंट्रोल करना है?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"फ़ोन या टैबलेट को अनलॉक किए बिना, कुछ डिवाइसों को कंट्रोल किया जा सकता है. आपके डिवाइस के ऐप्लिकेशन से यह तय किया जाता है कि किन डिवाइसों को इस तरह कंट्रोल किया जा सकता है."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"नहीं, रहने दें"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"हां"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"पिन में अक्षर या चिह्न शामिल होते हैं"</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 6d8b24b..c89a590 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Omogući USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Saznajte više"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Snimka zaslona"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Produljivanje otključavanja onemogućeno"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"šalje sliku"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Spremanje snimke zaslona..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Spremanje snimke zaslona na poslovni profil…"</string>
@@ -871,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodana je # kontrola.}one{Dodana je # kontrola.}few{Dodane su # kontrole.}other{Dodano je # kontrola.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Uklonjeno"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite li dodati aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Ukloniti kontrole za aplikaciju <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano u favorite"</string>
@@ -897,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Prikazati uređaje i omogućiti upravljanje njima na zaključanom zaslonu?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na zaključan zaslon možete dodati kontrole za svoje vanjske uređaje.\n\nAplikacija vašeg uređaja može vam dopustiti upravljanje nekim uređajima bez otključavanja telefona ili tableta.\n\nPromjene uvijek možete unijeti u Postavkama."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Upravljati uređajima na zaključanom zaslonu?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Nekim uređajima možete upravljati bez otključavanja telefona ili tableta. Aplikacija vašeg uređaja odlučuje kojim se uređajima može upravljati na taj način."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, hvala"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Da"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN sadrži slova ili simbole"</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index dcb7d72..96931df 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -871,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# vezérlő hozzáadva.}other{# vezérlő hozzáadva.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Eltávolítva"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Hozzáadja a(z) <xliff:g id="APPNAME">%s</xliff:g> alkalmazást?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Eltávolítja a(z) <xliff:g id="APPNAME">%s</xliff:g> vezérlőit?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Hozzáadva a kedvencekhez"</string>
@@ -897,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Szeretne megtekinteni és vezérelni eszközöket a lezárási képernyőn?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Hozzáadhatja külső eszközök vezérlőit a lezárási képernyőhöz.\n\nAz eszközön lévő alkalmazás segítségével telefonja vagy táblagépe feloldása nélkül is vezérelhet néhány eszközt.\n\nA Beállításokban bármikor módosíthatja ezt a funkciót."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Szeretne eszközöket vezérelni a lezárási képernyőn?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Telefonja vagy táblagépe feloldása nélkül is vezérelhet néhány eszközt. Az eszközalkalmazás határozza meg, hogy mely eszközök vezérelhetők ilyen módon."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Most nem"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Igen"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"A PIN-kód betűket vagy szimbólumokat tartalmaz"</string>
diff --git a/packages/SystemUI/res/values-hy/strings.xml b/packages/SystemUI/res/values-hy/strings.xml
index 1b21230..b852836 100644
--- a/packages/SystemUI/res/values-hy/strings.xml
+++ b/packages/SystemUI/res/values-hy/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Խոշորացնել ամբողջ էկրանը"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Խոշորացնել էկրանի որոշակի հատվածը"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Փոխել"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Բացել խոշորացման կարգավորումները"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Քաշեք անկյունը՝ չափը փոխելու համար"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Թույլատրել անկյունագծով ոլորումը"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Փոխել չափը"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Ձախ բռնակ"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Աջ բռնակ"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Ներքևի բռնակ"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Խոշորացման կարգավորումներ"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Խոշորացույցի չափսը"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Մասշտաբ"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Միջին"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Ավելացվեց կառավարման # տարր։}one{Ավելացվեց կառավարման # տարր։}other{Ավելացվեց կառավարման # տարր։}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Հեռացված է"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Ավելացնե՞լ <xliff:g id="APPNAME">%s</xliff:g> հավելվածը"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Հեռացնե՞լ <xliff:g id="APPNAME">%s</xliff:g> հավելվածի համար կարգավորումները։"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Ավելացված է ընտրանիում"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Ցույց տա՞լ և կառավարել սարքերը կողպէկրանից"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Դուք կարող եք կարգավորումներ ավելացնել ձեր արտաքին սարքերի համար կողպէկրանին։\n\nՁեր սարքի հավելվածը կարող է ձեզ թույլ տալ որոշ սարքեր կառավարել առանց ապակողպելու հեռախոսը կամ պլանշետը։\n\nՑանկացած ժամանակ փոփոխություններ կատարեք Կարգավորումներում։"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Կառավարե՞լ սարքերը կողպէկրանից"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Դուք կարող եք կառավարել որոշ սարքեր առանց ապակողպելու ձեր հեռախոսը կամ պլանշետը։ Ձեր սարքի հավելվածը որոշում է, թե որ սարքերը կարելի է կառավարել այս եղանակով։"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ոչ, շնորհակալություն"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Այո"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN կոդը տառեր և նշաններ է պարունակում"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index 055479e..e293b9b 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Memperbesar tampilan layar penuh"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Perbesar sebagian layar"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Alihkan"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Buka setelan pembesaran"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Tarik pojok persegi untuk mengubah ukuran"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Izinkan scrolling diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ubah ukuran"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Tuas kiri"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Tuas kanan"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Tuas bawah"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Setelan pembesaran"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Ukuran kaca pembesar"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Sedang"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol ditambahkan.}other{# kontrol ditambahkan.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Dihapus"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Tambahkan <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Hapus kontrol untuk <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Difavoritkan"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Tampilkan dan kontrol perangkat dari layar kunci?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Anda dapat menambahkan kontrol untuk perangkat eksternal ke layar kunci.\n\nAplikasi perangkat Anda mungkin mengizinkan Anda mengontrol beberapa perangkat tanpa membuka kunci ponsel atau tablet.\n\nAnda dapat melakukan perubahan kapan saja di Setelan."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Kontrol perangkat dari layar kunci?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Anda dapat mengontrol beberapa perangkat tanpa membuka kunci ponsel atau tablet. Aplikasi perangkat Anda menentukan perangkat yang dapat dikontrol dengan cara ini."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Lain kali"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ya"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN berisi huruf atau simbol"</string>
diff --git a/packages/SystemUI/res/values-is/strings.xml b/packages/SystemUI/res/values-is/strings.xml
index 553e0e4..1e6b6ed 100644
--- a/packages/SystemUI/res/values-is/strings.xml
+++ b/packages/SystemUI/res/values-is/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Stækka allan skjáinn"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Stækka hluta skjásins"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Rofi"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Opna stillingar stækkunar"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Dragðu horn til að breyta stærð"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Leyfa skáflettingu"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Breyta stærð"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Vinstra handfang"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Hægra handfang"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Handfang neðst"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Stillingar stækkunar"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Stærð stækkunarglers"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Stækka/minnka"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Miðlungs"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# stýringu bætt við.}one{# stýringu bætt við.}other{# stýringum bætt við.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Fjarlægt"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Viltu bæta <xliff:g id="APPNAME">%s</xliff:g> við?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Fjarlægja stýringar fyrir <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Eftirlæti"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Sjá og stjórna tækjum á lásskjánum?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Þú getur bætt við stýringum fyrir ytri tæki á lásskjáinn.\n\nForrit tækisins kann að leyfa þér að stjórna sumum tækjum án þess að taka símann eða spjaldtölvuna úr lás.\n\nÞú getur gert breytingar hvenær sem er í stillingunum."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Stjórna tækjum á lásskjá?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Þú getur stjórnað sumum tækjum án þess að taka símann eða spjaldtölvuna úr lás. Tækisforritið ákvarðar hvaða tækjum er hægt að stjórna á þennan hátt."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nei, takk"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Já"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN inniheldur bókstafi eða tákn"</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index f3876ce..a3da707 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Attiva USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Scopri di più"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Screenshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Funzionalità Extend Unlock disattivata"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"è stata inviata un\'immagine"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Salvataggio screenshot…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Salvataggio screenshot nel profilo di lavoro…"</string>
@@ -871,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controllo aggiunto.}many{# controlli aggiunti.}other{# controlli aggiunti.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Rimosso"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Vuoi aggiungere <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Vuoi rimuovere i controlli per l\'app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Aggiunto ai preferiti"</string>
@@ -897,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Vuoi visualizzare e controllare i dispositivi dalla schermata di blocco?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Puoi aggiungere impostazioni alla schermata di blocco per i tuoi dispositivi esterni.\n\nL\'app del tuo dispositivo potrebbe consentirti di controllare alcuni dispositivi senza dover sbloccare il tuo telefono o tablet.\n\nPuoi apportare modifiche in qualsiasi momento in Impostazioni."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Vuoi controllare i dispositivi dalla schermata di blocco?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Puoi controllare alcuni dispositivi senza sbloccare il telefono o il tablet. L\'app del dispositivo determina quali dispositivi possono essere controllati in questo modo."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"No, grazie"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Sì"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Il PIN contiene lettere o simboli"</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 4dcafa1..3a2e040 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -871,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{נוסף אמצעי בקרה אחד (#).}one{נוספו # אמצעי בקרה.}two{נוספו # אמצעי בקרה.}other{נוספו # אמצעי בקרה.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"הוסר"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"להוסיף את <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"להסיר את אמצעי הבקרה של <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"סומן כמועדף"</string>
@@ -897,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"להציג מכשירים ולאפשר שליטה בהם במסך הנעילה?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ניתן להוסיף למסך הנעילה אמצעי בקרה למכשירים החיצוניים.\n\nיכול להיות שהאפליקציה של המכשיר תאפשר לך לשלוט בחלק מהמכשירים בלי לבטל את הנעילה של הטלפון או הטאבלט.\n\nאפשר לבצע שינויים בכל שלב בהגדרות."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"לאפשר שליטה במכשירים במסך הנעילה?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"אפשר לשלוט בחלק מהמכשירים בלי לבטל את הנעילה של הטלפון או הטאבלט. המכשירים שניתן לשלוט בהם באופן הזה נקבעים באפליקציה לניהול מכשיר המשני."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"לא תודה"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"כן"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"קוד האימות מכיל אותיות או סמלים"</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index 0b7b469..550a19e 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB を有効にする"</string>
<string name="learn_more" msgid="4690632085667273811">"詳細"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"スクリーンショット"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock は無効です"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"画像を送信しました"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"スクリーンショットを保存しています..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"スクリーンショットを仕事用プロファイルに保存中…"</string>
@@ -871,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# 件のコントロールを追加しました。}other{# 件のコントロールを追加しました。}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"削除済み"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> を追加しますか?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> のコントロールを削除しますか?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"お気に入りに追加済み"</string>
@@ -897,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ロック画面にデバイスを表示して操作しますか?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ロック画面に外部デバイスのコントロールを追加できます。\n\nスマートフォンやタブレットのロックを解除しなくても、デバイスアプリによって一部のデバイスを操作できる可能性があります。\n\n設定でいつでも変更できます。"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ロック画面でデバイスを操作しますか?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"スマートフォンやタブレットのロックを解除しなくても、一部のデバイスを操作できます。この方法でどのデバイスを操作できるかは、デバイスアプリが判断します。"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"いいえ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"はい"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN に英字や記号を含める"</string>
diff --git a/packages/SystemUI/res/values-ka/strings.xml b/packages/SystemUI/res/values-ka/strings.xml
index 2bdf163..8e95488 100644
--- a/packages/SystemUI/res/values-ka/strings.xml
+++ b/packages/SystemUI/res/values-ka/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB-ის ჩართვა"</string>
<string name="learn_more" msgid="4690632085667273811">"შეიტყვეთ მეტი"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"ეკრანის ანაბეჭდი"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"გაფართოებული განბლოკვა გაითიშა"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"გაიგზავნა სურათი"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"ეკრანის სურათის შენახვა…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"მიმდინარეობს ეკრანის ანაბეჭდის შენახვა სამუშაო პროფილში…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"გაადიდეთ სრულ ეკრანზე"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ეკრანის ნაწილის გადიდება"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"გადართვა"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"გახსენით გადიდების პარამეტრები"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ჩავლებით გადაიტანეთ კუთხე ზომის შესაცვლელად"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"დიაგონალური გადახვევის დაშვება"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ზომის შეცვლა"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"მარცხენა სახელური"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"მარჯვენა სახელური"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"ქვედა სახელური"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"გადიდების პარამეტრები"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"გადიდების ზომა"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"გადიდება"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"საშუალო"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{დაემატა მართვის # საშუალება.}other{დაემატა მართვის # საშუალება.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ამოიშალა"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"გსურთ <xliff:g id="APPNAME">%s</xliff:g>-ის დამატება?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"ამოიშალოს <xliff:g id="APPNAME">%s</xliff:g>-ის მართვის საშუალებები?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"რჩეულებშია"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"გსურთ მოწყობილობების ჩვენება და მართვა ჩაკეტილი ეკრანიდან?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"შეგიძლიათ დაამატოთ მართვის საშუალებები გარე მოწყობილობებისთვის, ჩაკეტილ ეკრანზე.\n\nთქვენი მოწყობილობის აპმა შეიძლება მოგცეთ საშუალება, მართოთ ზოგიერთი მოწყობილობა თქვენი ტელეფონის ან ტაბლეტის განბლოკვის გარეშე.\n\nცვლილებების შეტანა ნებისმიერ დროს შეგიძლიათ პარამეტრებიდან."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"გსურთ მოწყობილობების მართვა ჩაკეტილი ეკრანიდან?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"შეგიძლიათ ზოგიერთი მოწყობილობის მართვა ტელეფონის ან ტაბლეტის განბლოკვის გარეშე. თქვენი მოწყობილობის აპი განსაზღვრავს, რომელი მოწყობილობები იმართება ამგვარად."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"არა, გმადლობთ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"დიახ"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-კოდი შეიცავს ასოებს ან სიმბოლოებს"</string>
diff --git a/packages/SystemUI/res/values-kk/strings.xml b/packages/SystemUI/res/values-kk/strings.xml
index 2a2b307..08b4879 100644
--- a/packages/SystemUI/res/values-kk/strings.xml
+++ b/packages/SystemUI/res/values-kk/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толық экранды ұлғайту"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экранның бөлігін ұлғайту"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Ауысу"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Ұлғайту параметрлерін ашу"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Өлшемін өзгерту үшін бұрышынан сүйреңіз."</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Диагональ бойынша айналдыруға рұқсат беру"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Өлшемін өзгерту"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Сол жақ маркер"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Оң жақ маркер"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Төменгі маркер"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Ұлғайту параметрлері"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Ұлғайтқыш көлемі"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Масштабтау"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Орташа"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# басқару элементі қосылды.}other{# басқару элементі қосылды.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Өшірілді"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> қолданбасын қосу керек пе?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> қолданбасының басқару элементтері жойылсын ба?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Таңдаулыларға қосылды"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Құрылғыларды құлып экранынан көрсетуге және басқаруға рұқсат берілсін бе?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Сыртқы құрылғылардың басқару элементтерін құлып экранына қоса аласыз.\n\nҚұрылғы қолданбасы кейбір құрылғыларды телефонның немесе планшеттің құлпын ашпастан басқаруға мүмкіндік береді.\n\n\"Параметрлер\" бөлімінде кез келген уақытта өзгерістер енгізуге болады."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Құрылғылар құлып экранынан басқарылсын ба?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Кейбір құрылғыларды телефонның немесе планшеттің құлпын ашпастан басқара аласыз. Құрылғы қолданбасы осылай басқаруға болатын құрылғыларды анықтайды."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Жоқ, рақмет"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Иә"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN коды әріптерден не таңбалардан құралады."</string>
diff --git a/packages/SystemUI/res/values-km/strings.xml b/packages/SystemUI/res/values-km/strings.xml
index b396538..9cdd5c0 100644
--- a/packages/SystemUI/res/values-km/strings.xml
+++ b/packages/SystemUI/res/values-km/strings.xml
@@ -871,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{បានបញ្ចូលការគ្រប់គ្រង #។}other{បានបញ្ចូលការគ្រប់គ្រង #។}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"បានដកចេញ"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"បញ្ចូល <xliff:g id="APPNAME">%s</xliff:g> ឬ?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"ដកការគ្រប់គ្រងសម្រាប់ <xliff:g id="APPNAME">%s</xliff:g> ចេញឬ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"បានដាក់ជាសំណព្វ"</string>
@@ -897,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"បង្ហាញ និងគ្រប់គ្រងឧបករណ៍ពីអេក្រង់ចាក់សោឬ?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"អ្នកអាចបញ្ចូលការគ្រប់គ្រងសម្រាប់ឧបករណ៍ខាងក្រៅរបស់អ្នកទៅក្នុងអេក្រង់ចាក់សោបាន។\n\nកម្មវិធីឧបករណ៍របស់អ្នកអាចអនុញ្ញាតឱ្យអ្នកគ្រប់គ្រងឧបករណ៍មួយចំនួន ដោយមិនចាំបាច់ដោះសោទូរសព្ទ ឬថេប្លេតរបស់អ្នក។\n\nអ្នកអាចធ្វើការផ្លាស់ប្ដូរបានគ្រប់ពេលនៅក្នុងការកំណត់។"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"គ្រប់គ្រងឧបករណ៍ពីអេក្រង់ចាក់សោឬ?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"អ្នកអាចគ្រប់គ្រងឧបករណ៍មួយចំនួន ដោយមិនចាំបាច់ដោះសោទូរសព្ទ ឬថេប្លេតរបស់អ្នក។ កម្មវិធីឧបករណ៍របស់អ្នកកំណត់ឧបករណ៍ដែលអាចត្រូវបានគ្រប់គ្រងតាមវិធីនេះ។"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"ទេ អរគុណ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"បាទ/ចាស"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"កូដ PIN មានអក្សរ ឬនិមិត្តសញ្ញា"</string>
diff --git a/packages/SystemUI/res/values-kn/strings.xml b/packages/SystemUI/res/values-kn/strings.xml
index cfe6268..fcdf34d 100644
--- a/packages/SystemUI/res/values-kn/strings.xml
+++ b/packages/SystemUI/res/values-kn/strings.xml
@@ -871,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ನಿಯಂತ್ರಣವನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}one{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}other{# ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಲಾಗಿದೆ.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ತೆಗೆದುಹಾಕಲಾಗಿದೆ"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ಅನ್ನು ಸೇರಿಸಬೇಕೆ?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> ಗಾಗಿ ನಿಯಂತ್ರಣಗಳನ್ನು ತೆಗೆದುಹಾಕಬೇಕೆ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ಮೆಚ್ಚಲಾಗಿರುವುದು"</string>
@@ -897,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ನಿಂದ ಸಾಧನಗಳನ್ನು ತೋರಿಸಬೇಕೇ ಹಾಗೂ ನಿಯಂತ್ರಿಸಬೇಕೇ?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ನಲ್ಲಿ ನಿಮ್ಮ ಬಾಹ್ಯ ಸಾಧನಗಳಿಗಾಗಿ ನೀವು ನಿಯಂತ್ರಣಗಳನ್ನು ಸೇರಿಸಬಹುದು.\n\nನಿಮ್ಮ ಫೋನ್ ಅಥವಾ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡದೆಯೇ ನಿಮ್ಮ ಕೆಲವು ಸಾಧನಗಳನ್ನು ನಿಯಂತ್ರಿಸಲು ನಿಮ್ಮ ಸಾಧನ ಆ್ಯಪ್ ಅನುಮತಿಸಬಹುದು.\n\nಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ನೀವು ಯಾವಾಗ ಬೇಕಾದರೂ ಬದಲಾವಣೆಗಳನ್ನು ಮಾಡಬಹುದು."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ಲಾಕ್ ಸ್ಕ್ರೀನ್ನಿಂದ ಸಾಧನಗಳನ್ನು ನಿಯಂತ್ರಿಸಬೇಕೇ?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"ನಿಮ್ಮ ಫೋನ್ ಅಥವಾ ಟ್ಯಾಬ್ಲೆಟ್ ಅನ್ನು ಅನ್ಲಾಕ್ ಮಾಡದೆಯೇ ನಿಮ್ಮ ಕೆಲವು ಸಾಧನಗಳನ್ನು ನೀವು ಕಂಟ್ರೋಲ್ ಮಾಡಬಹುದು. ಈ ವಿಧಾನದ ಮೂಲಕ ಯಾವ ಸಾಧನಗಳನ್ನು ಕಂಟ್ರೋಲ್ ಮಾಡಬಹುದು ಎಂಬುದನ್ನು ನಿಮ್ಮ ಸಾಧನದ ಆ್ಯಪ್ ನಿರ್ಧರಿಸುತ್ತದೆ."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"ಬೇಡ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"ಹೌದು"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ಪಿನ್ ಅಕ್ಷರಗಳು ಅಥವಾ ಸಂಕೇತಗಳನ್ನು ಒಳಗೊಂಡಿದೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index f131402..e339524 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"전체 화면 확대"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"화면 일부 확대"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"전환"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"확대 설정 열기"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"모서리를 드래그하여 크기 조절"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"대각선 스크롤 허용"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"크기 조절"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"왼쪽 핸들"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"오른쪽 핸들"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"하단 핸들"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"확대 설정"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"돋보기 크기"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"확대/축소"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"보통"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{설정이 #개 추가되었습니다.}other{설정이 #개 추가되었습니다.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"삭제됨"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>을(를) 추가할까요?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> 컨트롤을 삭제할까요?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"즐겨찾기에 추가됨"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"잠금 화면에서 기기를 표시하고 제어하시겠습니까?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"외부 기기에 대한 제어 권한을 잠금 화면에 추가할 수 있습니다.\n\n기기 앱을 사용하여 휴대전화나 태블릿의 잠금을 해제하지 않고 해당 기기를 제어할 수도 있습니다.\n\n언제든지 설정에서 옵션을 변경할 수 있습니다."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"잠금 화면에서 기기를 제어하시겠습니까?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"일부 기기의 경우 휴대전화나 태블릿을 잠금 해제하지 않고 해당 기기를 제어할 수 있습니다. 기기 앱에 어떤 기기를 이러한 방식으로 제어할 수 있는지 표시됩니다."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"아니요"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"예"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN에 문자나 기호가 포함됨"</string>
diff --git a/packages/SystemUI/res/values-ky/strings.xml b/packages/SystemUI/res/values-ky/strings.xml
index a53542b..77fddef 100644
--- a/packages/SystemUI/res/values-ky/strings.xml
+++ b/packages/SystemUI/res/values-ky/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Толук экранда ачуу"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Экрандын бир бөлүгүн чоңойтуу"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Которулуу"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Чоңойтуу параметрлерин ачуу"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Өлчөмүн өзгөртүү үчүн бурчун сүйрөңүз"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Диагональ боюнча сыдырууга уруксат берүү"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Өлчөмүн өзгөртүү"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Сол маркер"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Оң маркер"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Ылдыйкы маркер"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Чоңойтуу параметрлери"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Чоңойткучтун өлчөмү"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Чоңойтуп/кичирейтүү"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Орто"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# көзөмөл кошулду.}other{# көзөмөл кошулду.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Өчүрүлдү"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> кошулсунбу?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> башкаруу элементтери өчүрүлсүнбү?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Сүйүктүүлөргө кошулду"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Түзмөктөрдү кулпуланган экрандан көрүп, көзөмөлдөйсүзбү?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Тышкы түзмөктөрүңүздү көзөмөлдөө каражаттарын кулпу экранына кошо аласыз.\n\nТүзмөгүңүздүн колдонмосу айрым түзмөктөрдү телефонуңуздун же планшетиңиздин кулпусун ачпастан көзөмөлдөөгө уруксат бериши мүмкүн.\n\nКаалаган убакта Жөндөөлөрдөн өзгөртүүлөрдү жасай аласыз."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Түзмөктөрдү кулпуланган экрандан көзөмөлдөйсүзбү?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Айрым түзмөктөрдү телефонуңуздун же планшетиңиздин кулпусун ачпастан көзөмөлдөй аласыз. Кайсы түзмөктөрдү ушул жол менен көзөмөлдөөгө болорун түзмөгүңүздүн колдонмосу аныктайт."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Жок, рахмат"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ооба"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN код тамгалардан же символдордон турат"</string>
diff --git a/packages/SystemUI/res/values-lo/strings.xml b/packages/SystemUI/res/values-lo/strings.xml
index 205d66d..541b418 100644
--- a/packages/SystemUI/res/values-lo/strings.xml
+++ b/packages/SystemUI/res/values-lo/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ຂະຫຍາຍເຕັມຈໍ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ຂະຫຍາຍບາງສ່ວນຂອງໜ້າຈໍ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ສະຫຼັບ"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ເປີດການຕັ້ງຄ່າການຂະຫຍາຍ"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ລາກຢູ່ມຸມເພື່ອປັບຂະໜາດ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ອະນຸຍາດໃຫ້ເລື່ອນທາງຂວາງ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ປ່ຽນຂະໜາດ"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"ດ້າມຈັບຊ້າຍມື"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"ດ້າມຈັບຂວາມື"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"ດ້າມຈັບທາງລຸ່ມ"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"ການຕັ້ງຄ່າການຂະຫຍາຍ"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"ຂະໜາດການຂະຫຍາຍ"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"ຊູມ"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"ປານກາງ"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}other{ເພີ່ມ # ການຄວບຄຸມແລ້ວ.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ລຶບອອກແລ້ວ"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"ເພີ່ມ <xliff:g id="APPNAME">%s</xliff:g> ບໍ?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"ລຶບການຄວບຄຸມສຳລັບ <xliff:g id="APPNAME">%s</xliff:g> ອອກບໍ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ເພີ່ມລາຍການທີ່ມັກແລ້ວ"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ສະແດງ ແລະ ຄວບຄຸມອຸປະກອນຈາກໜ້າຈໍລັອກບໍ?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ທ່ານສາມາດເພີ່ມການຄວບຄຸມສຳລັບອຸປະກອນພາຍນອກຂອງທ່ານໄປໃສ່ໜ້າຈໍລັອກໄດ້.\n\nແອັບອຸປະກອນຂອງທ່ານອາດອະນຸຍາດໃຫ້ທ່ານຄວບຄຸມອຸປະກອນບາງຢ່າງໄດ້ໂດຍບໍ່ຕ້ອງປົດລັອກໂທລະສັບ ຫຼື ແທັບເລັດຂອງທ່ານ.\n\nທ່ານສາມາດປ່ຽນແປງຕອນໃດກໍໄດ້ໃນການຕັ້ງຄ່າ."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ຄວບຄຸມອຸປະກອນຈາກໜ້າຈໍລັອກບໍ?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"ທ່ານສາມາດຄວບຄຸມອຸປະກອນບາງຢ່າງໄດ້ໂດຍບໍ່ຕ້ອງປົດລັອກໂທລະສັບ ຫຼື ແທັບເລັດຂອງທ່ານ. ແອັບຈັດການອຸປະກອນຂອງທ່ານຈະກຳນົດວ່າອຸປະກອນໃດສາມາດຖືກຄວບຄຸມດ້ວຍວິທີນີ້ໄດ້."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"ບໍ່, ຂອບໃຈ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"ແມ່ນແລ້ວ"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ປະກອບມີຕົວອັກສອນ ຫຼື ສັນຍາລັກ"</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index ca52f06..38fe1c7 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Viso ekrano didinimas"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Didinti ekrano dalį"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Perjungti"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Atidaryti didinimo nustatymus"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Norėdami keisti dydį, vilkite kampą"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Slinkimo įstrižai leidimas"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Pakeisti dydį"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Rankenėlė kairėje"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Rankenėlė dešinėje"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Rankenėlė apačioje"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Didinimo nustatymai"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Didinimo dydis"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Mastelio keitimas"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Vidutinis"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Pridėtas # valdiklis.}one{Pridėtas # valdiklis.}few{Pridėti # valdikliai.}many{Pridėta # valdiklio.}other{Pridėta # valdiklių.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Pašalinta"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Pridėti „<xliff:g id="APPNAME">%s</xliff:g>“?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Pašalinti „<xliff:g id="APPNAME">%s</xliff:g>“ valdiklius?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Įtraukta į mėgstamiausius"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Rodyti ir valdyti įrenginius užrakinimo ekrane?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Galite pridėti išorinių įrenginių valdiklių užrakinimo ekrane.\n\nĮrenginio programoje gali būti leidžiama valdyti tam tikrus įrenginius neatrakinus telefono ar planšetinio kompiuterio.\n\nGalite bet kada pakeisti „Nustatymų“ skiltyje."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Valdyti įrenginius užrakinimo ekrane?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Galite valdyti kai kuriuos išorinius įrenginius neatrakinę telefono ar planšetinio kompiuterio. Įrenginio programoje nustatoma, kuriuos įrenginius galima valdyti tokiu būdu."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, ačiū"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Taip"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN kodą sudaro raidės arba simboliai"</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 34628f6..6b03a03 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Palielināt visu ekrānu"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Palielināt ekrāna daļu"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Pārslēgt"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Atvērt palielinājuma iestatījumus"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Velciet stūri, lai mainītu izmērus"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Atļaut ritināšanu pa diagonāli"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Mainīt lielumu"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Kreisais turis"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Labais turis"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Apakšdaļas turis"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Palielinājuma iestatījumi"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Lupas lielums"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Tālummainīt"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Vidējs"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Pievienota # vadīkla.}zero{Pievienotas # vadīklas.}one{Pievienota # vadīkla.}other{Pievienotas # vadīklas.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Noņemta"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Vai pievienot lietotni <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Vai noņemt vadīklas lietotnei <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Pievienota izlasei"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Vai skatīt un kontrolēt ierīces no bloķēšanas ekrāna?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Varat pievienot bloķēšanas ekrānam vadīklas, ar kurām kontrolēt savas ārējās ierīces.\n\nJūsu ierīces lietotne var ļaut jums kontrolēt dažas ierīces, neatbloķējot tālruni vai planšetdatoru.\n\nVarat jebkurā laikā veikt izmaiņas iestatījumos."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Vai kontrolēt ierīces no bloķēšanas ekrāna?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Varat kontrolēt noteiktas ierīces, neatbloķējot tālruni vai planšetdatoru. Jūsu ierīces lietotne nosaka, kuras ierīces varat šādi kontrolēt."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nē, paldies"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Jā"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ietver burtus vai simbolus."</string>
diff --git a/packages/SystemUI/res/values-mk/strings.xml b/packages/SystemUI/res/values-mk/strings.xml
index 175ef74..940b6191 100644
--- a/packages/SystemUI/res/values-mk/strings.xml
+++ b/packages/SystemUI/res/values-mk/strings.xml
@@ -871,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Додадена е # контрола.}one{Додадени се # контрола.}other{Додадени се # контроли.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Отстранета"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Да се додаде <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Да се отстранат контролите за <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Омилена"</string>
@@ -897,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Да се прикажуваат и контролираат уреди од заклучениот екран?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Може да додадете контроли за надворешните уреди на заклучениот екран.\n\nАпликацијата на уредот може да ви дозволи да контролирате одредени уреди без да го отклучувате телефонот или таблетот.\n\nМоже да извршите промени во секое време во „Поставки“."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Да се контролираат уреди од заклучен екран?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Може да контролирате одредени уреди без отклучување на телефонот или таблетот. Апликацијата на вашиот уред одредува кои уреди може да се контролираат вака."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Не, фала"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Да"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-кодот содржи букви или симболи"</string>
diff --git a/packages/SystemUI/res/values-ml/strings.xml b/packages/SystemUI/res/values-ml/strings.xml
index a25aa2c..2597fcd 100644
--- a/packages/SystemUI/res/values-ml/strings.xml
+++ b/packages/SystemUI/res/values-ml/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"സ്ക്രീൻ പൂർണ്ണമായും മാഗ്നിഫൈ ചെയ്യുക"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"സ്ക്രീനിന്റെ ഭാഗം മാഗ്നിഫൈ ചെയ്യുക"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"മാറുക"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"മാഗ്നിഫിക്കേഷൻ ക്രമീകരണം തുറക്കുക"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"വലുപ്പം മാറ്റാൻ മൂല വലിച്ചിടുക"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ഡയഗണൽ സ്ക്രോളിംഗ് അനുവദിക്കുക"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"വലുപ്പം മാറ്റുക"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"ഇടത് ഹാൻഡിൽ"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"വലത് ഹാൻഡിൽ"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"ചുവടെയുള്ള ഹാൻഡിൽ"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"മാഗ്നിഫിക്കേഷൻ ക്രമീകരണം"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"മാഗ്നിഫയർ വലുപ്പം"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"സൂം ചെയ്യുക"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"ഇടത്തരം"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# നിയന്ത്രണം ചേർത്തു.}other{# നിയന്ത്രണങ്ങൾ ചേർത്തു.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"നീക്കം ചെയ്തു"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ചേർക്കണോ?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> എന്നതിനുള്ള നിയന്ത്രണങ്ങൾ നീക്കം ചെയ്യണോ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"പ്രിയപ്പെട്ടതാക്കി"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ലോക്ക് സ്ക്രീനിൽ നിന്ന് ഉപകരണങ്ങൾ കാണിക്കുകയും നിയന്ത്രിക്കുകയും ചെയ്യണോ?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"നിങ്ങളുടെ ബാഹ്യ ഉപകരണങ്ങൾക്കുള്ള നിയന്ത്രണങ്ങൾ ലോക്ക് സ്ക്രീനിലേക്ക് ചേർക്കാനാകും.\n\nനിങ്ങളുടെ ഫോണോ ടാബ്ലെറ്റോ അൺലോക്ക് ചെയ്യാതെ ചില ഉപകരണങ്ങൾ നിയന്ത്രിക്കാൻ നിങ്ങളുടെ ഉപകരണ ആപ്പ് അനുവദിച്ചേക്കും.\n\nനിങ്ങൾക്ക് ക്രമീകരണത്തിൽ ഏതുസമയത്തും മാറ്റങ്ങൾ വരുത്താം."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ലോക്ക് സ്ക്രീനിൽ നിന്ന് ഉപകരണങ്ങൾ നിയന്ത്രിക്കണോ?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"നിങ്ങളുടെ ഫോണോ ടാബ്ലെറ്റോ അൺലോക്ക് ചെയ്യാതെ ചില ഉപകരണങ്ങൾ നിയന്ത്രിക്കാം. ഏതൊക്കെ ഉപകരണങ്ങൾ ഈ രീതിയിൽ നിയന്ത്രിക്കാൻ കഴിയുമെന്ന് നിങ്ങളുടെ ഉപകരണ ആപ്പ് നിർണ്ണയിക്കുന്നു."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"വേണ്ട, നന്ദി"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"ഉവ്വ്"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"പിന്നിൽ അക്ഷരങ്ങളോ ചിഹ്നങ്ങളോ അടങ്ങിയിരിക്കുന്നു"</string>
diff --git a/packages/SystemUI/res/values-mn/strings.xml b/packages/SystemUI/res/values-mn/strings.xml
index 73a4b75..cd5bdfd 100644
--- a/packages/SystemUI/res/values-mn/strings.xml
+++ b/packages/SystemUI/res/values-mn/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Бүтэн дэлгэцийг томруулах"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Дэлгэцийн нэг хэсгийг томруулах"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Сэлгэх"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Томруулах тохиргоог нээх"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Хэмжээг өөрчлөхийн тулд булангаас чирнэ үү"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Хөндлөн гүйлгэхийг зөвшөөрнө үү"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Хэмжээг өөрчлөх"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Зүүн бариул"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Баруун бариул"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Доод бариул"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Томруулах тохиргоо"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Томруулагчийн хэмжээ"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Томруулалт"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Дунд зэрэг"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# хяналт нэмсэн.}other{# хяналт нэмсэн.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Хассан"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>-г нэмэх үү?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g>-н тохиргоог хасах уу?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Дуртай гэж тэмдэглэсэн"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Түгжигдсэн дэлгэцээс төхөөрөмжүүдийг харуулж, хянах уу?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Та түгжигдсэн дэлгэцэд гадаад төхөөрөмжүүдийнхээ хяналтыг нэмэх боломжтой.\n\nТаны төхөөрөмжийн апп танд утас эсвэл таблетынхаа түгжээг тайлахгүйгээр зарим төхөөрөмжийг хянах боломжийг олгож магадгүй.\n\nТа хүссэн үедээ Тохиргоонд өөрчлөлт хийж болно."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Төхөөрөмжүүдийг түгжигдсэн дэлгэцээс хянах уу?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Та утас эсвэл таблетынхаа түгжээг тайлахгүйгээр зарим төхөөрөмжийг хянах боломжтой. Таны төхөөрөмжийн апп энэ аргаар ямар төхөөрөмжүүдийг хянах боломжтойг тодорхойлно."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Үгүй, баярлалаа"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Тийм"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ПИН нь үсэг эсвэл дүрс тэмдэгт агуулдаг"</string>
diff --git a/packages/SystemUI/res/values-mr/strings.xml b/packages/SystemUI/res/values-mr/strings.xml
index fea5b63..ea86fae 100644
--- a/packages/SystemUI/res/values-mr/strings.xml
+++ b/packages/SystemUI/res/values-mr/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB सुरू करा"</string>
<string name="learn_more" msgid="4690632085667273811">"अधिक जाणून घ्या"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"स्क्रीनशॉट"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"एक्स्टेंड अनलॉक बंद केले आहे"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"इमेज पाठवली आहे"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"स्क्रीनशॉट सेव्ह करत आहे…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"कार्य प्रोफाइलवर स्क्रीनशॉट सेव्ह करत आहे…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"फुल स्क्रीन मॅग्निफाय करा"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रीनचा काही भाग मॅग्निफाय करा"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"स्विच करा"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"मॅग्निफिकेशन सेटिंग्ज उघडा"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"आकार बदलण्यासाठी कोपरा ड्रॅग करा"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"तिरपे स्क्रोल करण्याची अनुमती द्या"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"आकार बदला"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"डावीकडील हँडल"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"उजवीकडील हँडल"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"तळाकडील हँडल"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"मॅग्निफिकेशन सेटिंग्ज"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"मॅग्निफायरचा आकार"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"झूम करा"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"मध्यम"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# नियंत्रण जोडले आहे.}other{# नियंत्रणे जोडली आहेत.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"काढून टाकले"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> जोडायचे आहे का?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> साठी नियंत्रणे काढून टाकायची आहेत का?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"आवडले"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"लॉक स्क्रीनवरून डिव्हाइस दाखवायचे आणि नियंत्रित करायचे का?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"तुम्ही तुमच्या बाह्य डिव्हाइससाठी लॉक स्क्रीनवर नियंत्रणे जोडू शकता.\n\nतुमचे डिव्हाइस अॅप तुम्हाला तुमचा फोन किंवा टॅबलेट अनलॉक न करता काही डिव्हाइस नियंत्रित करण्याची अनुमती देऊ शकते.\n\nतुम्ही सेटिंग्ज मध्ये कधीही बदल करू शकता."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"लॉक स्क्रीनवरून डिव्हाइस नियंत्रित करायची का?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"तुमचा फोन किंवा टॅबलेट अनलॉक न करता तुम्ही काही डिव्हाइस नियंत्रित करू शकता. तुमचे डिव्हाइस अॅप हे अशा प्रकारे कोणती डिव्हाइस नियंत्रित केली जाऊ शकतात हे निर्धारित करते."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"नाही, नको"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"होय"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"पिनमध्ये अक्षरे किंवा चिन्हे आहेत"</string>
diff --git a/packages/SystemUI/res/values-ms/strings.xml b/packages/SystemUI/res/values-ms/strings.xml
index 202d66f..1158287 100644
--- a/packages/SystemUI/res/values-ms/strings.xml
+++ b/packages/SystemUI/res/values-ms/strings.xml
@@ -871,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kawalan ditambah.}other{# kawalan ditambah.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Dialih keluar"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Tambahkan <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Alih keluar kawalan untuk <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Digemari"</string>
@@ -897,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Tunjukkan dan kawal peranti daripada skrin kunci?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Anda boleh menambah kawalan untuk peranti luaran anda pada skrin kunci.\n\nApl peranti anda mungkin membenarkan anda mengawal sesetengah peranti tanpa membuka kunci telefon atau tablet anda.\n\nAnda boleh membuat perubahan pada bila-bila masa dalam Tetapan."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Kawal peranti daripada skrin kunci?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Anda boleh mengawal sesetengah peranti tanpa membuka kunci telefon atau tablet anda. Apl peranti anda menentukan peranti yang boleh dikawal dengan cara ini."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Tidak perlu"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ya"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN mengandungi huruf atau simbol"</string>
diff --git a/packages/SystemUI/res/values-my/strings.xml b/packages/SystemUI/res/values-my/strings.xml
index bb1bba9..c110097 100644
--- a/packages/SystemUI/res/values-my/strings.xml
+++ b/packages/SystemUI/res/values-my/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ဖန်သားပြင်အပြည့် ချဲ့သည်"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ဖန်သားပြင် တစ်စိတ်တစ်ပိုင်းကို ချဲ့ပါ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ခလုတ်"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ချဲ့ခြင်း ဆက်တင်များ ဖွင့်ရန်"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"အရွယ်အစားပြန်ပြုပြင်ရန် ထောင့်စွန်းကို ဖိဆွဲပါ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ထောင့်ဖြတ် လှိမ့်ခွင့်ပြုရန်"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"အရွယ်အစားပြန်ပြုပြင်ရန်"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"ဘယ်ဘက်အထိန်း"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"ညာဘက်အထိန်း"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"အောက်ခြေအထိန်း"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"ချဲ့ခြင်း ဆက်တင်များ"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"မှန်ဘီလူး အရွယ်အစား"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"ဇူးမ်"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"အလတ်"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}other{ထိန်းချုပ်ခလုတ် # ခု ထည့်ထားသည်။}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ဖယ်ရှားထားသည်"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ထည့်မလား။"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> အတွက် သတ်မှတ်ချက်များ ဖယ်ရှားမလား။"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"အကြိုက်ဆုံးတွင် ထည့်ထားသည်"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"လော့ခ်မျက်နှာပြင်တွင် စက်ပစ္စည်းများကြည့်ရှုပြီး ထိန်းချုပ်မလား။"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"လော့ခ်မျက်နှာပြင်တွင် ပြင်ပစက်များအတွက် ထိန်းချုပ်မှုများ ထည့်နိုင်သည်။\n\nသင့်စက်ပစ္စည်းအက်ပ်က အချို့စက်များကို ဖုန်း (သို့) တက်ဘလက် လော့ခ်ဖွင့်ရန်မလိုဘဲ သုံးခွင့်ပေးနိုင်သည်။\n\nဆက်တင်များ၌ အချိန်မရွေး ပြောင်းလဲပြင်ဆင်နိုင်သည်။"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"လော့ခ်မျက်နှာပြင်တွင် စက်ပစ္စည်းများ ထိန်းချုပ်မလား။"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"အချို့စက်များကို ဖုန်း (သို့) တက်ဘလက် လော့ခ်ဖွင့်ရန်မလိုဘဲ ထိန်းချုပ်နိုင်သည်။ ဤနည်းလမ်းအတိုင်း ထိန်းချုပ်နိုင်မည့်စက်များကို သင့်စက်ပစ္စည်းအက်ပ်က ဆုံးဖြတ်သည်။"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"မလိုပါ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yes"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ပင်နံပါတ်တွင် စာလုံး သို့မဟုတ် သင်္ကေတများပါဝင်သည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index 1618f73..c6a665a 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Forstørr hele skjermen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Forstørr en del av skjermen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Bytt"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Åpne innstillinger for forstørring"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Dra hjørnet for å endre størrelse"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Tillat diagonal rulling"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Endre størrelse"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Venstre håndtak"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Høyre håndtak"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Nedre håndtak"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Innstillinger for forstørring"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Forstørringsstørrelse"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Middels"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll er lagt til.}other{# kontroller er lagt til.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Fjernet"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Vil du legge til <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Vil du fjerne kontrollene for <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoritt"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Vil du se og kontrollere enheter fra låseskjermen?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Du kan legge til kontroller for de eksterne enhetene dine på låseskjermen.\n\nEnhetsappen kan la deg kontrollere noen enheter uten å låse opp telefonen eller nettbrettet.\n\nDu kan når som helst endre innstillingene."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Vil du kontrollere enheter fra låseskjermen?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Du kan kontrollere visse enheter uten å låse opp telefonen eller nettbrettet. Enhetsappen avgjør hvilke enheter som kan kontrolleres på denne måten."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nei takk"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ja"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-koden inneholder bokstaver eller symboler"</string>
diff --git a/packages/SystemUI/res/values-ne/strings.xml b/packages/SystemUI/res/values-ne/strings.xml
index eafca69..621fdab 100644
--- a/packages/SystemUI/res/values-ne/strings.xml
+++ b/packages/SystemUI/res/values-ne/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"पूरै स्क्रिन जुम इन गर्नुहोस्"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"स्क्रिनको केही भाग म्याग्निफाइ गर्नुहोस्"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"बदल्नुहोस्"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"जुम इनसम्बन्धी सेटिङ खोल्नुहोस्"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"आकार बदल्न कुनाबाट ड्र्याग गर्नुहोस्"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"डायगोनल तरिकाले स्क्रोल गर्ने अनुमति दिनुहोस्"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"आकार बदल्नुहोस्"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"बायाँतिरको ह्यान्डल"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"दायाँतिरको ह्यान्डल"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"पुछारको ह्यान्डल"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"जुम इनसम्बन्धी सेटिङ"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"म्याग्निफायरको आकार"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"जुम"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"मध्यम"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# कन्ट्रोल हालियो।}other{# वटा कन्ट्रोल हालियो।}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"हटाइएको"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> हाल्ने हो?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> का सेटिङ हटाउने हो?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"मनपराइएको"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"लक स्क्रिनमै डिभाइसहरू देखाउने र लक स्क्रिनबाटै ती डिभाइसहरू नियन्त्रण गर्ने हो?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"तपाईं आफ्ना बाह्य डिभाइसहरूका कन्ट्रोलहरू लक स्क्रिनमा हाल्न सक्नुहुन्छ।\n\nतपाईंको डिभाइसको एपले तपाईंलाई आफ्नो फोन वा ट्याब्लेट अनलक नगरिकनै केही डिभाइसहरू नियन्त्रण गर्ने अनुमति दिन सक्छ।\n\nतपाईं जुनसुकै बेला सेटिङमा गई यी कुराहरू बदल्न सक्नुहुन्छ।"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"लक स्क्रिनबाटै डिभाइसहरू नियन्त्रण गर्ने हो?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"तपाईं आफ्नो फोन वा ट्याब्लेट अनलक नगरिकनै केही डिभाइसहरू नियन्त्रण गर्न सक्नुहुन्छ। तपाईंको डिभाइस एपले यस तरिकाले कुन कुन डिभाइस नियन्त्रण गर्न सकिन्छ भन्ने कुरा निर्धारण गर्छ।"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"पर्दैन"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"अँ"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN मा अक्षर वा चिन्हहरू समाविष्ट हुन्छन्"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 4427571..3b8a957 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Volledig scherm vergroten"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Deel van het scherm vergroten"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Schakelen"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Instellingen voor vergroting openen"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Sleep een hoek om het formaat te wijzigen"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonaal scrollen toestaan"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Formaat aanpassen"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Handgreep links"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Handgreep rechts"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Handgreep onderaan"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Instellingen voor vergroting"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Vergrotingsgrootte"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoomen"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Normaal"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# bedieningselement toegevoegd.}other{# bedieningselementen toegevoegd.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Verwijderd"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> toevoegen?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Bedieningselementen voor <xliff:g id="APPNAME">%s</xliff:g> verwijderen?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Gemarkeerd als favoriet"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Apparaten tonen en bedienen via het vergrendelscherm?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Je kunt bedieningselementen voor je externe apparaten toevoegen aan het vergrendelscherm.\n\nMet je apparaat-app kun je misschien bepaalde apparaten bedienen zonder je telefoon of tablet te ontgrendelen.\n\nJe kunt op elk moment wijzigingen aanbrengen via Instellingen."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Apparaten bedienen via vergrendelscherm?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Je kunt bepaalde apparaten bedienen zonder je telefoon of tablet te ontgrendelen. Je apparaat-app bepaalt welke apparaten op deze manier kunnen worden bediend."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nee, bedankt"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ja"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pincode bevat letters of symbolen"</string>
diff --git a/packages/SystemUI/res/values-or/strings.xml b/packages/SystemUI/res/values-or/strings.xml
index fb036f3..98ae465 100644
--- a/packages/SystemUI/res/values-or/strings.xml
+++ b/packages/SystemUI/res/values-or/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ସମ୍ପୂର୍ଣ୍ଣ ସ୍କ୍ରିନକୁ ମ୍ୟାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ସ୍କ୍ରିନର ଅଂଶ ମାଗ୍ନିଫାଏ କରନ୍ତୁ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ସ୍ୱିଚ୍ କରନ୍ତୁ"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ମାଗ୍ନିଫିକେସନ ସେଟିଂସ ଖୋଲନ୍ତୁ"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ରିସାଇଜ କରିବା ପାଇଁ କୋଣକୁ ଡ୍ରାଗ କରନ୍ତୁ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ଡାଏଗୋନାଲ ସ୍କ୍ରୋଲିଂକୁ ଅନୁମତି ଦିଅନ୍ତୁ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ରିସାଇଜ କରନ୍ତୁ"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"ବାମ ହ୍ୟାଣ୍ଡେଲ"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"ଡାହାଣ ହ୍ୟାଣ୍ଡେଲ"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"ନିମ୍ନର ହ୍ୟାଣ୍ଡେଲ"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"ମାଗ୍ନିଫିକେସନ ସେଟିଂସ"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"ମ୍ୟାଗ୍ନିଫାୟରର ଆକାର"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"ଜୁମ କରନ୍ତୁ"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"ମଧ୍ୟମ"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}other{#ଟି ନିୟନ୍ତ୍ରଣ ଯୋଗ କରାଯାଇଛି।}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"କାଢ଼ି ଦିଆଯାଇଛି"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>କୁ ଯୋଗ କରିବେ?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> ପାଇଁ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକୁ କାଢ଼ି ଦେବେ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ପସନ୍ଦ କରାଯାଇଛି"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ଲକ ସ୍କ୍ରିନରୁ ଡିଭାଇସଗୁଡ଼ିକୁ ଦେଖାଇବେ ଏବଂ ନିୟନ୍ତ୍ରଣ କରିବେ?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ଆପଣ ଲକ ସ୍କ୍ରିନରେ ଆପଣଙ୍କ ଏକ୍ସଟର୍ନଲ ଡିଭାଇସଗୁଡ଼ିକ ପାଇଁ ନିୟନ୍ତ୍ରଣଗୁଡ଼ିକ ଯୋଗ କରିପାରିବେ।\n\nଆପଣଙ୍କ ଫୋନ କିମ୍ବା ଟାବଲେଟକୁ ଅନଲକ ନକରି କିଛି ଡିଭାଇସକୁ ନିୟନ୍ତ୍ରଣ କରିବା ପାଇଁ ଆପଣଙ୍କ ଡିଭାଇସର ଆପ ଆପଣଙ୍କୁ ଅନୁମତି ଦେଇପାରେ।\n\nଆପଣ ଯେ କୌଣସି ସମୟରେ ସେଟିଂସରେ ପରିବର୍ତ୍ତନ କରିପାରିବେ।"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ଲକ ସ୍କ୍ରିନରୁ ଡିଭାଇସଗୁଡ଼ିକୁ ନିୟନ୍ତ୍ରଣ କରିବେ?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"ଆପଣ ଆପଣଙ୍କ ଫୋନ କିମ୍ବା ଟାବଲେଟକୁ ଅନଲକ ନକରି କିଛି ଡିଭାଇସକୁ ନିୟନ୍ତ୍ରଣ କରିପାରିବେ। ଏହି ଉପାୟରେ କେଉଁ ଡିଭାଇସଗୁଡ଼ିକୁ ନିୟନ୍ତ୍ରଣ କରାଯାଇପାରିବ ତାହା ଆପଣଙ୍କ ଡିଭାଇସ ଆପ ସ୍ଥିର କରେ।"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"ନା, ଧନ୍ୟବାଦ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"ହଁ"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PINରେ ଅକ୍ଷର କିମ୍ୱା ପ୍ରତୀକଗୁଡ଼ିକ ଥାଏ"</string>
diff --git a/packages/SystemUI/res/values-pa/strings.xml b/packages/SystemUI/res/values-pa/strings.xml
index 6aea323..ebdcd0c 100644
--- a/packages/SystemUI/res/values-pa/strings.xml
+++ b/packages/SystemUI/res/values-pa/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ਪੂਰੀ ਸਕ੍ਰੀਨ ਨੂੰ ਵੱਡਦਰਸ਼ੀ ਕਰੋ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ਸਕ੍ਰੀਨ ਦੇ ਹਿੱਸੇ ਨੂੰ ਵੱਡਾ ਕਰੋ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ਸਵਿੱਚ"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਸੈਟਿੰਗਾਂ ਖੋਲ੍ਹੋ"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ਆਕਾਰ ਬਦਲਣ ਲਈ ਕੋਨਾ ਘਸੀਟੋ"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"ਟੇਡੀ ਦਿਸ਼ਾ ਵਿੱਚ ਸਕ੍ਰੋਲ ਕਰਨ ਦਿਓ"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ਆਕਾਰ ਬਦਲੋ"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"ਖੱਬਾ ਹੈਂਡਲ"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"ਸੱਜਾ ਹੈਂਡਲ"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"ਹੇਠਲਾਂ ਹੈਂਡਲ"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"ਵੱਡਦਰਸ਼ੀਕਰਨ ਸੈਟਿੰਗਾਂ"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"ਵੱਡਦਰਸ਼ੀ ਦਾ ਆਕਾਰ"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"ਜ਼ੂਮ"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"ਦਰਮਿਆਨਾ"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}one{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ।}other{# ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕੀਤੇ ਗਏ।}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ਹਟਾਇਆ ਗਿਆ"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"ਕੀ <xliff:g id="APPNAME">%s</xliff:g> ਸ਼ਾਮਲ ਕਰਨਾ ਹੈ?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"ਕੀ <xliff:g id="APPNAME">%s</xliff:g> ਲਈ ਕੰਟਰੋਲਾਂ ਨੂੰ ਹਟਾਉਣਾ ਹੈ?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ਮਨਪਸੰਦ ਵਿੱਚ ਸ਼ਾਮਲ ਕੀਤਾ ਗਿਆ"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"ਕੀ ਲਾਕ ਸਕ੍ਰੀਨ ਤੋਂ ਡੀਵਾਈਸਾਂ ਨੂੰ ਦੇਖਣਾ ਅਤੇ ਕੰਟਰੋਲ ਕਰਨਾ ਹੈ?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ਤੁਸੀਂ ਲਾਕ ਸਕ੍ਰੀਨ \'ਤੇ ਆਪਣੇ ਬਾਹਰੀ ਡੀਵਾਈਸਾਂ ਲਈ ਕੰਟਰੋਲ ਸ਼ਾਮਲ ਕਰ ਸਕਦੇ ਹੋ।\n\nਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਮੌਜੂਦ ਐਪ ਤੁਹਾਨੂੰ ਤੁਹਾਡੇ ਫ਼ੋਨ ਜਾਂ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕੀਤੇ ਬਿਨਾਂ ਕੁਝ ਡੀਵਾਈਸਾਂ ਨੂੰ ਕੰਟਰੋਲ ਕਰਨ ਦੇ ਸਕਦੀ ਹੈ।\n\nਤੁਸੀਂ ਸੈਟਿੰਗਾਂ ਵਿੱਚ ਜਾ ਕੇ ਕਿਸੇ ਵੇਲੇ ਵੀ ਤਬਦੀਲੀਆਂ ਕਰ ਸਕਦੇ ਹੋ।"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ਕੀ ਲਾਕ ਸਕ੍ਰੀਨ ਤੋਂ ਡੀਵਾਈਸਾਂ ਨੂੰ ਕੰਟਰੋਲ ਕਰਨਾ ਹੈ?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"ਤੁਸੀਂ ਆਪਣੇ ਫ਼ੋਨ ਜਾਂ ਟੈਬਲੈੱਟ ਨੂੰ ਅਣਲਾਕ ਕੀਤੇ ਬਿਨਾਂ ਕੁਝ ਡੀਵਾਈਸਾਂ ਨੂੰ ਕੰਟਰੋਲ ਕਰ ਸਕਦੇ ਹੋ। ਤੁਹਾਡੇ ਡੀਵਾਈਸ \'ਤੇ ਮੌਜੂਦ ਐਪ ਇਹ ਨਿਰਧਾਰਿਤ ਕਰਦੀ ਹੈ ਕਿ ਇਸ ਤਰੀਕੇ ਨਾਲ ਕਿਹੜੇ ਡੀਵਾਈਸਾਂ ਨੂੰ ਕੰਟਰੋਲ ਕੀਤਾ ਜਾ ਸਕਦਾ ਹੈ।"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"ਨਹੀਂ ਧੰਨਵਾਦ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"ਹਾਂ"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"ਪਿੰਨ ਵਿੱਚ ਅੱਖਰ ਜਾਂ ਚਿੰਨ੍ਹ ਸ਼ਾਮਲ ਹਨ"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index 583259e..37eb638 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Włącz USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Więcej informacji"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Zrzut ekranu"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Wyłączono Extend Unlock"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"wysłano obraz"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Zapisywanie zrzutu ekranu..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Zapisuję zrzut ekranu w profilu służbowym…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Powiększanie pełnego ekranu"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Powiększ część ekranu"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Przełącz"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otwórz ustawienia powiększenia"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Przeciągnij róg, aby zmienić rozmiar"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Zezwalaj na przewijanie poprzeczne"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Zmień rozmiar"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Lewy uchwyt"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Prawy uchwyt"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Dolny uchwyt"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Ustawienia powiększenia"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Rozmiar powiększania"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Powiększenie"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Średni"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Dodano # element sterujący.}few{Dodano # elementy sterujące.}many{Dodano # elementów sterujących.}other{Dodano # elementu sterującego.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Usunięto"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Dodać aplikację <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Usunąć elementy sterujące aplikacji <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano do ulubionych"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Pokazywać urządzenia i umożliwiać sterowanie nimi na ekranie blokady?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Możesz dodać do ekranu blokady elementy sterujące dotyczące urządzeń zewnętrznych.\n\nMożesz mieć możliwość sterowania niektórymi urządzeniami za pomocą aplikacji na telefonie lub tablecie bez odblokowywania tych urządzeń.\n\nW dowolnej chwili możesz wprowadzić zmiany w Ustawieniach."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Sterować urządzeniami na ekranie blokady?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Możesz sterować niektórymi urządzeniami bez odblokowywania telefonu lub tabletu. Aplikacja urządzenia określa, którymi urządzeniami możesz sterować w ten sposób."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nie, dziękuję"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Tak"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Kod PIN zawiera litery lub symbole"</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index 616e007..498428e 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ativar USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Saiba mais"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Capturar tela"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock desativado"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou uma imagem"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Salvando captura de tela..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Salvando captura de tela no perfil de trabalho…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Trocar"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir as configurações de ampliação"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arraste o canto para redimensionar"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir rolagem diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionar"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Alça esquerda"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Alça direita"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Alça de baixo"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Configurações de ampliação"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Tamanho da lupa"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Médio"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar o app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remover controles do app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Mostrar e controlar dispositivos na tela de bloqueio?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Você pode adicionar à tela de bloqueio controles para dispositivos externos.\n\nO app do dispositivo pode permitir que você controle alguns dispositivos sem desbloquear o smartphone ou tablet.\n\nÉ possível fazer mudanças a qualquer momento nas Configurações."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Controlar dispositivos na tela de bloqueio?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"É possível controlar alguns dispositivos sem desbloquear o smartphone ou tablet. O app determina quais dispositivos podem ser controlados dessa maneira."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Agora não"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Sim"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contém letras ou símbolos"</string>
@@ -1092,7 +1088,7 @@
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir o acesso único"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
- <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os dele. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saiba mais"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saiba mais em <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index c1fb700..59e6cc4 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ativar USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Saiba mais"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Captura de ecrã"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Desbloqueio prolongado desativado"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou uma imagem"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"A guardar captura de ecrã..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"A guardar captura de ecrã no perfil de trabalho…"</string>
@@ -871,7 +870,8 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controlo adicionado.}many{# controlos adicionados.}other{# controlos adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <string name="controls_panel_authorization" msgid="4665218066461350247">"A app <xliff:g id="APPNAME">%s</xliff:g> pode escolher que controlos e conteúdos são apresentados aqui."</string>
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
+ <skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remover controlos para a app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado aos favoritos"</string>
<string name="accessibility_control_favorite_position" msgid="54220258048929221">"Adicionados aos favoritos, posição <xliff:g id="NUMBER">%d</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index 616e007..498428e 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"Ativar USB"</string>
<string name="learn_more" msgid="4690632085667273811">"Saiba mais"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Capturar tela"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Extend Unlock desativado"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"enviou uma imagem"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Salvando captura de tela..."</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Salvando captura de tela no perfil de trabalho…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ampliar toda a tela"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ampliar parte da tela"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Trocar"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Abrir as configurações de ampliação"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Arraste o canto para redimensionar"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permitir rolagem diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionar"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Alça esquerda"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Alça direita"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Alça de baixo"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Configurações de ampliação"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Tamanho da lupa"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Médio"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# controle adicionado.}one{# controle adicionado.}many{# de controles adicionados.}other{# controles adicionados.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Removido"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adicionar o app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Remover controles do app <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Adicionado como favorito"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Mostrar e controlar dispositivos na tela de bloqueio?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Você pode adicionar à tela de bloqueio controles para dispositivos externos.\n\nO app do dispositivo pode permitir que você controle alguns dispositivos sem desbloquear o smartphone ou tablet.\n\nÉ possível fazer mudanças a qualquer momento nas Configurações."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Controlar dispositivos na tela de bloqueio?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"É possível controlar alguns dispositivos sem desbloquear o smartphone ou tablet. O app determina quais dispositivos podem ser controlados dessa maneira."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Agora não"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Sim"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"O PIN contém letras ou símbolos"</string>
@@ -1092,7 +1088,7 @@
<string name="log_access_confirmation_title" msgid="4843557604739943395">"Permitir que o app <xliff:g id="LOG_ACCESS_APP_NAME">%s</xliff:g> acesse todos os registros do dispositivo?"</string>
<string name="log_access_confirmation_allow" msgid="752147861593202968">"Permitir o acesso único"</string>
<string name="log_access_confirmation_deny" msgid="2389461495803585795">"Não permitir"</string>
- <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os próprios. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
+ <string name="log_access_confirmation_body" msgid="6883031912003112634">"Os registros do dispositivo gravam o que acontece nele. Os apps podem usar esses registros para encontrar e corrigir problemas.\n\nAlguns registros podem conter informações sensíveis, então autorize o acesso a eles apenas para os apps em que você confia. \n\nSe você não permitir que esse app acesse todos os registros do dispositivo, ele ainda vai poder acessar os dele. O fabricante do dispositivo também pode ter acesso a alguns registros ou informações."</string>
<string name="log_access_confirmation_learn_more" msgid="3134565480986328004">"Saiba mais"</string>
<string name="log_access_confirmation_learn_more_at" msgid="5635666259505215905">"Saiba mais em <xliff:g id="URL">%s</xliff:g>"</string>
<string name="keyguard_affordance_enablement_dialog_action_template" msgid="8164857863036314664">"Abrir <xliff:g id="APPNAME">%1$s</xliff:g>"</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 7f531e7..ae0939f 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Mărește tot ecranul"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Mărește o parte a ecranului"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Comutator"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Deschide setările pentru mărire"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Trage de colț pentru a redimensiona"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Permite derularea pe diagonală"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Redimensionează"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Ghidajul din stânga"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Ghidajul din dreapta"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Ghidajul de jos"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Setări pentru mărire"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Dimensiunea lupei"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mediu"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{S-a adăugat # comandă.}few{S-au adăugat # comenzi.}other{S-au adăugat # de comenzi.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Eliminată"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Adaugi <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Elimini comenzile pentru <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Marcată ca preferată"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Afișezi și controlezi dispozitivele de pe ecranul de blocare?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Poți adăuga comenzi pentru dispozitivele externe pe ecranul de blocare.\n\nAplicația de pe dispozitiv îți poate permite să controlezi unele dispozitive fără să deblochezi telefonul.\n\nPoți face modificări oricând în setări."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Controlezi dispozitivele de pe ecranul de blocare?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Poți controla unele dispozitive fără să deblochezi telefonul sau tableta. Aplicația de dispozitiv stabilește dispozitivele care pot fi controlate astfel."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nu, mulțumesc"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Da"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Codul PIN conține litere sau simboluri"</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 79f2abf..244bdf7 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увеличение всего экрана"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увеличить часть экрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Переключить"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Открыть настройки увеличения"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Потяните за угол, чтобы изменить размер"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Разрешить прокручивать по диагонали"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Изменить размер"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Левый маркер"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Правый маркер"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Нижний маркер"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Настройки увеличения"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Размер лупы"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Масштаб"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Средняя"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Добавлен # элемент управления.}one{Добавлен # элемент управления.}few{Добавлено # элемента управления.}many{Добавлено # элементов управления.}other{Добавлено # элемента управления.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Удалено"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Добавить приложение \"<xliff:g id="APPNAME">%s</xliff:g>\"?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Удалить приложение \"<xliff:g id="APPNAME">%s</xliff:g>\" с панели управления устройствами?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Добавлено в избранное"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Разрешить показывать устройства и управлять ими на заблокированном экране?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Вы можете добавить элементы управления внешними устройствами на заблокированный экран.\n\nПриложение на вашем устройстве может разрешать управление некоторыми устройствами с заблокированного экрана.\n\nИзменить параметры можно в любое время в настройках."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Управлять устройствами на заблокированном экране?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Некоторыми устройствами можно управлять без разблокировки экрана на телефоне или планшете. Их точный перечень зависит от приложения на вашем устройстве."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Не сейчас"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Да"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-код содержит буквы или символы"</string>
diff --git a/packages/SystemUI/res/values-si/strings.xml b/packages/SystemUI/res/values-si/strings.xml
index 92c9a3f..61a5ce5 100644
--- a/packages/SystemUI/res/values-si/strings.xml
+++ b/packages/SystemUI/res/values-si/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"පූර්ණ තිරය විශාලනය කරන්න"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"තිරයේ කොටසක් විශාලනය කරන්න"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ස්විචය"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"විශාලන සැකසීම් විවෘත කරන්න"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ප්රමාණය වෙනස් කිරීමට කොන අදින්න"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"විකර්ණ අනුචලනයට ඉඩ දෙන්න"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ප්රතිප්රමාණය කරන්න"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"වම් හසුරුව"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"දකුණු හසුරුව"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"පහළ හසුරුව"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"විශාලන සැකසීම්"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"විශාලන තරම"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"විශාලනය කරන්න"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"මධ්යම"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# පාලනයක් එක් කර ඇත.}one{පාලන #ක් එක් කර ඇත.}other{පාලන #ක් එක් කර ඇත.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ඉවත් කළා"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> එක් කරන්න ද?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> සඳහා පාලන ඉවත් කරන්න ද?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ප්රියතම කළා"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"අගුලු තිරයෙන් උපාංග පෙන්වීම සහ පාලනය සිදු කරන්නද?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"ඔබට ඔබගේ බාහිර උපාංග සඳහා පාලන අගුලු තිරයට එක් කළ හැකිය.\n\nඔබගේ උපාංග යෙදුම ඔබගේ දුරකථනය හෝ ටැබ්ලටය අගුලු හැරීමෙන් තොරව සමහර උපාංග පාලනය කිරීමට ඉඩ ලබා දේ.\n\nඔබට සැකසීම් තුළ ඕනෑම වේලාවක වෙනස් කිරීම් සිදු කළ හැකිය."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"අගුලු තිරයෙන් උපාංග පාලනය කරන්නද?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"ඔබේ දුරකථනය හෝ ටැබ්ලටය අගුලු හැරීමෙන් තොරව ඔබට සමහර උපාංග පාලන කළ හැක. ඔබේ උපාංග යෙදුම මේ ආකාරයෙන් පාලන කළ හැකි උපාංග තීරණ කරයි."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"එපා ස්තුතියි"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"ඔව්"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN හි අකුරු හෝ සංකේත අඩංගු වේ"</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 090a82b..276f51f 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zväčšenie celej obrazovky"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zväčšiť časť obrazovky"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Prepnúť"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Otvoriť nastavenia zväčšenia"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Veľkosť zmeníte presunutím rohu"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Povoliť diagonálne posúvanie"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Zmeniť veľkosť"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Ľavá rukoväť"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Pravá rukoväť"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Dolná rukoväť"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Nastavenia zväčšenia"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Veľkosť zväčšenia"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Lupa"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Stredný"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Bol pridaný # ovládací prvok.}few{Boli pridané # ovládacie prvky.}many{# controls added.}other{Bolo pridaných # ovládacích prvkov.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Odstránené"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Chcete pridať aplikáciu <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Chcete odstrániť ovládanie aplikácie <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Pridané medzi obľúbené"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Chcete zobrazovať a ovládať zariadenia na uzamknutej obrazovke?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Na uzamknutú obrazovku si môžete pridať ovládanie externých zariadení.\n\nAplikácia zariadenia vám môže umožniť ovládať niektoré zariadenia bez odomknutia telefónu či tabletu.\n\nZmeny môžete vykonať kedykoľvek v Nastaveniach."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Chcete ovládať zariadenia na uzamknutej obrazovke?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Niektoré zariadenia môžete ovládať bez odomknutia telefónu či tabletu. Aplikácia zariadenia určuje, ktoré zariadenia sa dajú týmto spôsobom ovládať."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nie, vďaka"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Áno"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN obsahuje písmená či symboly"</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 84fd7c5..9736284 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Povečanje celotnega zaslona"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Povečava dela zaslona"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Stikalo"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Odpri nastavitve povečave"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Povlecite vogal, da spremenite velikost."</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Dovoli diagonalno pomikanje"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Spremeni velikost"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Ročica levo"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Ročica desno"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Ročica spodaj"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Nastavitve povečave"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Velikost povečevalnika"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Povečava/pomanjšava"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Srednja"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrolnik je dodan.}one{# kontrolnik je dodan.}two{# kontrolnika sta dodana.}few{# kontrolniki so dodani.}other{# kontrolnikov je dodanih.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Odstranjeno"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Želite dodati aplikacijo <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Želite odstraniti kontrolnike za aplikacijo <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Dodano med priljubljene"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Želite prikazati in upravljati naprave na zaklenjenem zaslonu?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Kontrolnike za zunanje naprave lahko dodate na zaklenjen zaslon.\n\nAplikacija v napravi vam bo morda omogočala upravljanje nekaterih naprav brez odklepanja telefona ali tabličnega računalnika.\n\nTe spremembe lahko kadar koli izvedete v nastavitvah."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Želite upravljati naprave na zaklenjenem zaslonu?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Nekatere naprave lahko upravljate brez odklepanja telefona ali tabličnega računalnika. Aplikacija v napravi določa, katere naprave je mogoče upravljati na ta način."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ne, hvala"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Da"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Koda PIN vsebuje črke ali simbole"</string>
diff --git a/packages/SystemUI/res/values-sq/strings.xml b/packages/SystemUI/res/values-sq/strings.xml
index 4cf4346..02f9638 100644
--- a/packages/SystemUI/res/values-sq/strings.xml
+++ b/packages/SystemUI/res/values-sq/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Zmadho ekranin e plotë"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Zmadho një pjesë të ekranit"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Ndërro"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Hap cilësimet e zmadhimit"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Zvarrit këndin për të ndryshuar përmasat"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Lejo lëvizjen diagonale"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ndrysho përmasat"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Doreza e majtë"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Doreza e djathtë"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Doreza e poshtme"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Cilësimet e zmadhimit"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Përmasa e zmadhimit"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zmadho"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Mesatar"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{U shtua # kontroll.}other{U shtuan # kontrolle.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"E hequr"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Të shtohet <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Të hiqen kontrollet për <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"E shtuar te të preferuarat"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Të shfaqen dhe të kontrollohen pajisjet nga ekrani i kyçjes?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Mund të shtosh kontrolle për pajisjet e tua të jashtme në ekranin e kyçjes.\n\nAplikacioni në pajisjen tënde mund të të lejojë të kontrollosh disa pajisje pa shkyçur telefonin apo tabletin.\n\nMund të bësh ndryshime në çdo kohë te \"Cilësimet\"."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Të kontrollohen pajisjet nga ekrani i kyçjes?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Mund të kontrollosh disa pajisje pa shkyçur telefonin apo tabletin tënd. Aplikacioni për pajisjen tënde përcakton se cilat pajisje mund të kontrollohen në këtë mënyrë."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Jo, faleminderit"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Po"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Kodi PIN përmban shkronja ose simbole"</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 987f5f5..ed99913 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Увећајте цео екран"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Увећајте део екрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Пређи"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Отвори подешавања увећања"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Превуците угао да бисте променили величину"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дозволи дијагонално скроловање"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Промени величину"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Лева ручица"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Десна ручица"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Доња ручица"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Подешавања увећања"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Величина лупе"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Зумирање"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Средње"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# контрола је додата.}one{# контрола је додата.}few{# контроле су додате.}other{# контрола је додато.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Уклоњено"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Желите ли да додате <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Желите да уклоните контроле за <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Означено је као омиљено"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Желите ли да приказујете и контролишете уређаје са закључаног екрана?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Можете да додате контроле за спољне уређаје на закључани екран.\n\nАпликација на уређају може да вам омогући да контролишете неке уређаје без откључавања телефона или таблета.\n\nТо можете да промените кад год желите у Подешавањима."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Желите ли да контролишете уређаје са закључаног екрана?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Неке уређаје можете да контролишете без откључавања телефона или таблета. Апликација на уређају одређује који уређаји могу да се контролишу на овај начин."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Не, хвала"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Да"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN садржи слова или симболе"</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index bffb743..2809b3b 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Förstora hela skärmen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Förstora en del av skärmen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Reglage"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Öppna inställningarna för förstoring"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Dra i hörnet för att ändra storlek"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Tillåt diagonal scrollning"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Ändra storlek"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Vänster handtag"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Höger handtag"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Nedre handtag"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Inställningar för förstoring"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Förstoringsstorlek"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Medel"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontroll har lagts till.}other{# kontroller har lagts till.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Har tagits bort"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Vill du lägga till <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Vill du ta bort inställningarna för <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Har lagts till som favorit"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Vill du se och styra enheter på låsskärmen?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Du kan lägga till reglage att styra externa enheter med på låsskärmen.\n\nVissa enheter kan gå att styra med appen på enheten utan att du behöver låsa upp telefonen eller surfplattan.\n\nDu kan när som helst ändra detta i inställningarna."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Vill du styra enheter på låsskärmen?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Du kan styra vissa enheter utan att låsa upp telefonen eller surfplattan. Vilka enheter som går att styra på det här sättet beror på appen på enheten."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Nej tack"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ja"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Pinkoden innehåller bokstäver eller symboler"</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 269d0a7..056a8a8 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Kuza skrini nzima"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Kuza sehemu ya skrini"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Swichi"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Fungua mipangilio ya ukuzaji"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Buruta kona ili ubadilishe ukubwa"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Ruhusu usogezaji wa kimshazari"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Badilisha ukubwa"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Ncha ya kushoto"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Ncha ya kulia"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Ncha ya chini"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Mipangilio ya ukuzaji"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Ukubwa wa kikuzaji"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Kuza"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Wastani"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Umeweka kidhibiti #.}other{Umeweka vidhibiti #.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Kimeondolewa"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Ungependa kuweka <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Ungependa kuondoa vidhibiti vya <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Kimewekwa kwenye vipendwa"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Ungependa kuonyesha na udhibiti vifaa kwenye skrini iliyofungwa?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Unaweza kuweka vidhibiti kwa ajili ya vifaa vyako vya nje kwenye skrini iliyofungwa.\n\nProgramu ya kifaa chako huenda ikakuruhusu udhibiti baadhi ya vifaa bila kufungua simu au kompyuta kibao yako.\n\nUnaweza kufanya mabadiliko muda wowote kwenye Mipangilio."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Ungependa kudhibiti vifaa kwenye skrini iliyofungwa?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Unaweza kudhibiti baadhi ya vifaa bila kufungua simu au kompyuta kibao yako. Programu ya kifaa chako hubainisha ni vifaa vipi vinaweza kudhibitiwa kwa njia hii."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Hapana"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ndiyo"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ina herufi au alama"</string>
diff --git a/packages/SystemUI/res/values-ta/strings.xml b/packages/SystemUI/res/values-ta/strings.xml
index ba38c98..49ace23 100644
--- a/packages/SystemUI/res/values-ta/strings.xml
+++ b/packages/SystemUI/res/values-ta/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"முழுத்திரையைப் பெரிதாக்கும்"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"திரையின் ஒரு பகுதியைப் பெரிதாக்கும்"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"ஸ்விட்ச்"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"பெரிதாக்கல் அமைப்புகளைத் திற"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"அளவை மாற்ற மூலையை இழுக்கவும்"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"குறுக்கே ஸ்க்ரோல் செய்வதை அனுமதி"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"அளவை மாற்று"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"இடது ஹேண்டில்"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"வலது ஹேண்டில்"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"கீழ்ப்புற ஹேண்டில்"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"பெரிதாக்கல் அமைப்புகள்"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"பெரிதாக்கும் கருவியின் அளவு"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"அளவை மாற்று"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"நடுத்தரமானது"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# கட்டுப்பாடு சேர்க்கப்பட்டது.}other{# கட்டுப்பாடுகள் சேர்க்கப்பட்டன.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"அகற்றப்பட்டது"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> ஆப்ஸைச் சேர்க்கவா?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> ஆப்ஸுக்கான கட்டுப்பாடுகளை அகற்றவா?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"பிடித்தவற்றில் சேர்க்கப்பட்டது"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"பூட்டுத் திரையிலிருந்தே சாதனங்களைப் பார்க்கவும் கட்டுப்படுத்தவும் அனுமதிக்கவா?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"வெளிப்புறச் சாதனங்களுக்கான கட்டுப்பாடுகளை உங்கள் பூட்டுத் திரையில் சேர்க்கலாம்.\n\nஉங்கள் மொபைலையோ டேப்லெட்டையோ அன்லாக் செய்யாமலேயே சில சாதனங்களைக் கட்டுப்படுத்த சாதன ஆப்ஸ் உங்களை அனுமதிக்கக்கூடும்.\n\nஅமைப்புகளுக்குச் சென்று எப்போது வேண்டுமானாலும் மாற்றங்களைச் செய்யலாம்."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"பூட்டுத் திரையிலிருந்தே சாதனங்களைக் கட்டுப்படுத்தவா?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"உங்கள் மொபைலையோ டேப்லெட்டையோ அன்லாக் செய்யாமலேயே சில சாதனங்களை நீங்கள் கட்டுப்படுத்தலாம். எந்தெந்தச் சாதனங்களை இவ்வாறு கட்டுப்படுத்தலாம் என்பதை உங்கள் சாதன ஆப்ஸ் தீர்மானிக்கும்."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"வேண்டாம்"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"ஆம்"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"பின்னில் எழுத்துகள் அல்லது குறிகள் உள்ளன"</string>
diff --git a/packages/SystemUI/res/values-te/strings.xml b/packages/SystemUI/res/values-te/strings.xml
index 4e0e625..9fe3d5c 100644
--- a/packages/SystemUI/res/values-te/strings.xml
+++ b/packages/SystemUI/res/values-te/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ఫుల్ స్క్రీన్ను మ్యాగ్నిఫై చేయండి"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"స్క్రీన్లో భాగాన్ని మ్యాగ్నిఫై చేయండి"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"స్విచ్ చేయి"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"మ్యాగ్నిఫికేషన్ సెట్టింగ్లను తెరవండి"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"సైజ్ మార్చడానికి మూలను లాగండి"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"వికర్ణ స్క్రోలింగ్ను అనుమతించండి"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"సైజ్ మార్చండి"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"ఎడమవైపు హ్యాండిల్"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"కుడివైపు హ్యాండిల్"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"కింద హ్యాండిల్"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"మ్యాగ్నిఫికేషన్ సెట్టింగ్లు"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"మాగ్నిఫయర్ సైజ్"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"జూమ్ చేయండి"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"మధ్యస్థం"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# కంట్రోల్ జోడించబడింది.}other{# కంట్రోల్స్ జోడించబడ్డాయి.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"తీసివేయబడింది"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g>ను జోడించాలా?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> కోసం కంట్రోల్స్ను తీసివేయాలా?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ఇష్టమైనదిగా గుర్తు పెట్టబడింది"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"లాక్ స్క్రీన్ నుండి పరికరాలను చూపించాలా, కంట్రోల్ చేయాలా?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"మీరు లాక్ స్క్రీన్కు మీ బాహ్య పరికరాల కోసం కంట్రోల్స్ను జోడించవచ్చు.\n\nమీ ఫోన్ లేదా టాబ్లెట్ను అన్లాక్ చేయకుండానే కొన్ని పరికరాలను కంట్రోల్ చేయడానికి మీ పరికర యాప్ మిమ్మల్ని అనుమతించవచ్చు.\n\nమీరు సెట్టింగ్లలో ఎప్పుడైనా మార్పులు చేయవచ్చు."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"లాక్ స్క్రీన్ నుండి పరికరాలను కంట్రోల్ చేయాలా?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"మీరు మీ ఫోన్ లేదా టాబ్లెట్ను అన్లాక్ చేయకుండానే కొన్ని పరికరాలను కంట్రోల్ చేయవచ్చు. ఈ విధంగా ఏ పరికరాలను కంట్రోల్ చేయవచ్చో మీ డివైజ్ యాప్ నిర్ణయిస్తుంది."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"వద్దు, ధన్యవాదాలు"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"అవును"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"పిన్ అక్షరాలను లేదా చిహ్నాలను కలిగి ఉంది"</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index c5de820..9f909a9 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -19,7 +19,7 @@
<resources xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
- <string name="app_label" msgid="4811759950673118541">"อินเทอร์เฟซผู้ใช้ของระบบ"</string>
+ <string name="app_label" msgid="4811759950673118541">"UI ของระบบ"</string>
<string name="battery_low_title" msgid="5319680173344341779">"เปิดโหมดประหยัดแบตเตอรี่ใช่ไหม"</string>
<string name="battery_low_description" msgid="3282977755476423966">"คุณมีแบตเตอรี่เหลืออยู่ <xliff:g id="PERCENTAGE">%s</xliff:g> โหมดประหยัดแบตเตอรี่จะเปิดธีมมืด จำกัดกิจกรรมในเบื้องหลัง และหน่วงเวลาการแจ้งเตือน"</string>
<string name="battery_low_intro" msgid="5148725009653088790">"โหมดประหยัดแบตเตอรี่จะเปิดธีมมืด จำกัดกิจกรรมในเบื้องหลัง และหน่วงเวลาการแจ้งเตือน"</string>
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"ขยายเป็นเต็มหน้าจอ"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"ขยายบางส่วนของหน้าจอ"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"เปลี่ยน"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"เปิดการตั้งค่าการขยาย"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"ลากที่มุมเพื่อปรับขนาด"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"อนุญาตการเลื่อนแบบทแยงมุม"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"ปรับขนาด"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"แฮนเดิลซ้าย"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"แฮนเดิลขวา"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"แฮนเดิลล่าง"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"การตั้งค่าการขยาย"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"ขนาดแว่นขยาย"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"ซูม"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"ปานกลาง"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{เพิ่มตัวควบคุม # ตัวแล้ว}other{เพิ่มตัวควบคุม # ตัวแล้ว}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"นำออกแล้ว"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"เพิ่ม <xliff:g id="APPNAME">%s</xliff:g> ไหม"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"นำการควบคุมสำหรับ <xliff:g id="APPNAME">%s</xliff:g> ออกไหม"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"ตั้งเป็นรายการโปรดแล้ว"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"แสดงและควบคุมอุปกรณ์จากหน้าจอล็อกไหม"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"คุณเพิ่มการควบคุมอุปกรณ์ภายนอกลงในหน้าจอล็อกได้\n\nแอปของอุปกรณ์อาจอนุญาตให้คุณควบคุมอุปกรณ์บางอย่างได้โดยไม่ต้องปลดล็อกโทรศัพท์หรือแท็บเล็ต\n\nคุณเปลี่ยนแปลงได้ทุกเมื่อในการตั้งค่า"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"ควบคุมอุปกรณ์จากหน้าจอล็อกไหม"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"คุณควบคุมอุปกรณ์บางอย่างได้โดยไม่ต้องปลดล็อกโทรศัพท์หรือแท็บเล็ต แอปจัดการอุปกรณ์จะระบุอุปกรณ์ที่สามารถควบคุมด้วยวิธีนี้ได้"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"ไม่เป็นไร"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"มี"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN ประกอบด้วยตัวอักษรหรือสัญลักษณ์"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index d8a9f3e..6326a97 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"I-magnify ang buong screen"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"I-magnify ang isang bahagi ng screen"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Switch"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Buksan ang mga setting ng pag-magnify"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"I-drag ang sulok para i-resize"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Payagan ang diagonal na pag-scroll"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"I-resize"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Handle sa kaliwa"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Handle sa kanan"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Handle sa ibaba"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Mga setting ng pag-magnify"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Laki ng magnifier"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Katamtaman"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Nagdagdag ng # kontrol.}one{Nagdagdag ng # kontrol.}other{Nagdagdag ng # na kontrol.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Inalis"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Idagdag ang <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Alisin ang mga kontrol para sa <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Ginawang paborito"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Ipakita at kontrolin ang mga device mula sa lock screen?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Puwede kang magdagdag ng mga kontrol para sa iyong mga external device sa lock screen.\n\nPosibleng payagan ka ng app ng iyong device na kontrolin ang ilang device nang hindi ina-unlock ang telepono o tablet mo.\n\nPuwede kang magsagawa ng mga pagbabago anumang oras sa Mga Setting."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Kontrolin ang mga device mula sa lock screen?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Puwede mong kontrolin ang ilang device nang hindi ina-unlock ang iyong telepono o tablet. Nakadepende sa app ng iyong device kung aling mga device ang puwedeng kontrolin sa ganitong paraan."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Huwag na lang"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Oo"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"May mga titik o simbolo ang PIN"</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index baacde08..5236912 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Tam ekran büyütme"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekranın bir parçasını büyütün"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Geç"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Büyütme ayarlarını aç"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Yeniden boyutlandırmak için köşeyi sürükleyin"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Çapraz kaydırmaya izin ver"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Yeniden boyutlandır"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Sol tutma yeri"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Sağ tutma yeri"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Alt tutma yeri"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Büyütme ayarları"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Büyüteç boyutu"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Zoom"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Orta"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# kontrol eklendi.}other{# kontrol eklendi.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Kaldırıldı"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> eklensin mi?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> için denetimler kaldırılsın mı?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Favoriler listesine eklendi"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Cihazlar kilit ekranında gösterilip buradan kontrol edilsin mi?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Kilit ekranına harici cihazlarınız için kontroller ekleyebilirsiniz.\n\nCihaz uygulamanız, bazı cihazları telefonunuzun veya tabletinizin kilidini açmadan kontrol etmenize izin verebilir.\n\nAyarlar\'da istediğiniz zaman değişiklik yapabilirsiniz."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Cihazlar kilit ekranından kontrol edilsin mi?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Bazı cihazları telefonunuzun veya tabletinizin kilidini açmadan kontrol edebilirsiniz.Hangi cihazların bu şekilde kontrol edilebileceğini cihaz uygulamanız belirler."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Hayır, teşekkürler"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Evet"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN, harf veya simge içerir"</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 6c25d7c..b63b396 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Збільшення всього екрана"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Збільшити частину екрана"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Перемкнути"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Відкрити налаштування збільшення"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Потягніть кут, щоб змінити розмір"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Дозволити прокручування по діагоналі"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Змінити розмір"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Лівий маркер"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Правий маркер"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Нижній маркер"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Налаштування збільшення"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Розмір лупи"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Масштаб"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Звичайна"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Додано # елемент керування.}one{Додано # елемент керування.}few{Додано # елементи керування.}many{Додано # елементів керування.}other{Додано # елемента керування.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Вилучено"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Долучити додаток <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Вилучити елементи керування для додатка <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Додано у вибране"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Переглядати пристрої та керувати ними на заблокованому екрані?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Елементи керування зовнішніми пристроями можна додавати на заблокований екран.\n\nЗа допомогою спеціального додатка ви можете керувати деякими пристроями, не розблоковуючи телефон або планшет.\n\nВи можете будь-коли вносити зміни в налаштуваннях."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Керувати пристроями на заблокованому екрані?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Ви можете керувати деякими пристроями, не розблоковуючи телефон або планшет. Якими пристроями можна керувати в такий спосіб, визначає додаток пристрою."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Ні, дякую"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Так"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN-код містить літери чи символи"</string>
diff --git a/packages/SystemUI/res/values-ur/strings.xml b/packages/SystemUI/res/values-ur/strings.xml
index 660fd6d..7b98a2e 100644
--- a/packages/SystemUI/res/values-ur/strings.xml
+++ b/packages/SystemUI/res/values-ur/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB پورٹ فعال کریں"</string>
<string name="learn_more" msgid="4690632085667273811">"مزید جانیں"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"اسکرین شاٹ"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"اَن لاک کی توسیع کو غیر فعال کیا گیا"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"ایک تصویر بھیجی"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"اسکرین شاٹ محفوظ ہو رہا ہے…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"اسکرین شاٹ دفتری پروفائل میں محفوظ کیا جا رہا ہے…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"فُل اسکرین کو بڑا کریں"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"اسکرین کا حصہ بڑا کریں"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"سوئچ کریں"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"میگنیفکیشن کی ترتیبات کھولیں"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"سائز تبدیل کرنے کے لیے کونے کو گھسیٹیں"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"وتری سکرولنگ کی اجازت دیں"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"سائز تبدیل کریں"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"بایاں ہینڈل"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"دایاں ہینڈل"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"نیچے کا ہینڈل"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"میگنیفکیشن کی ترتیبات"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"میگنیفائر کا سائز"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"زوم کریں"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"متوسط"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# کنٹرول کو شامل کیا گیا۔}other{# کنٹرولز کو شامل کیا گیا۔}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"ہٹا دیا گیا"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> کو شامل کریں؟"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> کے کنٹرولز کو ہٹا دیں؟"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"پسند کردہ"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"لاک اسکرین سے آلات دکھائیں اور کنٹرول کریں؟"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"آپ اپنے بیرونی آلات کے لیے لاک اسکرین پر کنٹرولز شامل کر سکتے ہیں۔\n\nآپ کے آلے کی ایپ آپ کو اپنے فون یا ٹیبلیٹ کو غیر مقفل کیے بغیر کچھ آلات کو کنٹرول کرنے کی اجازت دے سکتی ہے۔\n\nآپ ترتیبات میں کسی بھی وقت تبدیلیاں کر سکتے ہیں۔"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"لاک اسکرین سے آلات کو کنٹرول کریں؟"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"آپ اپنے فون یا ٹیبلیٹ کو غیر مقفل کیے بغیر کچھ آلات کو کنٹرول کر سکتے ہیں۔ آپ کے آلے کی ایپ اس بات کا تعین کرتی ہے کہ اس طرح کن آلات کو کنٹرول کیا جا سکتا ہے۔"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"نہیں شکریہ"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"ہاں"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN میں حروف یا علامات شامل ہیں"</string>
diff --git a/packages/SystemUI/res/values-uz/strings.xml b/packages/SystemUI/res/values-uz/strings.xml
index 31e3ce6..15472f5 100644
--- a/packages/SystemUI/res/values-uz/strings.xml
+++ b/packages/SystemUI/res/values-uz/strings.xml
@@ -69,8 +69,7 @@
<string name="usb_disable_contaminant_detection" msgid="3827082183595978641">"USB xususiyatini yoqish"</string>
<string name="learn_more" msgid="4690632085667273811">"Batafsil"</string>
<string name="global_action_screenshot" msgid="2760267567509131654">"Skrinshot"</string>
- <!-- no translation found for global_action_smart_lock_disabled (6286551337177954859) -->
- <skip />
+ <string name="global_action_smart_lock_disabled" msgid="6286551337177954859">"Kengaytirilgan ochish yoniq emas"</string>
<string name="remote_input_image_insertion_text" msgid="4850791636452521123">"rasm yuborildi"</string>
<string name="screenshot_saving_title" msgid="2298349784913287333">"Skrinshot saqlanmoqda…"</string>
<string name="screenshot_saving_work_profile_title" msgid="5332829607308450880">"Skrinshot ish profiliga saqlanmoqda…"</string>
@@ -834,8 +833,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Ekranni toʻliq kattalashtirish"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Ekran qismini kattalashtirish"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Almashtirish"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Kattalashtirish sozlamalarini ochish"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Oʻlchamini oʻzgartirish uchun burchakni torting"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Diagonal aylantirishga ruxsat berish"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Oʻlchamini oʻzgartirish"</string>
@@ -845,8 +843,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Chap slayder"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Oʻng slayder"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Quyi slayder"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Kattalashtirish sozlamalari"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Lupa oʻlchami"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Masshtab"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Oʻrtacha"</string>
@@ -873,7 +870,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{# ta boshqaruv elementi kiritildi.}other{# ta boshqaruv elementi kiritildi.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Olib tashlandi"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"<xliff:g id="APPNAME">%s</xliff:g> qoʻshilsinmi?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"<xliff:g id="APPNAME">%s</xliff:g> qurilma boshqaruv panelidan olib tashlansinmi?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Saralanganlarga kiritilgan"</string>
@@ -899,8 +896,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Qurilmalar qulflangan ekranda koʻrsatilsinmi va boshqarilsinmi?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Tashqi qurilmalaringiz uchun ekran qulfiga boshqaruvlarni qoʻshishingiz mumkin.\n\nQurilma ilovasi ayrim qurilmalarni telefon yoki planshet qulfini ochmasdan boshqarish imkonini beradi.\n\nIstalgan vaqtda Sozlamalar orqali oʻzgartirish mumkin."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Qurilmalar ekran qulfidan boshqarilsinmi?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Ayrim qurilmalarni telefon yoki planshet ekran qulfini ochmasdan boshqarish mumkin. Qurilmangiz ilovasi qaysi qurilmalarni shu tarzda boshqarish mumkinligini aniqlaydi."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Yopish"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Ha"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Harflar yoki maxsus belgilardan iborat PIN kod"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 53adea1..9e2d450 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Phóng to toàn màn hình"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Phóng to một phần màn hình"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Chuyển"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Mở chế độ cài đặt phóng to"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Kéo góc để thay đổi kích thước"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Cho phép cuộn chéo"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Đổi kích thước"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Ô điều khiển bên trái"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Ô điều khiển bên phải"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Ô điều khiển dưới cùng"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Chế độ cài đặt phóng to"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Kích thước phóng to"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Thu phóng"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Vừa"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{Đã thêm # chế độ điều khiển.}other{Đã thêm # chế độ điều khiển.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Đã xóa"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Thêm <xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Xoá chế độ cài đặt cho <xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Được yêu thích"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Bạn muốn hiện và điều khiển các thiết bị từ màn hình khoá?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Bạn có thể thêm các chế độ điều khiển cho những thiết bị bên ngoài vào màn hình khoá.\n\nỨng dụng thiết bị có thể cho phép bạn điều khiển một số thiết bị mà không cần mở khoá điện thoại hoặc máy tính bảng.\n\nBạn có thể thay đổi chế độ cài đặt này bất cứ lúc nào trong phần Cài đặt."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Bạn muốn điều khiển các thiết bị từ màn hình khoá?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Bạn có thể điều khiển một số thiết bị mà không cần mở khoá điện thoại hoặc máy tính bảng. Ứng dụng thiết lập và quản lý thiết bị phụ sẽ xác định thiết bị mà bạn có thể điều khiển bằng cách này."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Không, cảm ơn"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Có"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Mã PIN chứa các ký tự hoặc ký hiệu"</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index e764a74..6b0e5d2 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整个屏幕"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分屏幕"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"切换"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"打开放大功能设置"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"拖动一角即可调整大小"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"允许沿对角线滚动"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"调整大小"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"左侧手柄"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"右侧手柄"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"底部手柄"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"放大功能设置"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"放大镜大小"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"缩放"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"中"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已添加 # 个控件。}other{已添加 # 个控件。}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"添加“<xliff:g id="APPNAME">%s</xliff:g>”?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"移除<xliff:g id="APPNAME">%s</xliff:g>的控件?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"已收藏"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"要从锁定屏幕上显示和控制设备吗?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"您可以在锁定屏幕上添加用于控制外部设备的控件。\n\n您的设备应用可能会允许您在不解锁手机或平板电脑的情况下控制某些设备。\n\n您可以随时在“设置”中进行更改。"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"要从锁定屏幕上控制设备吗?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"您可以在不解锁手机或平板电脑的情况下控制某些设备。您的设备配套应用将决定哪些设备可以通过这种方式进行控制。"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"不用了"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"是"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 码由字母或符号组成"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index 187a4a5..d83891f 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大成個畫面"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大部分螢幕畫面"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"切換"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"開啟放大設定"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"拖曳角落即可調整大小"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"允許斜角捲動"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"調整大小"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"左控點"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"右控點"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"底部控點"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"放大設定"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"放大鏡大小"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"縮放"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"中"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已新增 # 個控制項。}other{已新增 # 個控制項。}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"要新增「<xliff:g id="APPNAME">%s</xliff:g>」嗎?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"要移除「<xliff:g id="APPNAME">%s</xliff:g>」的控制項嗎?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"要從上鎖畫面查看及控制裝置嗎?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"您可以在上鎖畫面新增外部裝置的控制項。\n\n裝置應用程式可能會讓您在不解鎖手機或平板電腦的情況下控制部分裝置。\n\n您可隨時在「設定」中作出變更。"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"要在上鎖畫面控制裝置嗎?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"您可以在不解鎖手機或平板電腦的情況下控制部分裝置。裝置應用程式決定哪些裝置可透過此方式控制。"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"不用了,謝謝"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"是"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 含有字母或符號"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index c2527c6..f50955e 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"放大整個螢幕畫面"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"放大局部螢幕畫面"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"切換"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"開啟放大功能設定"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"拖曳角落即可調整大小"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"允許沿對角線捲動"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"調整大小"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"左側控點"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"右側控點"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"底部控點"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"放大功能設定"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"放大鏡大小"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"縮放"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"中"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{已新增 # 個控制項。}other{已新增 # 個控制項。}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"已移除"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"要新增「<xliff:g id="APPNAME">%s</xliff:g>」嗎?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"要移除「<xliff:g id="APPNAME">%s</xliff:g>」的控制嗎?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"已加入收藏"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"要在螢幕鎖定畫面上查看及控制裝置嗎?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"你可以在螢幕鎖定畫面上新增外部裝置的控制選項。\n\n你或許可透過裝置應用程式控制某些裝置,而不必解鎖手機或平板電腦。\n\n你隨時可以前往「設定」進行變更。"</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"要在螢幕鎖定畫面上控制裝置嗎?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"你可以直接控制某些裝置,不必解鎖手機或平板電腦。裝置應用程式會判斷可透過這種方式控制的裝置。"</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"不用了,謝謝"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"是"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"PIN 碼含有字母或符號"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 0dd4111a5..d3b1646 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -834,8 +834,7 @@
<string name="magnification_mode_switch_state_full_screen" msgid="5229653514979530561">"Khulisa isikrini esigcwele"</string>
<string name="magnification_mode_switch_state_window" msgid="8597100249594076965">"Khulisa ingxenye eyesikrini"</string>
<string name="magnification_mode_switch_click_label" msgid="2786203505805898199">"Iswishi"</string>
- <!-- no translation found for magnification_open_settings_click_label (6151849212725923363) -->
- <skip />
+ <string name="magnification_open_settings_click_label" msgid="6151849212725923363">"Vula amasethingi okukhuliswa"</string>
<string name="magnification_drag_corner_to_resize" msgid="1249766311052418130">"Hudula ikhona ukuze usayize kabusha"</string>
<string name="accessibility_allow_diagonal_scrolling" msgid="3258050349191496398">"Vumela ukuskrola oku-diagonal"</string>
<string name="accessibility_resize" msgid="5733759136600611551">"Shintsha usayizi"</string>
@@ -845,8 +844,7 @@
<string name="accessibility_magnification_left_handle" msgid="6694953733271752950">"Isibambi sangakwesokunxele"</string>
<string name="accessibility_magnification_right_handle" msgid="9055988237319397605">"Isibambi esingakwesokudla"</string>
<string name="accessibility_magnification_bottom_handle" msgid="6531646968813821258">"Isibambi esingezansi"</string>
- <!-- no translation found for accessibility_magnification_settings_panel_description (8174187340747846953) -->
- <skip />
+ <string name="accessibility_magnification_settings_panel_description" msgid="8174187340747846953">"Amasethingi okukhuliswa"</string>
<string name="accessibility_magnifier_size" msgid="3038755600030422334">"Usayizi wesikhulisi"</string>
<string name="accessibility_magnification_zoom" msgid="4222088982642063979">"Sondeza"</string>
<string name="accessibility_magnification_medium" msgid="6994632616884562625">"Kumaphakathi"</string>
@@ -873,7 +871,7 @@
<string name="controls_number_of_favorites" msgid="4481806788981836355">"{count,plural, =1{ulawulo olu-# olwengeziwe.}one{ukulawulwa okungu-# okwengeziwe.}other{ukulawulwa okungu-# okwengeziwe.}}"</string>
<string name="controls_removed" msgid="3731789252222856959">"Isusiwe"</string>
<string name="controls_panel_authorization_title" msgid="267429338785864842">"Engeza i-<xliff:g id="APPNAME">%s</xliff:g>?"</string>
- <!-- no translation found for controls_panel_authorization (4665218066461350247) -->
+ <!-- no translation found for controls_panel_authorization (7045551688535104194) -->
<skip />
<string name="controls_panel_remove_app_authorization" msgid="5920442084735364674">"Susa izilawuli ze-<xliff:g id="APPNAME">%s</xliff:g>?"</string>
<string name="accessibility_control_favorite" msgid="8694362691985545985">"Kwenziwe intandokazi"</string>
@@ -899,8 +897,7 @@
<string name="controls_settings_show_controls_dialog_title" msgid="3357852503553809554">"Bonisa futhi ulawule amadivayisi ekukhiyeni isikrini?"</string>
<string name="controls_settings_show_controls_dialog_message" msgid="7666211700524587969">"Ungakwazi ukwengeza izilawuli zamadivayisi wakho angaphandle ekukhiyeni isikrini.\n\nI-app yakho yedivayisi ingakuvumela ukuthi ulawule amanye amadivayisi ngaphandle kokuvula ifoni noma ithebulethi yakho.\n\nUngenza izinguquko nganoma yisiphi isikhathi Kumasethingi."</string>
<string name="controls_settings_trivial_controls_dialog_title" msgid="7593188157655036677">"Lawula amadivayisi ekukhiyeni isikrini?"</string>
- <!-- no translation found for controls_settings_trivial_controls_dialog_message (397178734990952575) -->
- <skip />
+ <string name="controls_settings_trivial_controls_dialog_message" msgid="397178734990952575">"Ungalawula amanye amadivayisi ngaphandle kokuvula ifoni noma ithebulethi yakho. I-app yakho yedivayisi inquma ukuthi imaphi amadivayisi angalawulwa ngale ndlela."</string>
<string name="controls_settings_dialog_neutral_button" msgid="4514446354793124140">"Cha ngiyabonga"</string>
<string name="controls_settings_dialog_positive_button" msgid="436070672551674863">"Yebo"</string>
<string name="controls_pin_use_alphanumeric" msgid="8478371861023048414">"Iphinikhodi iqukethe amaletha namasimbui"</string>
diff --git a/packages/SystemUI/res/values/colors.xml b/packages/SystemUI/res/values/colors.xml
index 62e8c5f..31071ca 100644
--- a/packages/SystemUI/res/values/colors.xml
+++ b/packages/SystemUI/res/values/colors.xml
@@ -231,6 +231,9 @@
<color name="people_tile_background">@color/material_dynamic_secondary95</color>
+ <!-- Chipbar -->
+ <color name="chipbar_text_and_icon_color">@android:color/system_accent2_900</color>
+
<!-- Internet Dialog -->
<!-- Material next state on color-->
<color name="settingslib_state_on_color">@color/settingslib_state_on</color>
diff --git a/packages/SystemUI/res/values/config.xml b/packages/SystemUI/res/values/config.xml
index e5cd0c5..082f385 100644
--- a/packages/SystemUI/res/values/config.xml
+++ b/packages/SystemUI/res/values/config.xml
@@ -99,6 +99,7 @@
<item>accessibility_display_daltonizer_enabled:color_correction</item>
<item>accessibility_display_inversion_enabled:inversion</item>
<item>one_handed_mode_enabled:onehanded</item>
+ <item>accessibility_font_scaling_has_been_changed:font_scaling</item>
</string-array>
<!-- Use collapsed layout for media player in landscape QQS -->
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 4d38541..ff86c59 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -43,8 +43,6 @@
<dimen name="navigation_edge_panel_height">268dp</dimen>
<!-- The threshold to drag to trigger the edge action -->
<dimen name="navigation_edge_action_drag_threshold">16dp</dimen>
- <!-- The drag distance to consider evaluating gesture -->
- <dimen name="navigation_edge_action_min_distance_to_start_animation">24dp</dimen>
<!-- The threshold to progress back animation for edge swipe -->
<dimen name="navigation_edge_action_progress_threshold">412dp</dimen>
<!-- The minimum display position of the arrow on the screen -->
@@ -58,8 +56,6 @@
<!-- The thickness of the arrow -->
<dimen name="navigation_edge_arrow_thickness">4dp</dimen>
- <!-- The minimum delta needed to change direction / stop triggering back -->
- <dimen name="navigation_edge_minimum_x_delta_for_switch">32dp</dimen>
<!-- entry state -->
<item name="navigation_edge_entry_scale" format="float" type="dimen">0.98</item>
@@ -1099,6 +1095,7 @@
<!-- Size of Smartspace media recommendations cards in the QSPanel carousel -->
<dimen name="qs_media_rec_icon_top_margin">16dp</dimen>
+ <dimen name="qs_media_rec_album_icon_size">16dp</dimen>
<dimen name="qs_media_rec_album_size">88dp</dimen>
<dimen name="qs_media_rec_album_width">110dp</dimen>
<dimen name="qs_media_rec_album_height_expanded">108dp</dimen>
@@ -1636,7 +1633,6 @@
<dimen name="dream_overlay_bottom_affordance_padding">14dp</dimen>
<dimen name="dream_overlay_complication_clock_time_text_size">86dp</dimen>
<dimen name="dream_overlay_complication_clock_time_translation_y">28dp</dimen>
- <dimen name="dream_overlay_complication_home_controls_padding">28dp</dimen>
<dimen name="dream_overlay_complication_clock_subtitle_text_size">24sp</dimen>
<dimen name="dream_overlay_complication_preview_text_size">36sp</dimen>
<dimen name="dream_overlay_complication_preview_icon_padding">28dp</dimen>
diff --git a/packages/SystemUI/res/values/strings.xml b/packages/SystemUI/res/values/strings.xml
index a02c429..2aa912c 100644
--- a/packages/SystemUI/res/values/strings.xml
+++ b/packages/SystemUI/res/values/strings.xml
@@ -2431,7 +2431,7 @@
<!-- Shows in a dialog presented to the user to authorize this app to display a Device controls
panel (embedded activity) instead of controls rendered by SystemUI [CHAR LIMIT=NONE] -->
- <string name="controls_panel_authorization"><xliff:g id="appName" example="My app">%s</xliff:g>can choose which controls and content show here.</string>
+ <string name="controls_panel_authorization"><xliff:g id="appName" example="My app">%s</xliff:g> can choose which controls and content show here.</string>
<!-- Shows in a dialog presented to the user to authorize this app removal from a Device
controls panel [CHAR LIMIT=NONE] -->
@@ -2877,7 +2877,7 @@
<string name="manage_users">Manage users</string>
<!-- Toast shown when a notification does not support dragging to split [CHAR LIMIT=NONE] -->
- <string name="drag_split_not_supported">This notification does not support dragging to Splitscreen.</string>
+ <string name="drag_split_not_supported">This notification does not support dragging to split screen</string>
<!-- Content description for the Wi-Fi off icon in the dream overlay status bar [CHAR LIMIT=NONE] -->
<string name="dream_overlay_status_bar_wifi_off">Wi\u2011Fi unavailable</string>
diff --git a/packages/SystemUI/res/values/styles.xml b/packages/SystemUI/res/values/styles.xml
index 6596ed2..2fb1592 100644
--- a/packages/SystemUI/res/values/styles.xml
+++ b/packages/SystemUI/res/values/styles.xml
@@ -695,6 +695,8 @@
<style name="MediaPlayer.Recommendation.AlbumContainer.Updated">
<item name="android:layout_width">@dimen/qs_media_rec_album_width</item>
+ <item name="android:minWidth">@dimen/qs_media_rec_album_width</item>
+ <item name="android:minHeight">@dimen/qs_media_rec_album_height_collapsed</item>
<item name="android:background">@drawable/qs_media_light_source</item>
<item name="android:layout_marginTop">@dimen/qs_media_info_spacing</item>
</style>
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt
index 9766514..dedf0a7 100644
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewCapture.kt
@@ -53,6 +53,7 @@
fun View.captureToBitmap(window: Window? = null): ListenableFuture<Bitmap> {
val bitmapFuture: ResolvableFuture<Bitmap> = ResolvableFuture.create()
val mainExecutor = HandlerExecutor(Handler(Looper.getMainLooper()))
+ val isRobolectric = if (Build.FINGERPRINT.contains("robolectric")) true else false
// disable drawing again if necessary once work is complete
if (!HardwareRendererCompat.isDrawingEnabled()) {
@@ -61,8 +62,12 @@
}
mainExecutor.execute {
- val forceRedrawFuture = forceRedraw()
- forceRedrawFuture.addListener({ generateBitmap(bitmapFuture, window) }, mainExecutor)
+ if (isRobolectric) {
+ generateBitmap(bitmapFuture)
+ } else {
+ val forceRedrawFuture = forceRedraw()
+ forceRedrawFuture.addListener({ generateBitmap(bitmapFuture, window) }, mainExecutor)
+ }
}
return bitmapFuture
diff --git a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
index 2d47356..f96d1e3 100644
--- a/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
+++ b/packages/SystemUI/screenshot/src/com/android/systemui/testing/screenshot/ViewScreenshotTestRule.kt
@@ -19,6 +19,7 @@
import android.app.Activity
import android.app.Dialog
import android.graphics.Bitmap
+import android.os.Build
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.LayoutParams
@@ -26,6 +27,7 @@
import android.view.ViewGroup.LayoutParams.WRAP_CONTENT
import androidx.activity.ComponentActivity
import androidx.test.ext.junit.rules.ActivityScenarioRule
+import java.util.concurrent.TimeUnit
import org.junit.Assert.assertEquals
import org.junit.rules.RuleChain
import org.junit.rules.TestRule
@@ -54,14 +56,14 @@
)
)
private val activityRule = ActivityScenarioRule(ScreenshotActivity::class.java)
- private val delegateRule =
- RuleChain.outerRule(colorsRule)
- .around(deviceEmulationRule)
- .around(screenshotRule)
- .around(activityRule)
+ private val roboRule =
+ RuleChain.outerRule(deviceEmulationRule).around(screenshotRule).around(activityRule)
+ private val delegateRule = RuleChain.outerRule(colorsRule).around(roboRule)
+ private val isRobolectric = if (Build.FINGERPRINT.contains("robolectric")) true else false
override fun apply(base: Statement, description: Description): Statement {
- return delegateRule.apply(base, description)
+ val ruleToApply = if (isRobolectric) roboRule else delegateRule
+ return ruleToApply.apply(base, description)
}
protected fun takeScreenshot(
@@ -94,7 +96,12 @@
contentView = content.getChildAt(0)
}
- return contentView?.toBitmap() ?: error("contentView is null")
+ return if (isRobolectric) {
+ contentView?.captureToBitmap()?.get(10, TimeUnit.SECONDS)
+ ?: error("timeout while trying to capture view to bitmap")
+ } else {
+ contentView?.toBitmap() ?: error("contentView is null")
+ }
}
/**
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt b/packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
index 3efdc5a..4931b25 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimator.kt
@@ -192,4 +192,4 @@
)
}
-private const val TRANSLATION_PERCENTAGE = 0.3f
+private const val TRANSLATION_PERCENTAGE = 0.08f
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java
index cc3d7a8..3d05542 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginActionManager.java
@@ -210,12 +210,12 @@
private void onPluginConnected(PluginInstance<T> pluginInstance) {
if (DEBUG) Log.d(TAG, "onPluginConnected");
PluginPrefs.setHasPlugins(mContext);
- pluginInstance.onCreate(mContext, mListener);
+ pluginInstance.onCreate();
}
private void onPluginDisconnected(PluginInstance<T> pluginInstance) {
if (DEBUG) Log.d(TAG, "onPluginDisconnected");
- pluginInstance.onDestroy(mListener);
+ pluginInstance.onDestroy();
}
private void queryAll() {
@@ -312,7 +312,7 @@
try {
return mPluginInstanceFactory.create(
mContext, appInfo, component,
- mPluginClass);
+ mPluginClass, mListener);
} catch (InvalidVersionException e) {
reportInvalidVersion(component, component.getClassName(), e);
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
index 2f84602..016d573 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/plugins/PluginInstance.java
@@ -21,13 +21,16 @@
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManager.NameNotFoundException;
import android.text.TextUtils;
-import android.util.ArrayMap;
import android.util.Log;
+import androidx.annotation.Nullable;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.plugins.Plugin;
import com.android.systemui.plugins.PluginFragment;
+import com.android.systemui.plugins.PluginLifecycleManager;
import com.android.systemui.plugins.PluginListener;
import dalvik.system.PathClassLoader;
@@ -35,7 +38,7 @@
import java.io.File;
import java.util.ArrayList;
import java.util.List;
-import java.util.Map;
+import java.util.function.Supplier;
/**
* Contains a single instantiation of a Plugin.
@@ -45,42 +48,102 @@
*
* @param <T> The type of plugin that this contains.
*/
-public class PluginInstance<T extends Plugin> {
+public class PluginInstance<T extends Plugin> implements PluginLifecycleManager {
private static final String TAG = "PluginInstance";
- private static final Map<String, ClassLoader> sClassLoaders = new ArrayMap<>();
- private final Context mPluginContext;
- private final VersionInfo mVersionInfo;
+ private final Context mAppContext;
+ private final PluginListener<T> mListener;
private final ComponentName mComponentName;
- private final T mPlugin;
+ private final PluginFactory<T> mPluginFactory;
+
+ private Context mPluginContext;
+ private T mPlugin;
/** */
- public PluginInstance(ComponentName componentName, T plugin, Context pluginContext,
- VersionInfo versionInfo) {
+ public PluginInstance(
+ Context appContext,
+ PluginListener<T> listener,
+ ComponentName componentName,
+ PluginFactory<T> pluginFactory,
+ @Nullable T plugin) {
+ mAppContext = appContext;
+ mListener = listener;
mComponentName = componentName;
+ mPluginFactory = pluginFactory;
mPlugin = plugin;
- mPluginContext = pluginContext;
- mVersionInfo = versionInfo;
+
+ if (mPlugin != null) {
+ mPluginContext = mPluginFactory.createPluginContext();
+ }
}
/** Alerts listener and plugin that the plugin has been created. */
- public void onCreate(Context appContext, PluginListener<T> listener) {
- if (!(mPlugin instanceof PluginFragment)) {
- // Only call onCreate for plugins that aren't fragments, as fragments
- // will get the onCreate as part of the fragment lifecycle.
- mPlugin.onCreate(appContext, mPluginContext);
+ public void onCreate() {
+ mListener.onPluginAttached(this);
+ if (mPlugin == null) {
+ loadPlugin();
+ } else {
+ if (!(mPlugin instanceof PluginFragment)) {
+ // Only call onCreate for plugins that aren't fragments, as fragments
+ // will get the onCreate as part of the fragment lifecycle.
+ mPlugin.onCreate(mAppContext, mPluginContext);
+ }
+ mListener.onPluginLoaded(mPlugin, mPluginContext, this);
}
- listener.onPluginConnected(mPlugin, mPluginContext);
}
/** Alerts listener and plugin that the plugin is being shutdown. */
- public void onDestroy(PluginListener<T> listener) {
- listener.onPluginDisconnected(mPlugin);
+ public void onDestroy() {
+ unloadPlugin();
+ mListener.onPluginDetached(this);
+ }
+
+ /** Returns the current plugin instance (if it is loaded). */
+ @Nullable
+ public T getPlugin() {
+ return mPlugin;
+ }
+
+ /**
+ * Loads and creates the plugin if it does not exist.
+ */
+ public void loadPlugin() {
+ if (mPlugin != null) {
+ return;
+ }
+
+ mPlugin = mPluginFactory.createPlugin();
+ mPluginContext = mPluginFactory.createPluginContext();
+ if (mPlugin == null || mPluginContext == null) {
+ return;
+ }
+
+ if (!(mPlugin instanceof PluginFragment)) {
+ // Only call onCreate for plugins that aren't fragments, as fragments
+ // will get the onCreate as part of the fragment lifecycle.
+ mPlugin.onCreate(mAppContext, mPluginContext);
+ }
+ mListener.onPluginLoaded(mPlugin, mPluginContext, this);
+ }
+
+ /**
+ * Unloads and destroys the current plugin instance if it exists.
+ *
+ * This will free the associated memory if there are not other references.
+ */
+ public void unloadPlugin() {
+ if (mPlugin == null) {
+ return;
+ }
+
+ mListener.onPluginUnloaded(mPlugin, this);
if (!(mPlugin instanceof PluginFragment)) {
// Only call onDestroy for plugins that aren't fragments, as fragments
// will get the onDestroy as part of the fragment lifecycle.
mPlugin.onDestroy();
}
+ mPlugin = null;
+ mPluginContext = null;
}
/**
@@ -89,7 +152,7 @@
* It does this by string comparison of the class names.
**/
public boolean containsPluginClass(Class pluginClass) {
- return mPlugin.getClass().getName().equals(pluginClass.getName());
+ return mComponentName.getClassName().equals(pluginClass.getName());
}
public ComponentName getComponentName() {
@@ -101,7 +164,7 @@
}
public VersionInfo getVersionInfo() {
- return mVersionInfo;
+ return mPluginFactory.checkVersion(mPlugin);
}
@VisibleForTesting
@@ -134,21 +197,20 @@
Context context,
ApplicationInfo appInfo,
ComponentName componentName,
- Class<T> pluginClass)
+ Class<T> pluginClass,
+ PluginListener<T> listener)
throws PackageManager.NameNotFoundException, ClassNotFoundException,
InstantiationException, IllegalAccessException {
- ClassLoader classLoader = getClassLoader(appInfo, mBaseClassLoader);
- Context pluginContext = new PluginActionManager.PluginContextWrapper(
- context.createApplicationContext(appInfo, 0), classLoader);
- Class<T> instanceClass = (Class<T>) Class.forName(
- componentName.getClassName(), true, classLoader);
+ PluginFactory<T> pluginFactory = new PluginFactory<T>(
+ context, mInstanceFactory, appInfo, componentName, mVersionChecker, pluginClass,
+ () -> getClassLoader(appInfo, mBaseClassLoader));
// TODO: Only create the plugin before version check if we need it for
// legacy version check.
- T instance = (T) mInstanceFactory.create(instanceClass);
- VersionInfo version = mVersionChecker.checkVersion(
- instanceClass, pluginClass, instance);
- return new PluginInstance<T>(componentName, instance, pluginContext, version);
+ T instance = pluginFactory.createPlugin();
+ pluginFactory.checkVersion(instance);
+ return new PluginInstance<T>(
+ context, listener, componentName, pluginFactory, instance);
}
private boolean isPluginPackagePrivileged(String packageName) {
@@ -179,9 +241,6 @@
+ appInfo.sourceDir + ", pkg: " + appInfo.packageName);
return null;
}
- if (sClassLoaders.containsKey(appInfo.packageName)) {
- return sClassLoaders.get(appInfo.packageName);
- }
List<String> zipPaths = new ArrayList<>();
List<String> libPaths = new ArrayList<>();
@@ -190,13 +249,20 @@
TextUtils.join(File.pathSeparator, zipPaths),
TextUtils.join(File.pathSeparator, libPaths),
getParentClassLoader(baseClassLoader));
- sClassLoaders.put(appInfo.packageName, classLoader);
return classLoader;
}
}
/** Class that compares a plugin class against an implementation for version matching. */
- public static class VersionChecker {
+ public interface VersionChecker {
+ /** Compares two plugin classes. */
+ <T extends Plugin> VersionInfo checkVersion(
+ Class<T> instanceClass, Class<T> pluginClass, Plugin plugin);
+ }
+
+ /** Class that compares a plugin class against an implementation for version matching. */
+ public static class VersionCheckerImpl implements VersionChecker {
+ @Override
/** Compares two plugin classes. */
public <T extends Plugin> VersionInfo checkVersion(
Class<T> instanceClass, Class<T> pluginClass, Plugin plugin) {
@@ -204,7 +270,7 @@
VersionInfo instanceVersion = new VersionInfo().addClass(instanceClass);
if (instanceVersion.hasVersionInfo()) {
pluginVersion.checkVersion(instanceVersion);
- } else {
+ } else if (plugin != null) {
int fallbackVersion = plugin.getVersion();
if (fallbackVersion != pluginVersion.getDefaultVersion()) {
throw new VersionInfo.InvalidVersionException("Invalid legacy version", false);
@@ -225,4 +291,74 @@
return (T) cls.newInstance();
}
}
+
+ /**
+ * Instanced wrapper of InstanceFactory
+ *
+ * @param <T> is the type of the plugin object to be built
+ **/
+ public static class PluginFactory<T extends Plugin> {
+ private final Context mContext;
+ private final InstanceFactory<?> mInstanceFactory;
+ private final ApplicationInfo mAppInfo;
+ private final ComponentName mComponentName;
+ private final VersionChecker mVersionChecker;
+ private final Class<T> mPluginClass;
+ private final Supplier<ClassLoader> mClassLoaderFactory;
+
+ public PluginFactory(
+ Context context,
+ InstanceFactory<?> instanceFactory,
+ ApplicationInfo appInfo,
+ ComponentName componentName,
+ VersionChecker versionChecker,
+ Class<T> pluginClass,
+ Supplier<ClassLoader> classLoaderFactory) {
+ mContext = context;
+ mInstanceFactory = instanceFactory;
+ mAppInfo = appInfo;
+ mComponentName = componentName;
+ mVersionChecker = versionChecker;
+ mPluginClass = pluginClass;
+ mClassLoaderFactory = classLoaderFactory;
+ }
+
+ /** Creates the related plugin object from the factory */
+ public T createPlugin() {
+ try {
+ ClassLoader loader = mClassLoaderFactory.get();
+ Class<T> instanceClass = (Class<T>) Class.forName(
+ mComponentName.getClassName(), true, loader);
+ return (T) mInstanceFactory.create(instanceClass);
+ } catch (ClassNotFoundException ex) {
+ Log.e(TAG, "Failed to load plugin", ex);
+ } catch (IllegalAccessException ex) {
+ Log.e(TAG, "Failed to load plugin", ex);
+ } catch (InstantiationException ex) {
+ Log.e(TAG, "Failed to load plugin", ex);
+ }
+ return null;
+ }
+
+ /** Creates a context wrapper for the plugin */
+ public Context createPluginContext() {
+ try {
+ ClassLoader loader = mClassLoaderFactory.get();
+ return new PluginActionManager.PluginContextWrapper(
+ mContext.createApplicationContext(mAppInfo, 0), loader);
+ } catch (NameNotFoundException ex) {
+ Log.e(TAG, "Failed to create plugin context", ex);
+ }
+ return null;
+ }
+
+ /** Check Version and create VersionInfo for instance */
+ public VersionInfo checkVersion(T instance) {
+ if (instance == null) {
+ instance = createPlugin();
+ }
+ return mVersionChecker.checkVersion(
+ (Class<T>) instance.getClass(), mPluginClass, instance);
+ }
+ }
}
diff --git a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
index 0d36d04..1351314 100644
--- a/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
+++ b/packages/SystemUI/shared/src/com/android/systemui/shared/system/QuickStepContract.java
@@ -177,42 +177,96 @@
public static String getSystemUiStateString(int flags) {
StringJoiner str = new StringJoiner("|");
- str.add((flags & SYSUI_STATE_SCREEN_PINNING) != 0 ? "screen_pinned" : "");
- str.add((flags & SYSUI_STATE_OVERVIEW_DISABLED) != 0 ? "overview_disabled" : "");
- str.add((flags & SYSUI_STATE_HOME_DISABLED) != 0 ? "home_disabled" : "");
- str.add((flags & SYSUI_STATE_SEARCH_DISABLED) != 0 ? "search_disabled" : "");
- str.add((flags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0 ? "navbar_hidden" : "");
- str.add((flags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0 ? "notif_visible" : "");
- str.add((flags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) != 0 ? "qs_visible" : "");
- str.add((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) != 0 ? "keygrd_visible" : "");
- str.add((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0
- ? "keygrd_occluded" : "");
- str.add((flags & SYSUI_STATE_BOUNCER_SHOWING) != 0 ? "bouncer_visible" : "");
- str.add((flags & SYSUI_STATE_DIALOG_SHOWING) != 0 ? "dialog_showing" : "");
- str.add((flags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0 ? "a11y_click" : "");
- str.add((flags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0 ? "a11y_long_click" : "");
- str.add((flags & SYSUI_STATE_TRACING_ENABLED) != 0 ? "tracing" : "");
- str.add((flags & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0
- ? "asst_gesture_constrain" : "");
- str.add((flags & SYSUI_STATE_BUBBLES_EXPANDED) != 0 ? "bubbles_expanded" : "");
- str.add((flags & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0 ? "one_handed_active" : "");
- str.add((flags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0
- ? "allow_gesture" : "");
- str.add((flags & SYSUI_STATE_IME_SHOWING) != 0 ? "ime_visible" : "");
- str.add((flags & SYSUI_STATE_MAGNIFICATION_OVERLAP) != 0 ? "magnification_overlap" : "");
- str.add((flags & SYSUI_STATE_IME_SWITCHER_SHOWING) != 0 ? "ime_switcher_showing" : "");
- str.add((flags & SYSUI_STATE_DEVICE_DOZING) != 0 ? "device_dozing" : "");
- str.add((flags & SYSUI_STATE_BACK_DISABLED) != 0 ? "back_disabled" : "");
- str.add((flags & SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0
- ? "bubbles_mange_menu_expanded" : "");
- str.add((flags & SYSUI_STATE_IMMERSIVE_MODE) != 0 ? "immersive_mode" : "");
- str.add((flags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0 ? "vis_win_showing" : "");
- str.add((flags & SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE) != 0
- ? "freeform_active_in_desktop_mode" : "");
- str.add((flags & SYSUI_STATE_DEVICE_DREAMING) != 0 ? "device_dreaming" : "");
- str.add("screen_"
- + ((flags & SYSUI_STATE_SCREEN_TRANSITION) != 0 ? "turning_" : "")
- + ((flags & SYSUI_STATE_SCREEN_ON) != 0 ? "on" : "off"));
+ if ((flags & SYSUI_STATE_SCREEN_PINNING) != 0) {
+ str.add("screen_pinned");
+ }
+ if ((flags & SYSUI_STATE_OVERVIEW_DISABLED) != 0) {
+ str.add("overview_disabled");
+ }
+ if ((flags & SYSUI_STATE_HOME_DISABLED) != 0) {
+ str.add("home_disabled");
+ }
+ if ((flags & SYSUI_STATE_SEARCH_DISABLED) != 0) {
+ str.add("search_disabled");
+ }
+ if ((flags & SYSUI_STATE_NAV_BAR_HIDDEN) != 0) {
+ str.add("navbar_hidden");
+ }
+ if ((flags & SYSUI_STATE_NOTIFICATION_PANEL_EXPANDED) != 0) {
+ str.add("notif_visible");
+ }
+ if ((flags & SYSUI_STATE_QUICK_SETTINGS_EXPANDED) != 0) {
+ str.add("qs_visible");
+ }
+ if ((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING) != 0) {
+ str.add("keygrd_visible");
+ }
+ if ((flags & SYSUI_STATE_STATUS_BAR_KEYGUARD_SHOWING_OCCLUDED) != 0) {
+ str.add("keygrd_occluded");
+ }
+ if ((flags & SYSUI_STATE_BOUNCER_SHOWING) != 0) {
+ str.add("bouncer_visible");
+ }
+ if ((flags & SYSUI_STATE_DIALOG_SHOWING) != 0) {
+ str.add("dialog_showing");
+ }
+ if ((flags & SYSUI_STATE_A11Y_BUTTON_CLICKABLE) != 0) {
+ str.add("a11y_click");
+ }
+ if ((flags & SYSUI_STATE_A11Y_BUTTON_LONG_CLICKABLE) != 0) {
+ str.add("a11y_long_click");
+ }
+ if ((flags & SYSUI_STATE_TRACING_ENABLED) != 0) {
+ str.add("tracing");
+ }
+ if ((flags & SYSUI_STATE_ASSIST_GESTURE_CONSTRAINED) != 0) {
+ str.add("asst_gesture_constrain");
+ }
+ if ((flags & SYSUI_STATE_BUBBLES_EXPANDED) != 0) {
+ str.add("bubbles_expanded");
+ }
+ if ((flags & SYSUI_STATE_ONE_HANDED_ACTIVE) != 0) {
+ str.add("one_handed_active");
+ }
+ if ((flags & SYSUI_STATE_ALLOW_GESTURE_IGNORING_BAR_VISIBILITY) != 0) {
+ str.add("allow_gesture");
+ }
+ if ((flags & SYSUI_STATE_IME_SHOWING) != 0) {
+ str.add("ime_visible");
+ }
+ if ((flags & SYSUI_STATE_MAGNIFICATION_OVERLAP) != 0) {
+ str.add("magnification_overlap");
+ }
+ if ((flags & SYSUI_STATE_IME_SWITCHER_SHOWING) != 0) {
+ str.add("ime_switcher_showing");
+ }
+ if ((flags & SYSUI_STATE_DEVICE_DOZING) != 0) {
+ str.add("device_dozing");
+ }
+ if ((flags & SYSUI_STATE_BACK_DISABLED) != 0) {
+ str.add("back_disabled");
+ }
+ if ((flags & SYSUI_STATE_BUBBLES_MANAGE_MENU_EXPANDED) != 0) {
+ str.add("bubbles_mange_menu_expanded");
+ }
+ if ((flags & SYSUI_STATE_IMMERSIVE_MODE) != 0) {
+ str.add("immersive_mode");
+ }
+ if ((flags & SYSUI_STATE_VOICE_INTERACTION_WINDOW_SHOWING) != 0) {
+ str.add("vis_win_showing");
+ }
+ if ((flags & SYSUI_STATE_FREEFORM_ACTIVE_IN_DESKTOP_MODE) != 0) {
+ str.add("freeform_active_in_desktop_mode");
+ }
+ if ((flags & SYSUI_STATE_DEVICE_DREAMING) != 0) {
+ str.add("device_dreaming");
+ }
+ if ((flags & SYSUI_STATE_SCREEN_TRANSITION) != 0) {
+ str.add("screen_transition");
+ }
+ if ((flags & SYSUI_STATE_SCREEN_ON) != 0) {
+ str.add("screen_on");
+ }
return str.toString();
}
diff --git a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
index 4aaa566..3b9060a 100644
--- a/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
+++ b/packages/SystemUI/src/com/android/keyguard/ClockEventController.kt
@@ -259,7 +259,7 @@
largeTimeListener?.update(shouldTimeListenerRun)
}
- override fun onTimeFormatChanged(timeFormat: String) {
+ override fun onTimeFormatChanged(timeFormat: String?) {
clock?.events?.onTimeFormatChanged(DateFormat.is24HourFormat(context))
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
index 5ec59ab..7b781ce 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardClockSwitchController.java
@@ -22,6 +22,7 @@
import static com.android.keyguard.KeyguardClockSwitch.LARGE;
import static com.android.keyguard.KeyguardClockSwitch.SMALL;
+import android.annotation.Nullable;
import android.database.ContentObserver;
import android.os.UserHandle;
import android.provider.Settings;
@@ -458,6 +459,7 @@
mView.setClock(clock, mStatusBarStateController.getState());
}
+ @Nullable
private ClockController getClock() {
return mClockEventController.getClock();
}
@@ -510,7 +512,9 @@
}
/** Gets the animations for the current clock. */
+ @Nullable
public ClockAnimations getClockAnimations() {
- return getClock().getAnimations();
+ ClockController clock = getClock();
+ return clock == null ? null : clock.getAnimations();
}
}
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
index 7255383..1a572b7 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardSecurityContainerController.java
@@ -260,6 +260,14 @@
*/
@Override
public void finish(boolean strongAuth, int targetUserId) {
+ if (mFeatureFlags.isEnabled(Flags.PREVENT_BYPASS_KEYGUARD)
+ && !mKeyguardStateController.canDismissLockScreen() && !strongAuth) {
+ Log.e(TAG,
+ "Tried to dismiss keyguard when lockscreen is not dismissible and user "
+ + "was not authenticated with a primary security method "
+ + "(pin/password/pattern).");
+ return;
+ }
// If there's a pending runnable because the user interacted with a widget
// and we're leaving keyguard, then run it.
boolean deferKeyguardDone = false;
diff --git a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
index b3a641c..085f202 100644
--- a/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
+++ b/packages/SystemUI/src/com/android/keyguard/KeyguardUpdateMonitor.java
@@ -69,6 +69,7 @@
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_STRONG_AUTH_CHANGED;
import static com.android.keyguard.FaceAuthUiEvent.FACE_AUTH_UPDATED_USER_SWITCHING;
import static com.android.systemui.DejankUtils.whitelistIpcs;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_OPENED;
import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_UNKNOWN;
import android.annotation.AnyThread;
@@ -479,6 +480,11 @@
sCurrentUser = currentUser;
}
+ /**
+ * @deprecated This can potentially return unexpected values in a multi user scenario
+ * as this state is managed by another component. Consider using {@link UserTracker}.
+ */
+ @Deprecated
public synchronized static int getCurrentUser() {
return sCurrentUser;
}
@@ -1610,7 +1616,7 @@
requestActiveUnlock(
ActiveUnlockConfig.ActiveUnlockRequestOrigin.ASSISTANT,
"assistant",
- false);
+ /* dismissKeyguard */ true);
}
}
@@ -1881,6 +1887,11 @@
updateFaceListeningState(BIOMETRIC_ACTION_STOP,
FACE_AUTH_UPDATED_POSTURE_CHANGED);
}
+ if (mPostureState == DEVICE_POSTURE_OPENED) {
+ mLogger.d("Posture changed to open - attempting to request active unlock");
+ requestActiveUnlockFromWakeReason(PowerManager.WAKE_REASON_UNFOLD_DEVICE,
+ false);
+ }
}
};
@@ -2007,26 +2018,10 @@
FACE_AUTH_UPDATED_STARTED_WAKING_UP.setExtraInfo(pmWakeReason);
updateFaceListeningState(BIOMETRIC_ACTION_UPDATE,
FACE_AUTH_UPDATED_STARTED_WAKING_UP);
-
- final ActiveUnlockConfig.ActiveUnlockRequestOrigin requestOrigin =
- mActiveUnlockConfig.isWakeupConsideredUnlockIntent(pmWakeReason)
- ? ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
- : ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE;
- final String reason = "wakingUp - " + PowerManager.wakeReasonToString(pmWakeReason);
- if (mActiveUnlockConfig.shouldWakeupForceDismissKeyguard(pmWakeReason)) {
- requestActiveUnlockDismissKeyguard(
- requestOrigin,
- reason
- );
- } else {
- requestActiveUnlock(
- requestOrigin,
- reason
- );
- }
} else {
mLogger.logSkipUpdateFaceListeningOnWakeup(pmWakeReason);
}
+ requestActiveUnlockFromWakeReason(pmWakeReason, true);
for (int i = 0; i < mCallbacks.size(); i++) {
KeyguardUpdateMonitorCallback cb = mCallbacks.get(i).get();
@@ -2660,6 +2655,32 @@
}
}
+ private void requestActiveUnlockFromWakeReason(@PowerManager.WakeReason int wakeReason,
+ boolean powerManagerWakeup) {
+ if (!mFaceWakeUpTriggersConfig.shouldTriggerFaceAuthOnWakeUpFrom(wakeReason)) {
+ mLogger.logActiveUnlockRequestSkippedForWakeReasonDueToFaceConfig(wakeReason);
+ return;
+ }
+
+ final ActiveUnlockConfig.ActiveUnlockRequestOrigin requestOrigin =
+ mActiveUnlockConfig.isWakeupConsideredUnlockIntent(wakeReason)
+ ? ActiveUnlockConfig.ActiveUnlockRequestOrigin.UNLOCK_INTENT
+ : ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE;
+ final String reason = "wakingUp - " + PowerManager.wakeReasonToString(wakeReason)
+ + " powerManagerWakeup=" + powerManagerWakeup;
+ if (mActiveUnlockConfig.shouldWakeupForceDismissKeyguard(wakeReason)) {
+ requestActiveUnlockDismissKeyguard(
+ requestOrigin,
+ reason
+ );
+ } else {
+ requestActiveUnlock(
+ requestOrigin,
+ reason
+ );
+ }
+ }
+
/**
* Attempts to trigger active unlock from trust agent.
*/
@@ -4125,6 +4146,19 @@
KeyguardFingerprintListenModel.TABLE_HEADERS,
mFingerprintListenBuffer.toList()
).printTableData(pw);
+ } else if (mFpm != null && mFingerprintSensorProperties.isEmpty()) {
+ final int userId = mUserTracker.getUserId();
+ pw.println(" Fingerprint state (user=" + userId + ")");
+ pw.println(" mFingerprintSensorProperties.isEmpty="
+ + mFingerprintSensorProperties.isEmpty());
+ pw.println(" mFpm.isHardwareDetected="
+ + mFpm.isHardwareDetected());
+
+ new DumpsysTableLogger(
+ "KeyguardFingerprintListen",
+ KeyguardFingerprintListenModel.TABLE_HEADERS,
+ mFingerprintListenBuffer.toList()
+ ).printTableData(pw);
}
if (mFaceManager != null && !mFaceSensorProperties.isEmpty()) {
final int userId = mUserTracker.getUserId();
@@ -4155,6 +4189,19 @@
KeyguardFaceListenModel.TABLE_HEADERS,
mFaceListenBuffer.toList()
).printTableData(pw);
+ } else if (mFaceManager != null && mFaceSensorProperties.isEmpty()) {
+ final int userId = mUserTracker.getUserId();
+ pw.println(" Face state (user=" + userId + ")");
+ pw.println(" mFaceSensorProperties.isEmpty="
+ + mFaceSensorProperties.isEmpty());
+ pw.println(" mFaceManager.isHardwareDetected="
+ + mFaceManager.isHardwareDetected());
+
+ new DumpsysTableLogger(
+ "KeyguardFaceListen",
+ KeyguardFingerprintListenModel.TABLE_HEADERS,
+ mFingerprintListenBuffer.toList()
+ ).printTableData(pw);
}
new DumpsysTableLogger(
diff --git a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
index b1a83fb..6e98a18 100644
--- a/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
+++ b/packages/SystemUI/src/com/android/keyguard/dagger/ClockRegistryModule.java
@@ -60,7 +60,9 @@
featureFlags.isEnabled(Flags.LOCKSCREEN_CUSTOM_CLOCKS),
/* handleAllUsers= */ true,
new DefaultClockProvider(context, layoutInflater, resources),
- context.getString(R.string.lockscreen_clock_id_fallback));
+ context.getString(R.string.lockscreen_clock_id_fallback),
+ /* keepAllLoaded = */ false,
+ /* subTag = */ "System");
registry.registerListeners();
return registry;
}
diff --git a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
index 8d5b8be..e3ca13e 100644
--- a/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
+++ b/packages/SystemUI/src/com/android/keyguard/logging/KeyguardUpdateMonitorLogger.kt
@@ -62,6 +62,16 @@
)
}
+ fun logActiveUnlockRequestSkippedForWakeReasonDueToFaceConfig(wakeReason: Int) {
+ logBuffer.log(
+ "ActiveUnlock",
+ DEBUG,
+ { int1 = wakeReason },
+ { "Skip requesting active unlock from wake reason that doesn't trigger face auth" +
+ " reason=${PowerManager.wakeReasonToString(int1)}" }
+ )
+ }
+
fun logAuthInterruptDetected(active: Boolean) {
logBuffer.log(TAG, DEBUG, { bool1 = active }, { "onAuthInterruptDetected($bool1)" })
}
diff --git a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
index 90ecb46..de82ca0 100644
--- a/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
+++ b/packages/SystemUI/src/com/android/systemui/DisplayCutoutBaseView.kt
@@ -37,6 +37,8 @@
import androidx.annotation.VisibleForTesting
import com.android.systemui.RegionInterceptingFrameLayout.RegionInterceptableView
import com.android.systemui.animation.Interpolators
+import com.android.systemui.util.asIndenting
+import java.io.PrintWriter
/**
* A class that handles common actions of display cutout view.
@@ -324,4 +326,18 @@
}
}
}
+
+ open fun dump(pw: PrintWriter) {
+ val ipw = pw.asIndenting()
+ ipw.increaseIndent()
+ ipw.println("DisplayCutoutBaseView:")
+ ipw.increaseIndent()
+ ipw.println("shouldDrawCutout=$shouldDrawCutout")
+ ipw.println("cutout=${displayInfo.displayCutout}")
+ ipw.println("cameraProtectionProgress=$cameraProtectionProgress")
+ ipw.println("protectionRect=$protectionRect")
+ ipw.println("protectionRectOrig=$protectionRectOrig")
+ ipw.decreaseIndent()
+ ipw.decreaseIndent()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
index 54939fd..179eb39 100644
--- a/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
+++ b/packages/SystemUI/src/com/android/systemui/FaceScanningOverlay.kt
@@ -37,6 +37,8 @@
import com.android.systemui.animation.Interpolators
import com.android.systemui.log.ScreenDecorationsLogger
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.util.asIndenting
+import java.io.PrintWriter
import java.util.concurrent.Executor
/**
@@ -416,4 +418,15 @@
path.transform(scaleMatrix)
}
}
+
+ override fun dump(pw: PrintWriter) {
+ val ipw = pw.asIndenting()
+ ipw.increaseIndent()
+ ipw.println("FaceScanningOverlay:")
+ super.dump(ipw)
+ ipw.println("rimProgress=$rimProgress")
+ ipw.println("rimRect=$rimRect")
+ ipw.println("this=$this")
+ ipw.decreaseIndent()
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
index a74f2f8..99dd6b6 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorHwcLayer.kt
@@ -40,6 +40,8 @@
import android.view.RoundedCorners
import android.view.Surface
import androidx.annotation.VisibleForTesting
+import com.android.systemui.util.asIndenting
+import java.io.PrintWriter
import kotlin.math.ceil
import kotlin.math.floor
@@ -47,8 +49,8 @@
* When the HWC of the device supports Composition.DISPLAY_DECORATION, we use this layer to draw
* screen decorations.
*/
-class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDecorationSupport)
- : DisplayCutoutBaseView(context) {
+class ScreenDecorHwcLayer(context: Context, displayDecorationSupport: DisplayDecorationSupport) :
+ DisplayCutoutBaseView(context) {
val colorMode: Int
private val useInvertedAlphaColor: Boolean
private val color: Int
@@ -406,6 +408,20 @@
invalidate()
}
+ override fun dump(pw: PrintWriter) {
+ val ipw = pw.asIndenting()
+ ipw.increaseIndent()
+ ipw.println("ScreenDecorHwcLayer:")
+ super.dump(pw)
+ ipw.println("this=$this")
+ ipw.println("transparentRect=$transparentRect")
+ ipw.println("hasTopRoundedCorner=$hasTopRoundedCorner")
+ ipw.println("hasBottomRoundedCorner=$hasBottomRoundedCorner")
+ ipw.println("roundedCornerTopSize=$roundedCornerTopSize")
+ ipw.println("roundedCornerBottomSize=$roundedCornerBottomSize")
+ ipw.decreaseIndent()
+ }
+
companion object {
private val DEBUG_COLOR = ScreenDecorations.DEBUG_COLOR
}
diff --git a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
index fb65588..adc0412 100644
--- a/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
+++ b/packages/SystemUI/src/com/android/systemui/ScreenDecorations.java
@@ -23,6 +23,8 @@
import static android.view.ViewGroup.LayoutParams.WRAP_CONTENT;
import static android.view.WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS;
+import static com.android.systemui.util.DumpUtilsKt.asIndenting;
+
import android.annotation.IdRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -44,6 +46,7 @@
import android.os.Trace;
import android.provider.Settings.Secure;
import android.util.DisplayUtils;
+import android.util.IndentingPrintWriter;
import android.util.Log;
import android.util.Size;
import android.view.Display;
@@ -1005,39 +1008,55 @@
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("ScreenDecorations state:");
- pw.println(" DEBUG_DISABLE_SCREEN_DECORATIONS:" + DEBUG_DISABLE_SCREEN_DECORATIONS);
+ IndentingPrintWriter ipw = asIndenting(pw);
+ ipw.increaseIndent();
+ ipw.println("DEBUG_DISABLE_SCREEN_DECORATIONS:" + DEBUG_DISABLE_SCREEN_DECORATIONS);
if (DEBUG_DISABLE_SCREEN_DECORATIONS) {
return;
}
- pw.println(" mIsPrivacyDotEnabled:" + isPrivacyDotEnabled());
- pw.println(" shouldOptimizeOverlayVisibility:" + shouldOptimizeVisibility());
+ ipw.println("mIsPrivacyDotEnabled:" + isPrivacyDotEnabled());
+ ipw.println("shouldOptimizeOverlayVisibility:" + shouldOptimizeVisibility());
final boolean supportsShowingFaceScanningAnim = mFaceScanningFactory.getHasProviders();
- pw.println(" supportsShowingFaceScanningAnim:" + supportsShowingFaceScanningAnim);
+ ipw.println("supportsShowingFaceScanningAnim:" + supportsShowingFaceScanningAnim);
if (supportsShowingFaceScanningAnim) {
- pw.println(" canShowFaceScanningAnim:"
+ ipw.increaseIndent();
+ ipw.println("canShowFaceScanningAnim:"
+ mFaceScanningFactory.canShowFaceScanningAnim());
- pw.println(" shouldShowFaceScanningAnim (at time dump was taken):"
+ ipw.println("shouldShowFaceScanningAnim (at time dump was taken):"
+ mFaceScanningFactory.shouldShowFaceScanningAnim());
+ ipw.decreaseIndent();
}
- pw.println(" mPendingConfigChange:" + mPendingConfigChange);
+ FaceScanningOverlay faceScanningOverlay =
+ (FaceScanningOverlay) getOverlayView(mFaceScanningViewId);
+ if (faceScanningOverlay != null) {
+ faceScanningOverlay.dump(ipw);
+ }
+ ipw.println("mPendingConfigChange:" + mPendingConfigChange);
if (mHwcScreenDecorationSupport != null) {
- pw.println(" mHwcScreenDecorationSupport:");
- pw.println(" format="
+ ipw.increaseIndent();
+ ipw.println("mHwcScreenDecorationSupport:");
+ ipw.increaseIndent();
+ ipw.println("format="
+ PixelFormat.formatToString(mHwcScreenDecorationSupport.format));
- pw.println(" alphaInterpretation="
+ ipw.println("alphaInterpretation="
+ alphaInterpretationToString(mHwcScreenDecorationSupport.alphaInterpretation));
+ ipw.decreaseIndent();
+ ipw.decreaseIndent();
} else {
- pw.println(" mHwcScreenDecorationSupport: null");
+ ipw.increaseIndent();
+ pw.println("mHwcScreenDecorationSupport: null");
+ ipw.decreaseIndent();
}
if (mScreenDecorHwcLayer != null) {
- pw.println(" mScreenDecorHwcLayer:");
- pw.println(" transparentRegion=" + mScreenDecorHwcLayer.transparentRect);
+ ipw.increaseIndent();
+ mScreenDecorHwcLayer.dump(ipw);
+ ipw.decreaseIndent();
} else {
- pw.println(" mScreenDecorHwcLayer: null");
+ ipw.println("mScreenDecorHwcLayer: null");
}
if (mOverlays != null) {
- pw.println(" mOverlays(left,top,right,bottom)=("
+ ipw.println("mOverlays(left,top,right,bottom)=("
+ (mOverlays[BOUNDS_POSITION_LEFT] != null) + ","
+ (mOverlays[BOUNDS_POSITION_TOP] != null) + ","
+ (mOverlays[BOUNDS_POSITION_RIGHT] != null) + ","
diff --git a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt
index 53a421d..1836ce8 100644
--- a/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt
+++ b/packages/SystemUI/src/com/android/systemui/accessibility/fontscaling/FontScalingDialog.kt
@@ -15,6 +15,7 @@
*/
package com.android.systemui.accessibility.fontscaling
+import android.annotation.WorkerThread
import android.content.Context
import android.content.pm.ActivityInfo
import android.content.res.Configuration
@@ -27,18 +28,26 @@
import android.widget.TextView
import com.android.systemui.R
import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView
+import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.settings.SystemSettings
+import java.util.concurrent.Executor
import kotlin.math.roundToInt
/** The Dialog that contains a seekbar for changing the font size. */
-class FontScalingDialog(context: Context, private val systemSettings: SystemSettings) :
- SystemUIDialog(context) {
+class FontScalingDialog(
+ context: Context,
+ private val systemSettings: SystemSettings,
+ private val secureSettings: SecureSettings,
+ @Background private val backgroundExecutor: Executor
+) : SystemUIDialog(context) {
private val strEntryValues: Array<String> =
context.resources.getStringArray(com.android.settingslib.R.array.entryvalues_font_size)
private lateinit var title: TextView
private lateinit var doneButton: Button
private lateinit var seekBarWithIconButtonsView: SeekBarWithIconButtonsView
+ private var lastProgress: Int = -1
private val configuration: Configuration =
Configuration(context.getResources().getConfiguration())
@@ -70,12 +79,22 @@
seekBarWithIconButtonsView.setMax((strEntryValues).size - 1)
val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, 1.0f)
- seekBarWithIconButtonsView.setProgress(fontSizeValueToIndex(currentScale))
+ lastProgress = fontSizeValueToIndex(currentScale)
+ seekBarWithIconButtonsView.setProgress(lastProgress)
seekBarWithIconButtonsView.setOnSeekBarChangeListener(
object : OnSeekBarChangeListener {
override fun onProgressChanged(seekBar: SeekBar, progress: Int, fromUser: Boolean) {
- systemSettings.putString(Settings.System.FONT_SCALE, strEntryValues[progress])
+ if (progress != lastProgress) {
+ if (!fontSizeHasBeenChangedFromTile) {
+ backgroundExecutor.execute { updateSecureSettingsIfNeeded() }
+ fontSizeHasBeenChangedFromTile = true
+ }
+
+ backgroundExecutor.execute { updateFontScale(strEntryValues[progress]) }
+
+ lastProgress = progress
+ }
}
override fun onStartTrackingTouch(seekBar: SeekBar) {
@@ -115,4 +134,28 @@
}
}
}
+
+ @WorkerThread
+ fun updateFontScale(newScale: String) {
+ systemSettings.putString(Settings.System.FONT_SCALE, newScale)
+ }
+
+ @WorkerThread
+ fun updateSecureSettingsIfNeeded() {
+ if (
+ secureSettings.getString(Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED) !=
+ ON
+ ) {
+ secureSettings.putString(
+ Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
+ ON
+ )
+ }
+ }
+
+ companion object {
+ private const val ON = "1"
+ private const val OFF = "0"
+ private var fontSizeHasBeenChangedFromTile = false
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
index 52312b8..4b5c50f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricFingerprintIconController.kt
@@ -230,29 +230,21 @@
if (isReverseDefaultRotation) (rotation + 1) % 4 else rotation
@RawRes
- private fun getSideFpsAnimationForTransition(rotation: Int): Int {
- when (rotation) {
- Surface.ROTATION_90 -> if (context.isInRearDisplayMode()) {
- return R.raw.biometricprompt_rear_portrait_reverse_base
- } else if (isDeviceFolded) {
- return R.raw.biometricprompt_folded_base_topleft
- } else {
- return R.raw.biometricprompt_portrait_base_topleft
- }
- Surface.ROTATION_270 -> if (context.isInRearDisplayMode()) {
- return R.raw.biometricprompt_rear_portrait_base
- } else if (isDeviceFolded) {
- return R.raw.biometricprompt_folded_base_bottomright
- } else {
- return R.raw.biometricprompt_portrait_base_bottomright
- }
- else -> if (context.isInRearDisplayMode()) {
- return R.raw.biometricprompt_rear_landscape_base
- } else if (isDeviceFolded) {
- return R.raw.biometricprompt_folded_base_default
- } else {
- return R.raw.biometricprompt_landscape_base
- }
+ private fun getSideFpsAnimationForTransition(rotation: Int): Int = when (rotation) {
+ Surface.ROTATION_90 -> if (isDeviceFolded) {
+ R.raw.biometricprompt_folded_base_topleft
+ } else {
+ R.raw.biometricprompt_portrait_base_topleft
+ }
+ Surface.ROTATION_270 -> if (isDeviceFolded) {
+ R.raw.biometricprompt_folded_base_bottomright
+ } else {
+ R.raw.biometricprompt_portrait_base_bottomright
+ }
+ else -> if (isDeviceFolded) {
+ R.raw.biometricprompt_folded_base_default
+ } else {
+ R.raw.biometricprompt_landscape_base
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
index a7b6e6a..13bb6d3 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthBiometricView.java
@@ -658,7 +658,9 @@
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
mIconController.onConfigurationChanged(newConfig);
- updateState(mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_STATE));
+ if (mSavedState != null) {
+ updateState(mSavedState.getInt(AuthDialog.KEY_BIOMETRIC_STATE));
+ }
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
index 4aa985b..705fc8c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/AuthController.java
@@ -823,7 +823,7 @@
final Rect overlayBounds = new Rect(
0, /* left */
- mCachedDisplayInfo.getNaturalHeight() / 2, /* top */
+ 0, /* top */
mCachedDisplayInfo.getNaturalWidth(), /* right */
mCachedDisplayInfo.getNaturalHeight() /* botom */);
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
index b62c729..c98a62f 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/SideFpsController.kt
@@ -173,16 +173,12 @@
override fun show(
sensorId: Int,
@BiometricOverlayConstants.ShowReason reason: Int
- ) {
- if (
- reason.isReasonToAutoShow(activityTaskManager) &&
- !context.isInRearDisplayMode()
- ) {
+ ) =
+ if (reason.isReasonToAutoShow(activityTaskManager)) {
show(SideFpsUiRequestSource.AUTO_SHOW, reason)
} else {
hide(SideFpsUiRequestSource.AUTO_SHOW)
}
- }
override fun hide(sensorId: Int) = hide(SideFpsUiRequestSource.AUTO_SHOW)
}
@@ -199,7 +195,7 @@
scope.launch {
alternateBouncerInteractor.isVisible.collect { isVisible: Boolean ->
if (isVisible) {
- show(SideFpsUiRequestSource.ALTERNATE_BOUNCER)
+ show(SideFpsUiRequestSource.ALTERNATE_BOUNCER, REASON_AUTH_KEYGUARD)
} else {
hide(SideFpsUiRequestSource.ALTERNATE_BOUNCER)
}
@@ -440,13 +436,17 @@
@BiometricOverlayConstants.ShowReason reason: Int
) {
fun update() {
- val c = context.getColor(R.color.biometric_dialog_accent)
- val chevronFill = context.getColor(R.color.sfps_chevron_fill)
val isKeyguard = reason == REASON_AUTH_KEYGUARD
if (isKeyguard) {
+ val color = context.getColor(R.color.numpad_key_color_secondary) // match bouncer color
+ val chevronFill =
+ com.android.settingslib.Utils.getColorAttrDefaultColor(
+ context,
+ android.R.attr.textColorPrimaryInverse
+ )
for (key in listOf(".blue600", ".blue400")) {
addValueCallback(KeyPath(key, "**"), LottieProperty.COLOR_FILTER) {
- PorterDuffColorFilter(c, PorterDuff.Mode.SRC_ATOP)
+ PorterDuffColorFilter(color, PorterDuff.Mode.SRC_ATOP)
}
}
addValueCallback(KeyPath(".black", "**"), LottieProperty.COLOR_FILTER) {
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
index bb35355..e7ec3eb 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/UdfpsController.java
@@ -42,6 +42,7 @@
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
+import android.hardware.input.InputManager;
import android.os.Build;
import android.os.Handler;
import android.os.PowerManager;
@@ -169,6 +170,7 @@
@NonNull private final AlternateBouncerInteractor mAlternateBouncerInteractor;
@NonNull private final SecureSettings mSecureSettings;
@NonNull private final UdfpsUtils mUdfpsUtils;
+ @NonNull private final InputManager mInputManager;
// Currently the UdfpsController supports a single UDFPS sensor. If devices have multiple
// sensors, this, in addition to a lot of the code here, will be updated.
@@ -576,6 +578,10 @@
data.getTime(),
data.getGestureStart(),
mStatusBarStateController.isDozing());
+
+ // Pilfer if valid overlap, don't allow following events to reach keyguard
+ mInputManager.pilferPointers(
+ mOverlay.getOverlayView().getViewRootImpl().getInputToken());
break;
case UP:
@@ -599,9 +605,8 @@
break;
case UNCHANGED:
- if (!isWithinSensorArea(mOverlay.getOverlayView(), event.getX(), event.getY(),
+ if (!isWithinSensorArea(mOverlay.getOverlayView(), event.getRawX(), event.getRawY(),
true) && mActivePointerId == MotionEvent.INVALID_POINTER_ID
- && event.getActionMasked() == MotionEvent.ACTION_DOWN
&& mAlternateBouncerInteractor.isVisibleState()) {
// No pointer on sensor, forward to keyguard if alternateBouncer is visible
mKeyguardViewManager.onTouch(event);
@@ -612,6 +617,13 @@
}
logBiometricTouch(processedTouch.getEvent(), data);
+ // Always pilfer pointers that are within sensor area
+ if (isWithinSensorArea(mOverlay.getOverlayView(), event.getRawX(), event.getRawY(), true)) {
+ Log.d("Austin", "pilferTouch invalid overlap");
+ mInputManager.pilferPointers(
+ mOverlay.getOverlayView().getViewRootImpl().getInputToken());
+ }
+
return processedTouch.getTouchData().isWithinSensor(mOverlayParams.getNativeSensorBounds());
}
@@ -798,6 +810,7 @@
@NonNull SessionTracker sessionTracker,
@NonNull AlternateBouncerInteractor alternateBouncerInteractor,
@NonNull SecureSettings secureSettings,
+ @NonNull InputManager inputManager,
@NonNull UdfpsUtils udfpsUtils) {
mContext = context;
mExecution = execution;
@@ -841,6 +854,7 @@
mAlternateBouncerInteractor = alternateBouncerInteractor;
mSecureSettings = secureSettings;
mUdfpsUtils = udfpsUtils;
+ mInputManager = inputManager;
mTouchProcessor = mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)
? singlePointerTouchProcessor : null;
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
index 3d56326..d0d6f4c 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/Utils.kt
@@ -36,7 +36,6 @@
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityManager
import com.android.internal.widget.LockPatternUtils
-import com.android.systemui.R
import java.lang.annotation.Retention
import java.lang.annotation.RetentionPolicy
@@ -118,7 +117,4 @@
@Retention(RetentionPolicy.SOURCE)
@IntDef(CREDENTIAL_PIN, CREDENTIAL_PATTERN, CREDENTIAL_PASSWORD)
internal annotation class CredentialType
-}
-
-fun Context.isInRearDisplayMode(): Boolean = resources.getIntArray(
- com.android.internal.R.array.config_rearDisplayDeviceStates).isNotEmpty()
\ No newline at end of file
+}
\ No newline at end of file
diff --git a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
index 92a7094..9a0792e 100644
--- a/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractor.kt
@@ -37,12 +37,12 @@
@Inject
constructor(private val authController: AuthController, @Application scope: CoroutineScope) {
- /** Whether a touch should be intercepted or allowed to pass to the UdfpsOverlay */
- fun canInterceptTouchInUdfpsBounds(ev: MotionEvent): Boolean {
+ /** Whether a touch is within the under-display fingerprint sensor area */
+ fun isTouchWithinUdfpsArea(ev: MotionEvent): Boolean {
val isUdfpsEnrolled = authController.isUdfpsEnrolled(KeyguardUpdateMonitor.getCurrentUser())
- val isWithinUdfpsOverlayBounds =
+ val isWithinOverlayBounds =
udfpsOverlayParams.value.overlayBounds.contains(ev.rawX.toInt(), ev.rawY.toInt())
- return !isUdfpsEnrolled || !isWithinUdfpsOverlayBounds
+ return isUdfpsEnrolled && isWithinOverlayBounds
}
/** Returns the current udfpsOverlayParams */
diff --git a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
index e8c83b1..0123857 100644
--- a/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
+++ b/packages/SystemUI/src/com/android/systemui/classifier/ProximityClassifier.java
@@ -81,19 +81,19 @@
int action = motionEvent.getActionMasked();
if (action == MotionEvent.ACTION_DOWN) {
- mGestureStartTimeNs = motionEvent.getEventTimeNano();
+ mGestureStartTimeNs = motionEvent.getEventTimeNanos();
if (mPrevNearTimeNs > 0) {
// We only care about if the proximity sensor is triggered while a move event is
// happening.
- mPrevNearTimeNs = motionEvent.getEventTimeNano();
+ mPrevNearTimeNs = motionEvent.getEventTimeNanos();
}
logDebug("Gesture start time: " + mGestureStartTimeNs);
mNearDurationNs = 0;
}
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_CANCEL) {
- update(mNear, motionEvent.getEventTimeNano());
- long duration = motionEvent.getEventTimeNano() - mGestureStartTimeNs;
+ update(mNear, motionEvent.getEventTimeNanos());
+ long duration = motionEvent.getEventTimeNanos() - mGestureStartTimeNs;
logDebug("Gesture duration, Proximity duration: " + duration + ", " + mNearDurationNs);
diff --git a/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt b/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt
index 5dabbbb..6a6c3eb 100644
--- a/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/shared/model/TintedIcon.kt
@@ -16,10 +16,10 @@
package com.android.systemui.common.shared.model
-import androidx.annotation.AttrRes
+import androidx.annotation.ColorRes
/** Models an icon with a specific tint. */
data class TintedIcon(
val icon: Icon,
- @AttrRes val tintAttr: Int?,
+ @ColorRes val tint: Int?,
)
diff --git a/packages/SystemUI/src/com/android/systemui/common/ui/binder/TintedIconViewBinder.kt b/packages/SystemUI/src/com/android/systemui/common/ui/binder/TintedIconViewBinder.kt
index dea8cfd..bcc5932 100644
--- a/packages/SystemUI/src/com/android/systemui/common/ui/binder/TintedIconViewBinder.kt
+++ b/packages/SystemUI/src/com/android/systemui/common/ui/binder/TintedIconViewBinder.kt
@@ -17,15 +17,14 @@
package com.android.systemui.common.ui.binder
import android.widget.ImageView
-import com.android.settingslib.Utils
import com.android.systemui.common.shared.model.TintedIcon
object TintedIconViewBinder {
/**
* Binds the given tinted icon to the view.
*
- * [TintedIcon.tintAttr] will always be applied, meaning that if it is null, then the tint
- * *will* be reset to null.
+ * [TintedIcon.tint] will always be applied, meaning that if it is null, then the tint *will* be
+ * reset to null.
*/
fun bind(
tintedIcon: TintedIcon,
@@ -33,8 +32,8 @@
) {
IconViewBinder.bind(tintedIcon.icon, view)
view.imageTintList =
- if (tintedIcon.tintAttr != null) {
- Utils.getColorAttr(view.context, tintedIcon.tintAttr)
+ if (tintedIcon.tint != null) {
+ view.resources.getColorStateList(tintedIcon.tint, view.context.theme)
} else {
null
}
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
index bf0a692..224eb1c 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsActivity.kt
@@ -20,6 +20,8 @@
import android.content.Context
import android.content.Intent
import android.content.IntentFilter
+import android.content.pm.ActivityInfo
+import android.content.res.Configuration
import android.os.Bundle
import android.os.RemoteException
import android.service.dreams.IDreamManager
@@ -57,9 +59,11 @@
private lateinit var parent: ViewGroup
private lateinit var broadcastReceiver: BroadcastReceiver
private var mExitToDream: Boolean = false
+ private lateinit var lastConfiguration: Configuration
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
+ lastConfiguration = resources.configuration
if (featureFlags.isEnabled(Flags.USE_APP_PANELS)) {
window.addPrivateFlags(WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY)
}
@@ -92,6 +96,14 @@
initBroadcastReceiver()
}
+ override fun onConfigurationChanged(newConfig: Configuration) {
+ super.onConfigurationChanged(newConfig)
+ if (lastConfiguration.diff(newConfig) and ActivityInfo.CONFIG_ORIENTATION != 0 ) {
+ uiController.onOrientationChange()
+ }
+ lastConfiguration = newConfig
+ }
+
override fun onStart() {
super.onStart()
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
index 0d53117..3ecf423 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiController.kt
@@ -64,6 +64,8 @@
* This element will be the one that appears when the user first opens the controls activity.
*/
fun getPreferredSelectedItem(structures: List<StructureInfo>): SelectedItem
+
+ fun onOrientationChange()
}
sealed class SelectedItem {
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
index 5da86de9..868e527 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/ControlsUiControllerImpl.kt
@@ -124,6 +124,7 @@
}
private var selectedItem: SelectedItem = SelectedItem.EMPTY_SELECTION
+ private var selectionItem: SelectionItem? = null
private lateinit var allStructures: List<StructureInfo>
private val controlsById = mutableMapOf<ControlKey, ControlWithState>()
private val controlViewsById = mutableMapOf<ControlKey, ControlViewHolder>()
@@ -230,6 +231,7 @@
this.overflowMenuAdapter = null
hidden = false
retainCache = false
+ selectionItem = null
controlActionCoordinator.activityContext = activityContext
@@ -272,7 +274,7 @@
}
}
- private fun reload(parent: ViewGroup) {
+ private fun reload(parent: ViewGroup, dismissTaskView: Boolean = true) {
if (hidden) return
controlsListingController.get().removeCallback(listingCallback)
@@ -327,8 +329,8 @@
@VisibleForTesting
internal fun startRemovingApp(componentName: ComponentName, appName: CharSequence) {
removeAppDialog?.cancel()
- removeAppDialog = dialogsFactory.createRemoveAppDialog(context, appName) {
- if (!controlsController.get().removeFavorites(componentName)) {
+ removeAppDialog = dialogsFactory.createRemoveAppDialog(context, appName) { shouldRemove ->
+ if (!shouldRemove || !controlsController.get().removeFavorites(componentName)) {
return@createRemoveAppDialog
}
@@ -425,6 +427,7 @@
} else {
Log.w(ControlsUiController.TAG, "Not TaskViewFactory to display panel $selectionItem")
}
+ this.selectionItem = selectionItem
bgExecutor.execute {
val intent = Intent(Intent.ACTION_MAIN)
@@ -605,6 +608,7 @@
if (items.size == 1) {
spinner.setBackground(null)
anchor.setOnClickListener(null)
+ anchor.isClickable = false
return
} else {
spinner.background = parent.context.resources
@@ -657,6 +661,7 @@
val maxColumns = ControlAdapter.findMaxColumns(activityContext.resources)
val listView = parent.requireViewById(R.id.global_actions_controls_list) as ViewGroup
+ listView.removeAllViews()
var lastRow: ViewGroup = createRow(inflater, listView)
selectedStructure.controls.forEach {
val key = ControlKey(selectedStructure.componentName, it.controlId)
@@ -804,6 +809,15 @@
}
}
+ override fun onOrientationChange() {
+ selectionItem?.let {
+ when (selectedItem) {
+ is SelectedItem.StructureItem -> createListView(it)
+ is SelectedItem.PanelItem -> taskViewController?.refreshBounds() ?: reload(parent)
+ }
+ } ?: reload(parent)
+ }
+
private fun createRow(inflater: LayoutInflater, listView: ViewGroup): ViewGroup {
val row = inflater.inflate(R.layout.controls_row, listView, false) as ViewGroup
listView.addView(row)
diff --git a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
index 78e87ca..1f89c91 100644
--- a/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/controls/ui/PanelTaskViewController.kt
@@ -37,7 +37,7 @@
private val activityContext: Context,
private val uiExecutor: Executor,
private val pendingIntent: PendingIntent,
- private val taskView: TaskView,
+ val taskView: TaskView,
private val hide: () -> Unit = {}
) {
@@ -108,6 +108,10 @@
}
}
+ fun refreshBounds() {
+ taskView.onLocationChanged()
+ }
+
fun dismiss() {
taskView.release()
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java b/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java
index 055cd52..7f567aa 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/DreamMonitor.java
@@ -23,6 +23,7 @@
import com.android.systemui.CoreStartable;
import com.android.systemui.dreams.callbacks.DreamStatusBarStateCallback;
import com.android.systemui.dreams.conditions.DreamCondition;
+import com.android.systemui.flags.RestartDozeListener;
import com.android.systemui.shared.condition.Monitor;
import com.android.systemui.util.condition.ConditionalCoreStartable;
@@ -39,17 +40,19 @@
private final Monitor mConditionMonitor;
private final DreamCondition mDreamCondition;
private final DreamStatusBarStateCallback mCallback;
+ private RestartDozeListener mRestartDozeListener;
@Inject
public DreamMonitor(Monitor monitor, DreamCondition dreamCondition,
@Named(DREAM_PRETEXT_MONITOR) Monitor pretextMonitor,
- DreamStatusBarStateCallback callback) {
+ DreamStatusBarStateCallback callback,
+ RestartDozeListener restartDozeListener) {
super(pretextMonitor);
mConditionMonitor = monitor;
mDreamCondition = dreamCondition;
mCallback = callback;
-
+ mRestartDozeListener = restartDozeListener;
}
@Override
@@ -61,5 +64,8 @@
mConditionMonitor.addSubscription(new Monitor.Subscription.Builder(mCallback)
.addCondition(mDreamCondition)
.build());
+
+ mRestartDozeListener.init();
+ mRestartDozeListener.maybeRestartSleep();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java
index 7f395d8..82a8858 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/DreamHomeControlsComplication.java
@@ -33,7 +33,6 @@
import com.android.internal.logging.UiEvent;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.CoreStartable;
-import com.android.systemui.R;
import com.android.systemui.animation.ActivityLaunchAnimator;
import com.android.systemui.controls.ControlsServiceInfo;
import com.android.systemui.controls.dagger.ControlsComponent;
@@ -157,14 +156,14 @@
* Contains values/logic associated with the dream complication view.
*/
public static class DreamHomeControlsChipViewHolder implements ViewHolder {
- private final View mView;
+ private final ImageView mView;
private final ComplicationLayoutParams mLayoutParams;
private final DreamHomeControlsChipViewController mViewController;
@Inject
DreamHomeControlsChipViewHolder(
DreamHomeControlsChipViewController dreamHomeControlsChipViewController,
- @Named(DREAM_HOME_CONTROLS_CHIP_VIEW) View view,
+ @Named(DREAM_HOME_CONTROLS_CHIP_VIEW) ImageView view,
@Named(DREAM_HOME_CONTROLS_CHIP_LAYOUT_PARAMS) ComplicationLayoutParams layoutParams
) {
mView = view;
@@ -174,7 +173,7 @@
}
@Override
- public View getView() {
+ public ImageView getView() {
return mView;
}
@@ -187,7 +186,7 @@
/**
* Controls behavior of the dream complication.
*/
- static class DreamHomeControlsChipViewController extends ViewController<View> {
+ static class DreamHomeControlsChipViewController extends ViewController<ImageView> {
private static final String TAG = "DreamHomeControlsCtrl";
private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
@@ -216,7 +215,7 @@
@Inject
DreamHomeControlsChipViewController(
- @Named(DREAM_HOME_CONTROLS_CHIP_VIEW) View view,
+ @Named(DREAM_HOME_CONTROLS_CHIP_VIEW) ImageView view,
ActivityStarter activityStarter,
Context context,
ControlsComponent controlsComponent,
@@ -231,10 +230,9 @@
@Override
protected void onViewAttached() {
- final ImageView chip = mView.findViewById(R.id.home_controls_chip);
- chip.setImageResource(mControlsComponent.getTileImageId());
- chip.setContentDescription(mContext.getString(mControlsComponent.getTileTitleId()));
- chip.setOnClickListener(this::onClickHomeControls);
+ mView.setImageResource(mControlsComponent.getTileImageId());
+ mView.setContentDescription(mContext.getString(mControlsComponent.getTileTitleId()));
+ mView.setOnClickListener(this::onClickHomeControls);
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamHomeControlsComplicationComponent.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamHomeControlsComplicationComponent.java
index a7aa97f..cf05d2d 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamHomeControlsComplicationComponent.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/DreamHomeControlsComplicationComponent.java
@@ -19,7 +19,7 @@
import static java.lang.annotation.RetentionPolicy.RUNTIME;
import android.view.LayoutInflater;
-import android.view.View;
+import android.widget.ImageView;
import com.android.systemui.R;
import com.android.systemui.dreams.complication.DreamHomeControlsComplication;
@@ -74,8 +74,8 @@
@Provides
@DreamHomeControlsComplicationScope
@Named(DREAM_HOME_CONTROLS_CHIP_VIEW)
- static View provideHomeControlsChipView(LayoutInflater layoutInflater) {
- return layoutInflater.inflate(R.layout.dream_overlay_home_controls_chip,
+ static ImageView provideHomeControlsChipView(LayoutInflater layoutInflater) {
+ return (ImageView) layoutInflater.inflate(R.layout.dream_overlay_home_controls_chip,
null, false);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java
index 6808142..3be42cb 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/complication/dagger/RegisteredComplicationsModule.java
@@ -23,6 +23,8 @@
import com.android.systemui.dagger.SystemUIBinder;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.dreams.complication.ComplicationLayoutParams;
+import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import javax.inject.Named;
@@ -47,6 +49,7 @@
String DREAM_MEDIA_ENTRY_LAYOUT_PARAMS = "media_entry_layout_params";
int DREAM_CLOCK_TIME_COMPLICATION_WEIGHT = 1;
+ int DREAM_CLOCK_TIME_COMPLICATION_WEIGHT_NO_SMARTSPACE = 2;
int DREAM_SMARTSPACE_COMPLICATION_WEIGHT = 2;
int DREAM_MEDIA_COMPLICATION_WEIGHT = 0;
int DREAM_HOME_CONTROLS_CHIP_COMPLICATION_WEIGHT = 4;
@@ -58,7 +61,15 @@
*/
@Provides
@Named(DREAM_CLOCK_TIME_COMPLICATION_LAYOUT_PARAMS)
- static ComplicationLayoutParams provideClockTimeLayoutParams() {
+ static ComplicationLayoutParams provideClockTimeLayoutParams(FeatureFlags featureFlags) {
+ if (featureFlags.isEnabled(Flags.HIDE_SMARTSPACE_ON_DREAM_OVERLAY)) {
+ return new ComplicationLayoutParams(0,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ComplicationLayoutParams.POSITION_BOTTOM
+ | ComplicationLayoutParams.POSITION_START,
+ ComplicationLayoutParams.DIRECTION_END,
+ DREAM_CLOCK_TIME_COMPLICATION_WEIGHT_NO_SMARTSPACE);
+ }
return new ComplicationLayoutParams(0,
ViewGroup.LayoutParams.WRAP_CONTENT,
ComplicationLayoutParams.POSITION_BOTTOM
@@ -90,8 +101,8 @@
@Named(DREAM_MEDIA_ENTRY_LAYOUT_PARAMS)
static ComplicationLayoutParams provideMediaEntryLayoutParams(@Main Resources res) {
return new ComplicationLayoutParams(
- res.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_width),
- res.getDimensionPixelSize(R.dimen.keyguard_affordance_fixed_height),
+ ViewGroup.LayoutParams.WRAP_CONTENT,
+ ViewGroup.LayoutParams.WRAP_CONTENT,
ComplicationLayoutParams.POSITION_BOTTOM
| ComplicationLayoutParams.POSITION_START,
ComplicationLayoutParams.DIRECTION_END,
diff --git a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
index 2befce7..5bbfbda 100644
--- a/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
+++ b/packages/SystemUI/src/com/android/systemui/dreams/conditions/DreamCondition.java
@@ -15,6 +15,7 @@
*/
package com.android.systemui.dreams.conditions;
+import android.app.DreamManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -30,6 +31,7 @@
*/
public class DreamCondition extends Condition {
private final Context mContext;
+ private final DreamManager mDreamManager;
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
@@ -39,8 +41,10 @@
};
@Inject
- public DreamCondition(Context context) {
+ public DreamCondition(Context context,
+ DreamManager dreamManager) {
mContext = context;
+ mDreamManager = dreamManager;
}
private void processIntent(Intent intent) {
@@ -62,8 +66,8 @@
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_DREAMING_STARTED);
filter.addAction(Intent.ACTION_DREAMING_STOPPED);
- final Intent stickyIntent = mContext.registerReceiver(mReceiver, filter);
- processIntent(stickyIntent);
+ mContext.registerReceiver(mReceiver, filter);
+ updateCondition(mDreamManager.isDreaming());
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
index 5c310c3..2c11d78 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebug.java
@@ -86,9 +86,34 @@
private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
new ServerFlagReader.ChangeListener() {
@Override
- public void onChange(Flag<?> flag) {
- mRestarter.restartSystemUI(
- "Server flag change: " + flag.getNamespace() + "." + flag.getName());
+ public void onChange(Flag<?> flag, String value) {
+ boolean shouldRestart = false;
+ if (mBooleanFlagCache.containsKey(flag.getName())) {
+ boolean newValue = value == null ? false : Boolean.parseBoolean(value);
+ if (mBooleanFlagCache.get(flag.getName()) != newValue) {
+ shouldRestart = true;
+ }
+ } else if (mStringFlagCache.containsKey(flag.getName())) {
+ String newValue = value == null ? "" : value;
+ if (mStringFlagCache.get(flag.getName()) != value) {
+ shouldRestart = true;
+ }
+ } else if (mIntFlagCache.containsKey(flag.getName())) {
+ int newValue = 0;
+ try {
+ newValue = value == null ? 0 : Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ }
+ if (mIntFlagCache.get(flag.getName()) != newValue) {
+ shouldRestart = true;
+ }
+ }
+ if (shouldRestart) {
+ mRestarter.restartSystemUI(
+ "Server flag change: " + flag.getNamespace() + "."
+ + flag.getName());
+
+ }
}
};
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt
index 06ca0ad..28c45b8 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsDebugStartable.kt
@@ -22,7 +22,6 @@
import com.android.systemui.dump.DumpManager
import com.android.systemui.statusbar.commandline.CommandRegistry
import com.android.systemui.util.InitializationChecker
-import com.android.systemui.util.concurrency.DelayableExecutor
import dagger.Binds
import dagger.Module
import dagger.multibindings.ClassKey
@@ -38,8 +37,6 @@
private val featureFlags: FeatureFlagsDebug,
private val broadcastSender: BroadcastSender,
private val initializationChecker: InitializationChecker,
- private val restartDozeListener: RestartDozeListener,
- private val delayableExecutor: DelayableExecutor
) : CoreStartable {
init {
@@ -55,9 +52,6 @@
// protected broadcast should only be sent for the main process
val intent = Intent(FlagManager.ACTION_SYSUI_STARTED)
broadcastSender.sendBroadcast(intent)
-
- restartDozeListener.init()
- delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000)
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
index 9859ff6..9d19a7d 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsRelease.java
@@ -53,13 +53,38 @@
private final Map<String, Flag<?>> mAllFlags;
private final Map<String, Boolean> mBooleanCache = new HashMap<>();
private final Map<String, String> mStringCache = new HashMap<>();
+ private final Map<String, Integer> mIntCache = new HashMap<>();
private final ServerFlagReader.ChangeListener mOnPropertiesChanged =
new ServerFlagReader.ChangeListener() {
@Override
- public void onChange(Flag<?> flag) {
- mRestarter.restartSystemUI(
- "Server flag change: " + flag.getNamespace() + "." + flag.getName());
+ public void onChange(Flag<?> flag, String value) {
+ boolean shouldRestart = false;
+ if (mBooleanCache.containsKey(flag.getName())) {
+ boolean newValue = value == null ? false : Boolean.parseBoolean(value);
+ if (mBooleanCache.get(flag.getName()) != newValue) {
+ shouldRestart = true;
+ }
+ } else if (mStringCache.containsKey(flag.getName())) {
+ String newValue = value == null ? "" : value;
+ if (mStringCache.get(flag.getName()) != newValue) {
+ shouldRestart = true;
+ }
+ } else if (mIntCache.containsKey(flag.getName())) {
+ int newValue = 0;
+ try {
+ newValue = value == null ? 0 : Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ }
+ if (mIntCache.get(flag.getName()) != newValue) {
+ shouldRestart = true;
+ }
+ }
+ if (shouldRestart) {
+ mRestarter.restartSystemUI(
+ "Server flag change: " + flag.getNamespace() + "."
+ + flag.getName());
+ }
}
};
@@ -97,68 +122,97 @@
@Override
public boolean isEnabled(@NotNull ReleasedFlag flag) {
- return mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true);
+ // Fill the cache.
+ return isEnabledInternal(flag.getName(),
+ mServerFlagReader.readServerOverride(flag.getNamespace(), flag.getName(), true));
}
@Override
public boolean isEnabled(ResourceBooleanFlag flag) {
- if (!mBooleanCache.containsKey(flag.getName())) {
- return isEnabled(flag.getName(), mResources.getBoolean(flag.getResourceId()));
- }
-
- return mBooleanCache.get(flag.getName());
+ // Fill the cache.
+ return isEnabledInternal(flag.getName(), mResources.getBoolean(flag.getResourceId()));
}
@Override
public boolean isEnabled(SysPropBooleanFlag flag) {
- if (!mBooleanCache.containsKey(flag.getName())) {
- return isEnabled(
- flag.getName(),
- mSystemProperties.getBoolean(flag.getName(), flag.getDefault()));
- }
-
- return mBooleanCache.get(flag.getName());
+ // Fill the cache.
+ return isEnabledInternal(
+ flag.getName(),
+ mSystemProperties.getBoolean(flag.getName(), flag.getDefault()));
}
- private boolean isEnabled(String name, boolean defaultValue) {
- mBooleanCache.put(name, defaultValue);
- return defaultValue;
+ /**
+ * Checks and fills the boolean cache. This is important, Always call through to this method!
+ *
+ * We use the cache as a way to decide if we need to restart the process when server-side
+ * changes occur.
+ */
+ private boolean isEnabledInternal(String name, boolean defaultValue) {
+ // Fill the cache.
+ if (!mBooleanCache.containsKey(name)) {
+ mBooleanCache.put(name, defaultValue);
+ }
+
+ return mBooleanCache.get(name);
}
@NonNull
@Override
public String getString(@NonNull StringFlag flag) {
- return getString(flag.getName(), flag.getDefault());
+ // Fill the cache.
+ return getStringInternal(flag.getName(), flag.getDefault());
}
@NonNull
@Override
public String getString(@NonNull ResourceStringFlag flag) {
- if (!mStringCache.containsKey(flag.getName())) {
- return getString(flag.getName(),
- requireNonNull(mResources.getString(flag.getResourceId())));
- }
-
- return mStringCache.get(flag.getName());
+ // Fill the cache.
+ return getStringInternal(flag.getName(),
+ requireNonNull(mResources.getString(flag.getResourceId())));
}
- private String getString(String name, String defaultValue) {
- mStringCache.put(name, defaultValue);
- return defaultValue;
+ /**
+ * Checks and fills the String cache. This is important, Always call through to this method!
+ *
+ * We use the cache as a way to decide if we need to restart the process when server-side
+ * changes occur.
+ */
+ private String getStringInternal(String name, String defaultValue) {
+ if (!mStringCache.containsKey(name)) {
+ mStringCache.put(name, defaultValue);
+ }
+
+ return mStringCache.get(name);
}
@NonNull
@Override
public int getInt(@NonNull IntFlag flag) {
- return flag.getDefault();
+ // Fill the cache.
+ return getIntInternal(flag.getName(), flag.getDefault());
}
@NonNull
@Override
public int getInt(@NonNull ResourceIntFlag flag) {
+ // Fill the cache.
return mResources.getInteger(flag.getResourceId());
}
+ /**
+ * Checks and fills the integer cache. This is important, Always call through to this method!
+ *
+ * We use the cache as a way to decide if we need to restart the process when server-side
+ * changes occur.
+ */
+ private int getIntInternal(String name, int defaultValue) {
+ if (!mIntCache.containsKey(name)) {
+ mIntCache.put(name, defaultValue);
+ }
+
+ return mIntCache.get(name);
+ }
+
@Override
public void dump(@NonNull PrintWriter pw, @NonNull String[] args) {
pw.println("can override: false");
diff --git a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt
index 133e67f..f97112d 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/FeatureFlagsReleaseStartable.kt
@@ -18,8 +18,6 @@
import com.android.systemui.CoreStartable
import com.android.systemui.dump.DumpManager
-import com.android.systemui.util.InitializationChecker
-import com.android.systemui.util.concurrency.DelayableExecutor
import dagger.Binds
import dagger.Module
import dagger.multibindings.ClassKey
@@ -31,9 +29,6 @@
constructor(
dumpManager: DumpManager,
featureFlags: FeatureFlags,
- private val initializationChecker: InitializationChecker,
- private val restartDozeListener: RestartDozeListener,
- private val delayableExecutor: DelayableExecutor
) : CoreStartable {
init {
@@ -42,12 +37,7 @@
}
}
- override fun start() {
- if (initializationChecker.initializeComponents()) {
- restartDozeListener.init()
- delayableExecutor.executeDelayed({ restartDozeListener.maybeRestartSleep() }, 1000)
- }
- }
+ override fun start() {}
}
@Module
diff --git a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
index de44d60..399f2c6 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/Flags.kt
@@ -214,11 +214,25 @@
"lock_screen_long_press_enabled"
)
+ /** Enables UI updates for AI wallpapers in the wallpaper picker. */
+ // TODO(b/267722622): Tracking Bug
+ @JvmField
+ val WALLPAPER_PICKER_UI_FOR_AIWP =
+ releasedFlag(
+ 229,
+ "wallpaper_picker_ui_for_aiwp"
+ )
+
/** Whether to inflate the bouncer view on a background thread. */
// TODO(b/272091103): Tracking Bug
@JvmField
val ASYNC_INFLATE_BOUNCER = unreleasedFlag(229, "async_inflate_bouncer", teamfood = true)
+ /** Whether to inflate the bouncer view on a background thread. */
+ // TODO(b/273341787): Tracking Bug
+ @JvmField
+ val PREVENT_BYPASS_KEYGUARD = unreleasedFlag(230, "prevent_bypass_keyguard")
+
// 300 - power menu
// TODO(b/254512600): Tracking Bug
@JvmField val POWER_MENU_LITE = releasedFlag(300, "power_menu_lite")
@@ -236,12 +250,21 @@
// TODO(b/270223352): Tracking Bug
@JvmField
- val HIDE_SMARTSPACE_ON_DREAM_OVERLAY = unreleasedFlag(404, "hide_smartspace_on_dream_overlay")
+ val HIDE_SMARTSPACE_ON_DREAM_OVERLAY =
+ unreleasedFlag(
+ 404,
+ "hide_smartspace_on_dream_overlay",
+ teamfood = true
+ )
// TODO(b/271460958): Tracking Bug
@JvmField
- val SHOW_WEATHER_COMPLICATION_ON_DREAM_OVERLAY = unreleasedFlag(405,
- "show_weather_complication_on_dream_overlay")
+ val SHOW_WEATHER_COMPLICATION_ON_DREAM_OVERLAY =
+ unreleasedFlag(
+ 405,
+ "show_weather_complication_on_dream_overlay",
+ teamfood = true
+ )
// 500 - quick settings
@@ -392,7 +415,7 @@
@JvmField val ROUNDED_BOX_RIPPLE = releasedFlag(1002, "rounded_box_ripple")
// TODO(b/270882464): Tracking Bug
- val ENABLE_DOCK_SETUP_V2 = unreleasedFlag(1005, "enable_dock_setup_v2", teamfood = true)
+ val ENABLE_DOCK_SETUP_V2 = releasedFlag(1005, "enable_dock_setup_v2")
// TODO(b/265045965): Tracking Bug
val SHOW_LOWLIGHT_ON_DIRECT_BOOT = releasedFlag(1003, "show_lowlight_on_direct_boot")
@@ -452,7 +475,7 @@
sysPropBooleanFlag(
1110,
"persist.wm.debug.enable_pip_keep_clear_algorithm",
- default = false
+ default = true
)
// TODO(b/256873975): Tracking Bug
@@ -522,7 +545,7 @@
// TODO(b/270987164): Tracking Bug
@JvmField
- val TRACKPAD_GESTURE_BACK = unreleasedFlag(1205, "trackpad_gesture_back", teamfood = true)
+ val TRACKPAD_GESTURE_FEATURES = releasedFlag(1205, "trackpad_gesture_features")
// TODO(b/263826204): Tracking Bug
@JvmField
@@ -544,6 +567,10 @@
val WM_ENABLE_PREDICTIVE_BACK_QS_DIALOG_ANIM =
unreleasedFlag(1209, "persist.wm.debug.predictive_back_qs_dialog_anim", teamfood = true)
+ // TODO(b/273800936): Tracking Bug
+ @JvmField
+ val TRACKPAD_GESTURE_COMMON = releasedFlag(1210, "trackpad_gesture_common")
+
// 1300 - screenshots
// TODO(b/254513155): Tracking Bug
@JvmField
@@ -657,13 +684,18 @@
val ENABLE_DARK_VIGNETTE_WHEN_FOLDING =
unreleasedFlag(2700, "enable_dark_vignette_when_folding")
+ // TODO(b/265764985): Tracking Bug
+ @Keep
+ @JvmField
+ val ENABLE_UNFOLD_STATUS_BAR_ANIMATIONS =
+ unreleasedFlag(2701, "enable_unfold_status_bar_animations")
+
// TODO(b259590361): Tracking bug
val EXPERIMENTAL_FLAG = unreleasedFlag(2, "exp_flag_release")
// 2600 - keyboard
// TODO(b/259352579): Tracking Bug
- @JvmField val SHORTCUT_LIST_SEARCH_LAYOUT =
- unreleasedFlag(2600, "shortcut_list_search_layout", teamfood = true)
+ @JvmField val SHORTCUT_LIST_SEARCH_LAYOUT = releasedFlag(2600, "shortcut_list_search_layout")
// TODO(b/259428678): Tracking Bug
@JvmField
@@ -674,4 +706,9 @@
@JvmField
val LARGE_SHADE_GRANULAR_ALPHA_INTERPOLATION =
unreleasedFlag(2602, "large_shade_granular_alpha_interpolation", teamfood = true)
+
+ // TODO(b/272805037): Tracking Bug
+ @JvmField
+ val ADVANCED_VPN_ENABLED = unreleasedFlag(2800, name = "AdvancedVpn__enable_feature",
+ namespace = "vpn", teamfood = true)
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt b/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt
index bd74f4e..b49d60d 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/RestartDozeListener.kt
@@ -20,7 +20,9 @@
import android.util.Log
import com.android.internal.annotations.VisibleForTesting
import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.dagger.qualifiers.Background
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.util.concurrency.DelayableExecutor
import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.time.SystemClock
import javax.inject.Inject
@@ -33,6 +35,7 @@
private val statusBarStateController: StatusBarStateController,
private val powerManager: PowerManager,
private val systemClock: SystemClock,
+ @Background val bgExecutor: DelayableExecutor,
) {
companion object {
@@ -44,7 +47,7 @@
val listener =
object : StatusBarStateController.StateListener {
override fun onDreamingChanged(isDreaming: Boolean) {
- settings.putBool(RESTART_NAP_KEY, isDreaming)
+ storeSleepState(isDreaming)
}
}
@@ -62,11 +65,19 @@
}
fun maybeRestartSleep() {
- if (settings.getBool(RESTART_NAP_KEY, false)) {
- Log.d("RestartDozeListener", "Restarting sleep state")
- powerManager.wakeUp(systemClock.uptimeMillis())
- powerManager.goToSleep(systemClock.uptimeMillis())
- settings.putBool(RESTART_NAP_KEY, false)
- }
+ bgExecutor.executeDelayed(
+ {
+ if (settings.getBool(RESTART_NAP_KEY, false)) {
+ Log.d("RestartDozeListener", "Restarting sleep state")
+ powerManager.wakeUp(systemClock.uptimeMillis())
+ powerManager.goToSleep(systemClock.uptimeMillis())
+ }
+ },
+ 1000
+ )
+ }
+
+ private fun storeSleepState(sleeping: Boolean) {
+ bgExecutor.execute { settings.putBool(RESTART_NAP_KEY, sleeping) }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
index 9b748d0..eaf5eac 100644
--- a/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
+++ b/packages/SystemUI/src/com/android/systemui/flags/ServerFlagReader.kt
@@ -37,7 +37,7 @@
fun listenForChanges(values: Collection<Flag<*>>, listener: ChangeListener)
interface ChangeListener {
- fun onChange(flag: Flag<*>)
+ fun onChange(flag: Flag<*>, value: String?)
}
}
@@ -67,7 +67,7 @@
propLoop@ for (propName in properties.keyset) {
for (flag in flags) {
if (propName == flag.name) {
- listener.onChange(flag)
+ listener.onChange(flag, properties.getString(propName, null))
break@propLoop
}
}
@@ -144,7 +144,7 @@
for ((listener, flags) in listeners) {
flagLoop@ for (flag in flags) {
if (name == flag.name) {
- listener.onChange(flag)
+ listener.onChange(flag, if (value) "true" else "false")
break@flagLoop
}
}
@@ -159,5 +159,6 @@
flags: Collection<Flag<*>>,
listener: ServerFlagReader.ChangeListener
) {
+ listeners.add(Pair(listener, flags))
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
index eae40d6..aad4a2d 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractor.kt
@@ -23,6 +23,7 @@
import com.android.systemui.keyguard.data.repository.BiometricSettingsRepository
import com.android.systemui.keyguard.data.repository.DeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
+import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager.LegacyAlternateBouncer
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.time.SystemClock
@@ -34,6 +35,7 @@
class AlternateBouncerInteractor
@Inject
constructor(
+ private val statusBarStateController: StatusBarStateController,
private val keyguardStateController: KeyguardStateController,
private val bouncerRepository: KeyguardBouncerRepository,
private val biometricSettingsRepository: BiometricSettingsRepository,
@@ -46,8 +48,20 @@
var legacyAlternateBouncer: LegacyAlternateBouncer? = null
var legacyAlternateBouncerVisibleTime: Long = NOT_VISIBLE
+ var receivedDownTouch = false
val isVisible: Flow<Boolean> = bouncerRepository.alternateBouncerVisible
+ private val keyguardStateControllerCallback: KeyguardStateController.Callback =
+ object : KeyguardStateController.Callback {
+ override fun onUnlockedChanged() {
+ maybeHide()
+ }
+ }
+
+ init {
+ keyguardStateController.addCallback(keyguardStateControllerCallback)
+ }
+
/**
* Sets the correct bouncer states to show the alternate bouncer if it can show.
*
@@ -79,6 +93,7 @@
* @return true if the alternate bouncer was newly hidden, else false.
*/
fun hide(): Boolean {
+ receivedDownTouch = false
return if (isModernAlternateBouncerEnabled) {
val wasAlternateBouncerVisible = isVisibleState()
bouncerRepository.setAlternateVisible(false)
@@ -107,7 +122,8 @@
biometricSettingsRepository.isStrongBiometricAllowed.value &&
biometricSettingsRepository.isFingerprintEnabledByDevicePolicy.value &&
!deviceEntryFingerprintAuthRepository.isLockedOut.value &&
- !keyguardStateController.isUnlocked
+ !keyguardStateController.isUnlocked &&
+ !statusBarStateController.isDozing
} else {
legacyAlternateBouncer != null &&
keyguardUpdateMonitor.isUnlockingWithBiometricAllowed(true)
@@ -127,6 +143,12 @@
}
}
+ private fun maybeHide() {
+ if (isVisibleState() && !canShowAlternateBouncerForFingerprint()) {
+ hide()
+ }
+ }
+
companion object {
private const val MIN_VISIBILITY_DURATION_UNTIL_TOUCHES_DISMISS_ALTERNATE_BOUNCER_MS = 200L
private const val NOT_VISIBLE = -1L
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
index 7064827..8448b80 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/domain/interactor/KeyguardQuickAffordanceInteractor.kt
@@ -414,6 +414,10 @@
KeyguardPickerFlag(
name = Contract.FlagsTable.FLAG_NAME_MONOCHROMATIC_THEME,
value = featureFlags.isEnabled(Flags.MONOCHROMATIC_THEME)
+ ),
+ KeyguardPickerFlag(
+ name = Contract.FlagsTable.FLAG_NAME_WALLPAPER_PICKER_UI_FOR_AIWP,
+ value = featureFlags.isEnabled(Flags.WALLPAPER_PICKER_UI_FOR_AIWP)
)
)
}
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
index d246b35e..5704f88 100644
--- a/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/LogModule.java
@@ -136,6 +136,14 @@
return factory.create("NotifSectionLog", 1000 /* maxSize */, false /* systrace */);
}
+ /** Provides a logging buffer for all logs related to remote input controller. */
+ @Provides
+ @SysUISingleton
+ @NotificationRemoteInputLog
+ public static LogBuffer provideNotificationRemoteInputLogBuffer(LogBufferFactory factory) {
+ return factory.create("NotifRemoteInputLog", 50 /* maxSize */, false /* systrace */);
+ }
+
/** Provides a logging buffer for all logs related to the data layer of notifications. */
@Provides
@SysUISingleton
@@ -152,6 +160,14 @@
return factory.create("QSLog", 700 /* maxSize */, false /* systrace */);
}
+ /** Provides a logging buffer for logs related to Quick Settings configuration. */
+ @Provides
+ @SysUISingleton
+ @QSConfigLog
+ public static LogBuffer provideQSConfigLogBuffer(LogBufferFactory factory) {
+ return factory.create("QSConfigLog", 100 /* maxSize */, true /* systrace */);
+ }
+
/** Provides a logging buffer for {@link com.android.systemui.broadcast.BroadcastDispatcher} */
@Provides
@SysUISingleton
diff --git a/core/java/android/service/voice/DetectorFailure.aidl b/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationRemoteInputLog.kt
similarity index 69%
copy from core/java/android/service/voice/DetectorFailure.aidl
copy to packages/SystemUI/src/com/android/systemui/log/dagger/NotificationRemoteInputLog.kt
index 3591329..3a639a0 100644
--- a/core/java/android/service/voice/DetectorFailure.aidl
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/NotificationRemoteInputLog.kt
@@ -14,6 +14,12 @@
* limitations under the License.
*/
-package android.service.voice;
+package com.android.systemui.log.dagger
-parcelable DetectorFailure;
+import javax.inject.Qualifier
+
+/** A [com.android.systemui.log.LogBuffer] for NotificationRemoteInput. */
+@Qualifier
+@MustBeDocumented
+@Retention(AnnotationRetention.RUNTIME)
+annotation class NotificationRemoteInputLog
diff --git a/packages/SystemUI/src/com/android/systemui/log/dagger/QSConfigLog.java b/packages/SystemUI/src/com/android/systemui/log/dagger/QSConfigLog.java
new file mode 100644
index 0000000..295bf88
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/log/dagger/QSConfigLog.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.log.dagger;
+
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import com.android.systemui.plugins.log.LogBuffer;
+
+import java.lang.annotation.Documented;
+import java.lang.annotation.Retention;
+
+import javax.inject.Qualifier;
+
+/** A {@link LogBuffer} for QS configuration changed messages. */
+@Qualifier
+@Documented
+@Retention(RUNTIME)
+public @interface QSConfigLog {
+}
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
index 67d3be4..9c7b48d 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselController.kt
@@ -225,8 +225,10 @@
object : KeyguardUpdateMonitorCallback() {
override fun onStrongAuthStateChanged(userId: Int) {
if (keyguardUpdateMonitor.isUserInLockdown(userId)) {
+ debugLogger.logCarouselHidden()
hideMediaCarousel()
} else if (keyguardUpdateMonitor.isUserUnlocked(userId)) {
+ debugLogger.logCarouselVisible()
showMediaCarousel()
}
}
@@ -298,7 +300,7 @@
receivedSmartspaceCardLatency: Int,
isSsReactivated: Boolean
) {
- debugLogger.logMediaLoaded(key)
+ debugLogger.logMediaLoaded(key, data.active)
if (addOrUpdatePlayer(key, oldKey, data, isSsReactivated)) {
// Log card received if a new resumable media card is added
MediaPlayerData.getMediaPlayer(key)?.let {
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselControllerLogger.kt
index 35bda15..9af11b9 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselControllerLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaCarouselControllerLogger.kt
@@ -42,8 +42,16 @@
}
)
- fun logMediaLoaded(key: String) =
- buffer.log(TAG, LogLevel.DEBUG, { str1 = key }, { "add player $str1" })
+ fun logMediaLoaded(key: String, active: Boolean) =
+ buffer.log(
+ TAG,
+ LogLevel.DEBUG,
+ {
+ str1 = key
+ bool1 = active
+ },
+ { "add player $str1, active: $bool1" }
+ )
fun logMediaRemoved(key: String) =
buffer.log(TAG, LogLevel.DEBUG, { str1 = key }, { "removing player $str1" })
@@ -69,6 +77,10 @@
},
{ "removing recommendation $str1, immediate=$bool1" }
)
+
+ fun logCarouselHidden() = buffer.log(TAG, LogLevel.DEBUG, {}, { "hiding carousel" })
+
+ fun logCarouselVisible() = buffer.log(TAG, LogLevel.DEBUG, {}, { "showing carousel" })
}
private const val TAG = "MediaCarouselCtlrLog"
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
index 00e5aac..15d999a 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaControlPanel.java
@@ -151,7 +151,7 @@
private static final float REC_MEDIA_COVER_SCALE_FACTOR = 1.25f;
private static final float MEDIA_SCRIM_START_ALPHA = 0.25f;
private static final float MEDIA_REC_SCRIM_START_ALPHA = 0.15f;
- private static final float MEDIA_PLAYER_SCRIM_END_ALPHA = 0.9f;
+ private static final float MEDIA_PLAYER_SCRIM_END_ALPHA = 1.0f;
private static final float MEDIA_REC_SCRIM_END_ALPHA = 1.0f;
private static final Intent SETTINGS_INTENT = new Intent(ACTION_MEDIA_CONTROLS_SETTINGS);
@@ -647,14 +647,17 @@
} else {
mLogger.logOpenOutputSwitcher(mUid, mPackageName, mInstanceId);
if (device.getIntent() != null) {
- if (device.getIntent().isActivity()) {
- mActivityStarter.startActivity(
- device.getIntent().getIntent(), true);
+ PendingIntent deviceIntent = device.getIntent();
+ boolean showOverLockscreen = mKeyguardStateController.isShowing()
+ && mActivityIntentHelper.wouldPendingShowOverLockscreen(
+ deviceIntent, mLockscreenUserManager.getCurrentUserId());
+ if (deviceIntent.isActivity() && !showOverLockscreen) {
+ mActivityStarter.postStartActivityDismissingKeyguard(deviceIntent);
} else {
try {
BroadcastOptions options = BroadcastOptions.makeBasic();
options.setInteractive(true);
- device.getIntent().send(options.toBundle());
+ deviceIntent.send(options.toBundle());
} catch (PendingIntent.CanceledException e) {
Log.e(TAG, "Device pending intent was canceled");
}
@@ -1373,7 +1376,8 @@
itemIndex
);
} else {
- mediaCoverImageView.setImageIcon(recommendation.getIcon());
+ mediaCoverImageView.post(
+ () -> mediaCoverImageView.setImageIcon(recommendation.getIcon()));
}
// Set up the media item's click listener if applicable.
diff --git a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
index b4724dd..7a1302c 100644
--- a/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/controls/ui/MediaViewController.kt
@@ -89,6 +89,9 @@
R.id.turbulence_noise_view,
R.id.touch_ripple_view,
)
+
+ // Sizing view id for recommendation card view.
+ val recSizingViewId = R.id.sizing_view
}
/** A listener when the current dimensions of the player change */
@@ -176,7 +179,21 @@
// Layout dimensions are possibly changing, so we need to update them. (at
// least on large screen devices)
lastOrientation = newOrientation
- loadLayoutForType(type)
+ // Update the height of media controls for the expanded layout. it is needed
+ // for large screen devices.
+ if (type == TYPE.PLAYER) {
+ backgroundIds.forEach { id ->
+ expandedLayout.getConstraint(id).layout.mHeight =
+ context.resources.getDimensionPixelSize(
+ R.dimen.qs_media_session_height_expanded
+ )
+ }
+ } else {
+ expandedLayout.getConstraint(recSizingViewId).layout.mHeight =
+ context.resources.getDimensionPixelSize(
+ R.dimen.qs_media_session_height_expanded
+ )
+ }
}
}
}
@@ -602,7 +619,11 @@
tmpState
)
}
- logger.logMediaSize("setCurrentState", result.width, result.height)
+ logger.logMediaSize(
+ "setCurrentState (progress $transitionProgress)",
+ result.width,
+ result.height
+ )
layoutController.setState(
result,
applyImmediately,
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
index ee93c37..dbc2a5e 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/common/MediaTttUtils.kt
@@ -19,12 +19,13 @@
import android.content.Context
import android.content.pm.PackageManager
import android.graphics.drawable.Drawable
-import androidx.annotation.AttrRes
+import androidx.annotation.ColorRes
import androidx.annotation.DrawableRes
import com.android.systemui.R
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.Icon
import com.android.systemui.common.shared.model.TintedIcon
+import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo.Companion.DEFAULT_ICON_TINT
/** Utility methods for media tap-to-transfer. */
class MediaTttUtils {
@@ -78,7 +79,7 @@
return IconInfo(
contentDescription,
MediaTttIcon.Loaded(packageManager.getApplicationIcon(appPackageName)),
- tintAttr = null,
+ tint = null,
isAppIcon = true
)
} catch (e: PackageManager.NameNotFoundException) {
@@ -96,7 +97,7 @@
)
},
MediaTttIcon.Resource(R.drawable.ic_cast),
- tintAttr = android.R.attr.textColorPrimary,
+ tint = DEFAULT_ICON_TINT,
isAppIcon = false
)
}
@@ -107,7 +108,7 @@
data class IconInfo(
val contentDescription: ContentDescription,
val icon: MediaTttIcon,
- @AttrRes val tintAttr: Int?,
+ @ColorRes val tint: Int?,
/**
* True if [drawable] is the app's icon, and false if [drawable] is some generic default icon.
*/
@@ -120,7 +121,7 @@
is MediaTttIcon.Loaded -> Icon.Loaded(icon.drawable, contentDescription)
is MediaTttIcon.Resource -> Icon.Resource(icon.res, contentDescription)
}
- return TintedIcon(iconOutput, tintAttr)
+ return TintedIcon(iconOutput, tint)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
index fab8c06..78082c3 100644
--- a/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
+++ b/packages/SystemUI/src/com/android/systemui/media/taptotransfer/receiver/MediaTttChipControllerReceiver.kt
@@ -225,8 +225,10 @@
val iconRippleView: ReceiverChipRippleView = view.requireViewById(R.id.icon_glow_ripple)
val rippleView: ReceiverChipRippleView = view.requireViewById(R.id.ripple)
val translationYBy = getTranslationAmount()
+ // Expand ripple before translating icon container to make sure both views have same bounds.
+ rippleController.expandToInProgressState(rippleView, iconRippleView)
// Make the icon container view starts animation from bottom of the screen.
- iconContainerView.translationY += rippleController.getReceiverIconSize()
+ iconContainerView.translationY = rippleController.getReceiverIconSize().toFloat()
animateViewTranslationAndFade(
iconContainerView,
translationYBy = -1 * translationYBy,
@@ -235,7 +237,6 @@
) {
animateBouncingView(iconContainerView, translationYBy * BOUNCE_TRANSLATION_RATIO)
}
- rippleController.expandToInProgressState(rippleView, iconRippleView)
}
override fun animateViewOut(view: ViewGroup, removalReason: String?, onAnimationEnd: Runnable) {
@@ -293,7 +294,7 @@
/** Returns the amount that the chip will be translated by in its intro animation. */
private fun getTranslationAmount(): Float {
- return rippleController.getRippleSize() * 0.5f
+ return rippleController.getReceiverIconSize() * 2f
}
private fun View.getAppIconView(): CachingIconView {
diff --git a/packages/SystemUI/src/com/android/systemui/multishade/domain/interactor/MultiShadeInteractor.kt b/packages/SystemUI/src/com/android/systemui/multishade/domain/interactor/MultiShadeInteractor.kt
index b9f6d83..ebb8639 100644
--- a/packages/SystemUI/src/com/android/systemui/multishade/domain/interactor/MultiShadeInteractor.kt
+++ b/packages/SystemUI/src/com/android/systemui/multishade/domain/interactor/MultiShadeInteractor.kt
@@ -23,6 +23,7 @@
import com.android.systemui.multishade.data.model.MultiShadeInteractionModel
import com.android.systemui.multishade.data.remoteproxy.MultiShadeInputProxy
import com.android.systemui.multishade.data.repository.MultiShadeRepository
+import com.android.systemui.multishade.shared.math.isZero
import com.android.systemui.multishade.shared.model.ProxiedInputModel
import com.android.systemui.multishade.shared.model.ShadeConfig
import com.android.systemui.multishade.shared.model.ShadeId
@@ -63,6 +64,10 @@
}
}
+ /** Whether any shade is expanded, even a little bit. */
+ val isAnyShadeExpanded: Flow<Boolean> =
+ maxShadeExpansion.map { maxExpansion -> !maxExpansion.isZero() }.distinctUntilChanged()
+
/**
* A _processed_ version of the proxied input flow.
*
diff --git a/packages/SystemUI/src/com/android/systemui/multishade/domain/interactor/MultiShadeMotionEventInteractor.kt b/packages/SystemUI/src/com/android/systemui/multishade/domain/interactor/MultiShadeMotionEventInteractor.kt
new file mode 100644
index 0000000..ff7c901
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/multishade/domain/interactor/MultiShadeMotionEventInteractor.kt
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.multishade.domain.interactor
+
+import android.content.Context
+import android.view.MotionEvent
+import android.view.ViewConfiguration
+import com.android.systemui.dagger.qualifiers.Application
+import com.android.systemui.multishade.shared.model.ProxiedInputModel
+import javax.inject.Inject
+import kotlin.math.abs
+import kotlinx.coroutines.CoroutineScope
+import kotlinx.coroutines.flow.SharingStarted
+import kotlinx.coroutines.flow.StateFlow
+import kotlinx.coroutines.flow.stateIn
+
+/**
+ * Encapsulates business logic to handle [MotionEvent]-based user input.
+ *
+ * This class is meant purely for the legacy `View`-based system to be able to pass `MotionEvent`s
+ * into the newer multi-shade framework for processing.
+ */
+class MultiShadeMotionEventInteractor
+@Inject
+constructor(
+ @Application private val applicationContext: Context,
+ @Application private val applicationScope: CoroutineScope,
+ private val interactor: MultiShadeInteractor,
+) {
+
+ private val isAnyShadeExpanded: StateFlow<Boolean> =
+ interactor.isAnyShadeExpanded.stateIn(
+ scope = applicationScope,
+ started = SharingStarted.Eagerly,
+ initialValue = false,
+ )
+
+ private var interactionState: InteractionState? = null
+
+ /**
+ * Returns `true` if the given [MotionEvent] and the rest of events in this gesture should be
+ * passed to this interactor's [onTouchEvent] method.
+ *
+ * Note: the caller should continue to pass [MotionEvent] instances into this method, even if it
+ * returns `false` as the gesture may be intercepted mid-stream.
+ */
+ fun shouldIntercept(event: MotionEvent): Boolean {
+ if (isAnyShadeExpanded.value) {
+ // If any shade is expanded, we assume that touch handling outside the shades is handled
+ // by the scrim that appears behind the shades. No need to intercept anything here.
+ return false
+ }
+
+ return when (event.actionMasked) {
+ MotionEvent.ACTION_DOWN -> {
+ // Record where the pointer was placed and which pointer it was.
+ interactionState =
+ InteractionState(
+ initialX = event.x,
+ initialY = event.y,
+ currentY = event.y,
+ pointerId = event.getPointerId(0),
+ isDraggingHorizontally = false,
+ isDraggingVertically = false,
+ )
+
+ false
+ }
+ MotionEvent.ACTION_MOVE -> {
+ interactionState?.let {
+ val pointerIndex = event.findPointerIndex(it.pointerId)
+ val currentX = event.getX(pointerIndex)
+ val currentY = event.getY(pointerIndex)
+ if (!it.isDraggingHorizontally && !it.isDraggingVertically) {
+ val xDistanceTravelled = abs(currentX - it.initialX)
+ val yDistanceTravelled = abs(currentY - it.initialY)
+ val touchSlop = ViewConfiguration.get(applicationContext).scaledTouchSlop
+ interactionState =
+ when {
+ yDistanceTravelled > touchSlop ->
+ it.copy(isDraggingVertically = true)
+ xDistanceTravelled > touchSlop ->
+ it.copy(isDraggingHorizontally = true)
+ else -> interactionState
+ }
+ }
+ }
+
+ // We want to intercept the rest of the gesture if we're dragging.
+ interactionState.isDraggingVertically()
+ }
+ MotionEvent.ACTION_UP,
+ MotionEvent.ACTION_CANCEL ->
+ // Make sure that we intercept the up or cancel if we're dragging, to handle drag
+ // end and cancel.
+ interactionState.isDraggingVertically()
+ else -> false
+ }
+ }
+
+ /**
+ * Notifies that a [MotionEvent] in a series of events of a gesture that was intercepted due to
+ * the result of [shouldIntercept] has been received.
+ *
+ * @param event The [MotionEvent] to handle.
+ * @param viewWidthPx The width of the view, in pixels.
+ * @return `true` if the event was consumed, `false` otherwise.
+ */
+ fun onTouchEvent(event: MotionEvent, viewWidthPx: Int): Boolean {
+ return when (event.actionMasked) {
+ MotionEvent.ACTION_MOVE -> {
+ interactionState?.let {
+ if (it.isDraggingVertically) {
+ val pointerIndex = event.findPointerIndex(it.pointerId)
+ val previousY = it.currentY
+ val currentY = event.getY(pointerIndex)
+ interactionState =
+ it.copy(
+ currentY = currentY,
+ )
+
+ val yDragAmountPx = currentY - previousY
+ if (yDragAmountPx != 0f) {
+ interactor.sendProxiedInput(
+ ProxiedInputModel.OnDrag(
+ xFraction = event.x / viewWidthPx,
+ yDragAmountPx = yDragAmountPx,
+ )
+ )
+ }
+ }
+ }
+
+ true
+ }
+ MotionEvent.ACTION_UP -> {
+ if (interactionState.isDraggingVertically()) {
+ // We finished dragging. Record that so the multi-shade framework can issue a
+ // fling, if the velocity reached in the drag was high enough, for example.
+ interactor.sendProxiedInput(ProxiedInputModel.OnDragEnd)
+ }
+
+ interactionState = null
+ true
+ }
+ MotionEvent.ACTION_CANCEL -> {
+ if (interactionState.isDraggingVertically()) {
+ // Our drag gesture was canceled by the system. This happens primarily in one of
+ // two occasions: (a) the parent view has decided to intercept the gesture
+ // itself and/or route it to a different child view or (b) the pointer has
+ // traveled beyond the bounds of our view and/or the touch display. Either way,
+ // we pass the cancellation event to the multi-shade framework to record it.
+ // Doing that allows the multi-shade framework to know that the gesture ended to
+ // allow new gestures to be accepted.
+ interactor.sendProxiedInput(ProxiedInputModel.OnDragCancel)
+ }
+
+ interactionState = null
+ true
+ }
+ else -> false
+ }
+ }
+
+ private data class InteractionState(
+ val initialX: Float,
+ val initialY: Float,
+ val currentY: Float,
+ val pointerId: Int,
+ val isDraggingHorizontally: Boolean,
+ val isDraggingVertically: Boolean,
+ )
+
+ private fun InteractionState?.isDraggingVertically(): Boolean {
+ return this?.isDraggingVertically == true
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/multishade/shared/math/Math.kt b/packages/SystemUI/src/com/android/systemui/multishade/shared/math/Math.kt
new file mode 100644
index 0000000..c2eaf72
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/multishade/shared/math/Math.kt
@@ -0,0 +1,27 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.multishade.shared.math
+
+import androidx.annotation.VisibleForTesting
+import kotlin.math.abs
+
+/** Returns `true` if this [Float] is within [epsilon] of `0`. */
+fun Float.isZero(epsilon: Float = EPSILON): Boolean {
+ return abs(this) < epsilon
+}
+
+@VisibleForTesting private const val EPSILON = 0.0001f
diff --git a/packages/SystemUI/src/com/android/systemui/multishade/ui/view/MultiShadeView.kt b/packages/SystemUI/src/com/android/systemui/multishade/ui/view/MultiShadeView.kt
new file mode 100644
index 0000000..aecec39
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/multishade/ui/view/MultiShadeView.kt
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ */
+
+package com.android.systemui.multishade.ui.view
+
+import android.content.Context
+import android.util.AttributeSet
+import android.widget.FrameLayout
+import androidx.lifecycle.Lifecycle
+import androidx.lifecycle.lifecycleScope
+import androidx.lifecycle.repeatOnLifecycle
+import com.android.systemui.compose.ComposeFacade
+import com.android.systemui.lifecycle.repeatWhenAttached
+import com.android.systemui.multishade.domain.interactor.MultiShadeInteractor
+import com.android.systemui.multishade.ui.viewmodel.MultiShadeViewModel
+import com.android.systemui.util.time.SystemClock
+import kotlinx.coroutines.launch
+
+/**
+ * View that hosts the multi-shade system and acts as glue between legacy code and the
+ * implementation.
+ */
+class MultiShadeView(
+ context: Context,
+ attrs: AttributeSet?,
+) :
+ FrameLayout(
+ context,
+ attrs,
+ ) {
+
+ fun init(
+ interactor: MultiShadeInteractor,
+ clock: SystemClock,
+ ) {
+ repeatWhenAttached {
+ lifecycleScope.launch {
+ repeatOnLifecycle(Lifecycle.State.CREATED) {
+ addView(
+ ComposeFacade.createMultiShadeView(
+ context = context,
+ viewModel =
+ MultiShadeViewModel(
+ viewModelScope = this,
+ interactor = interactor,
+ ),
+ clock = clock,
+ )
+ )
+ }
+
+ // Here when destroyed.
+ removeAllViews()
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/multishade/ui/viewmodel/MultiShadeViewModel.kt b/packages/SystemUI/src/com/android/systemui/multishade/ui/viewmodel/MultiShadeViewModel.kt
index ce6ab97..ed92c54 100644
--- a/packages/SystemUI/src/com/android/systemui/multishade/ui/viewmodel/MultiShadeViewModel.kt
+++ b/packages/SystemUI/src/com/android/systemui/multishade/ui/viewmodel/MultiShadeViewModel.kt
@@ -26,7 +26,6 @@
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.combine
-import kotlinx.coroutines.flow.distinctUntilChanged
import kotlinx.coroutines.flow.flatMapLatest
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.map
@@ -87,10 +86,7 @@
when (shadeConfig) {
// In the dual shade configuration, the scrim is enabled when the expansion is
// greater than zero on any one of the shades.
- is ShadeConfig.DualShadeConfig ->
- interactor.maxShadeExpansion
- .map { expansion -> expansion > 0 }
- .distinctUntilChanged()
+ is ShadeConfig.DualShadeConfig -> interactor.isAnyShadeExpanded
// No scrim in the single shade configuration.
is ShadeConfig.SingleShadeConfig -> flowOf(false)
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
index 80ed08c..e7bb6dc 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/BackPanelController.kt
@@ -53,11 +53,14 @@
private const val PX_PER_SEC = 1000
private const val PX_PER_MS = 1
-internal const val MIN_DURATION_ACTIVE_ANIMATION = 300L
+internal const val MIN_DURATION_ACTIVE_BEFORE_INACTIVE_ANIMATION = 300L
+private const val MIN_DURATION_ACTIVE_AFTER_INACTIVE_ANIMATION = 130L
private const val MIN_DURATION_CANCELLED_ANIMATION = 200L
private const val MIN_DURATION_COMMITTED_ANIMATION = 120L
private const val MIN_DURATION_INACTIVE_BEFORE_FLUNG_ANIMATION = 50L
-private const val MIN_DURATION_CONSIDERED_AS_FLING = 100L
+
+private const val MIN_DURATION_ENTRY_TO_ACTIVE_CONSIDERED_AS_FLING = 100L
+private const val MIN_DURATION_INACTIVE_TO_ACTIVE_CONSIDERED_AS_FLING = 400L
private const val FAILSAFE_DELAY_MS = 350L
private const val POP_ON_FLING_DELAY = 140L
@@ -145,12 +148,12 @@
private var startY = 0f
private var startIsLeft: Boolean? = null
- private var gestureSinceActionDown = 0L
private var gestureEntryTime = 0L
+ private var gestureInactiveTime = 0L
private var gestureActiveTime = 0L
- private val elapsedTimeSinceActionDown
- get() = SystemClock.uptimeMillis() - gestureSinceActionDown
+ private val elapsedTimeSinceInactive
+ get() = SystemClock.uptimeMillis() - gestureInactiveTime
private val elapsedTimeSinceEntry
get() = SystemClock.uptimeMillis() - gestureEntryTime
@@ -158,6 +161,9 @@
// so that we can unambiguously start showing the ENTRY animation
private var hasPassedDragSlop = false
+ // Distance in pixels a drag can be considered for a fling event
+ private var minFlingDistance = 0
+
private val failsafeRunnable = Runnable { onFailsafe() }
internal enum class GestureState {
@@ -235,6 +241,7 @@
private fun updateConfiguration() {
params.update(resources)
mView.updateArrowPaint(params.arrowThickness)
+ minFlingDistance = ViewConfiguration.get(context).scaledTouchSlop * 3
}
private val configurationListener = object : ConfigurationController.ConfigurationListener {
@@ -268,7 +275,6 @@
velocityTracker!!.addMovement(event)
when (event.actionMasked) {
MotionEvent.ACTION_DOWN -> {
- gestureSinceActionDown = SystemClock.uptimeMillis()
cancelAllPendingAnimations()
startX = event.x
startY = event.y
@@ -307,8 +313,22 @@
}
}
GestureState.ACTIVE -> {
- if (elapsedTimeSinceEntry < MIN_DURATION_CONSIDERED_AS_FLING) {
+ if (previousState == GestureState.ENTRY &&
+ elapsedTimeSinceEntry
+ < MIN_DURATION_ENTRY_TO_ACTIVE_CONSIDERED_AS_FLING
+ ) {
updateArrowState(GestureState.FLUNG)
+ } else if (previousState == GestureState.INACTIVE &&
+ elapsedTimeSinceInactive
+ < MIN_DURATION_INACTIVE_TO_ACTIVE_CONSIDERED_AS_FLING
+ ) {
+ // A delay is added to allow the background to transition back to ACTIVE
+ // since it was briefly in INACTIVE. Without this delay, setting it
+ // immediately to COMMITTED would result in the committed animation
+ // appearing like it was playing in INACTIVE.
+ mainHandler.postDelayed(MIN_DURATION_ACTIVE_AFTER_INACTIVE_ANIMATION) {
+ updateArrowState(GestureState.COMMITTED)
+ }
} else {
updateArrowState(GestureState.COMMITTED)
}
@@ -376,7 +396,7 @@
val isPastDynamicDeactivationThreshold =
totalTouchDelta <= params.deactivationSwipeTriggerThreshold
val isMinDurationElapsed =
- elapsedTimeSinceActionDown > MIN_DURATION_ACTIVE_ANIMATION
+ elapsedTimeSinceEntry > MIN_DURATION_ACTIVE_BEFORE_INACTIVE_ANIMATION
if (isMinDurationElapsed && (!isWithinYActivationThreshold ||
isPastDynamicDeactivationThreshold)
@@ -470,8 +490,15 @@
GestureState.GONE -> 0f
}
+ val indicator = when (currentState) {
+ GestureState.ENTRY -> params.entryIndicator
+ GestureState.INACTIVE -> params.preThresholdIndicator
+ GestureState.ACTIVE -> params.activeIndicator
+ else -> params.preThresholdIndicator
+ }
+
strokeAlphaProgress?.let { progress ->
- params.arrowStrokeAlphaSpring.get(progress).takeIf { it.isNewState }?.let {
+ indicator.arrowDimens.alphaSpring?.get(progress)?.takeIf { it.isNewState }?.let {
mView.popArrowAlpha(0f, it.value)
}
}
@@ -537,7 +564,8 @@
backgroundHeightStretchAmount = params.heightInterpolator
.getInterpolation(progress),
backgroundAlphaStretchAmount = 1f,
- arrowAlphaStretchAmount = params.arrowStrokeAlphaInterpolator.get(progress).value,
+ arrowAlphaStretchAmount = params.entryIndicator.arrowDimens
+ .alphaInterpolator?.get(progress)?.value ?: 0f,
edgeCornerStretchAmount = params.edgeCornerInterpolator.getInterpolation(progress),
farCornerStretchAmount = params.farCornerInterpolator.getInterpolation(progress),
fullyStretchedDimens = params.preThresholdIndicator
@@ -567,7 +595,8 @@
backgroundHeightStretchAmount = params.heightInterpolator
.getInterpolation(progress),
backgroundAlphaStretchAmount = 1f,
- arrowAlphaStretchAmount = params.arrowStrokeAlphaInterpolator.get(progress).value,
+ arrowAlphaStretchAmount = params.preThresholdIndicator.arrowDimens
+ .alphaInterpolator?.get(progress)?.value ?: 0f,
edgeCornerStretchAmount = params.edgeCornerInterpolator.getInterpolation(progress),
farCornerStretchAmount = params.farCornerInterpolator.getInterpolation(progress),
fullyStretchedDimens = params.preThresholdIndicator
@@ -599,19 +628,15 @@
windowManager.addView(mView, layoutParams)
}
- private fun isDragAwayFromEdge(velocityPxPerSecThreshold: Int = 0) = velocityTracker!!.run {
- computeCurrentVelocity(PX_PER_SEC)
- val velocity = xVelocity.takeIf { mView.isLeftPanel } ?: (xVelocity * -1)
- velocity > velocityPxPerSecThreshold
- }
-
private fun isFlungAwayFromEdge(endX: Float, startX: Float = touchDeltaStartX): Boolean {
- val minDistanceConsideredForFling = ViewConfiguration.get(context).scaledTouchSlop
val flingDistance = if (mView.isLeftPanel) endX - startX else startX - endX
- val isPastFlingVelocity = isDragAwayFromEdge(
- velocityPxPerSecThreshold =
- ViewConfiguration.get(context).scaledMinimumFlingVelocity)
- return flingDistance > minDistanceConsideredForFling && isPastFlingVelocity
+ val flingVelocity = velocityTracker?.run {
+ computeCurrentVelocity(PX_PER_SEC)
+ xVelocity.takeIf { mView.isLeftPanel } ?: (xVelocity * -1)
+ } ?: 0f
+ val isPastFlingVelocityThreshold =
+ flingVelocity > ViewConfiguration.get(context).scaledMinimumFlingVelocity
+ return flingDistance > minFlingDistance && isPastFlingVelocityThreshold
}
private fun playHorizontalAnimationThen(onEnd: DelayedOnAnimationEndListener) {
@@ -664,7 +689,6 @@
mView.setSpring(
arrowLength = params.entryIndicator.arrowDimens.lengthSpring,
arrowHeight = params.entryIndicator.arrowDimens.heightSpring,
- arrowAlpha = params.entryIndicator.arrowDimens.alphaSpring,
scale = params.entryIndicator.scaleSpring,
verticalTranslation = params.entryIndicator.verticalTranslationSpring,
horizontalTranslation = params.entryIndicator.horizontalTranslationSpring,
@@ -725,6 +749,7 @@
arrowLength = params.committedIndicator.arrowDimens.lengthSpring,
arrowHeight = params.committedIndicator.arrowDimens.heightSpring,
scale = params.committedIndicator.scaleSpring,
+ backgroundAlpha = params.committedIndicator.backgroundDimens.alphaSpring,
backgroundWidth = params.committedIndicator.backgroundDimens.widthSpring,
backgroundHeight = params.committedIndicator.backgroundDimens.heightSpring,
backgroundEdgeCornerRadius = params.committedIndicator.backgroundDimens
@@ -733,6 +758,10 @@
.farCornerRadiusSpring,
)
}
+ GestureState.CANCELLED -> {
+ mView.setSpring(
+ backgroundAlpha = params.cancelledIndicator.backgroundDimens.alphaSpring)
+ }
else -> {}
}
@@ -864,6 +893,7 @@
}
GestureState.INACTIVE -> {
+ gestureInactiveTime = SystemClock.uptimeMillis()
// Typically entering INACTIVE means
// totalTouchDelta <= deactivationSwipeTriggerThreshold
@@ -900,9 +930,9 @@
val delay = max(0, MIN_DURATION_CANCELLED_ANIMATION - elapsedTimeSinceEntry)
playWithBackgroundWidthAnimation(onEndSetGoneStateListener, delay)
- params.arrowStrokeAlphaSpring.get(0f).takeIf { it.isNewState }?.let {
- mView.popArrowAlpha(0f, it.value)
- }
+ val springForceOnCancelled = params.cancelledIndicator
+ .arrowDimens.alphaSpring?.get(0f)?.value
+ mView.popArrowAlpha(0f, springForceOnCancelled)
mainHandler.postDelayed(10L) { vibratorHelper.cancel() }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
index b454c23..cfcc671 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgeBackGestureHandler.java
@@ -67,7 +67,6 @@
import com.android.systemui.flags.FeatureFlags;
import com.android.systemui.flags.Flags;
import com.android.systemui.model.SysUiState;
-import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.NavigationEdgeBackPlugin;
@@ -591,7 +590,8 @@
// Add a nav bar panel window
mIsNewBackAffordanceEnabled = mFeatureFlags.isEnabled(Flags.NEW_BACK_AFFORDANCE);
- mIsTrackpadGestureBackEnabled = mFeatureFlags.isEnabled(Flags.TRACKPAD_GESTURE_BACK);
+ mIsTrackpadGestureBackEnabled = mFeatureFlags.isEnabled(
+ Flags.TRACKPAD_GESTURE_FEATURES);
resetEdgeBackPlugin();
mPluginManager.addPluginListener(
this, NavigationEdgeBackPlugin.class, /*allowMultiple=*/ false);
diff --git a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
index d46333a..3dc6d2f 100644
--- a/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
+++ b/packages/SystemUI/src/com/android/systemui/navigationbar/gestural/EdgePanelParams.kt
@@ -12,9 +12,10 @@
val length: Float? = 0f,
val height: Float? = 0f,
val alpha: Float = 0f,
- var alphaSpring: SpringForce? = null,
val heightSpring: SpringForce? = null,
val lengthSpring: SpringForce? = null,
+ var alphaSpring: Step<SpringForce>? = null,
+ var alphaInterpolator: Step<Float>? = null
)
data class BackgroundDimens(
@@ -61,11 +62,6 @@
private set
var arrowThickness: Float = 0f
private set
- lateinit var arrowStrokeAlphaSpring: Step<SpringForce>
- private set
- lateinit var arrowStrokeAlphaInterpolator: Step<Float>
- private set
-
// The closest to y
var minArrowYPosition: Int = 0
private set
@@ -81,13 +77,6 @@
var swipeProgressThreshold: Float = 0f
private set
- // The minimum delta needed to change direction / stop triggering back
- var minDeltaForSwitch: Int = 0
- private set
-
- var minDragToStartAnimation: Float = 0f
- private set
-
lateinit var entryWidthInterpolator: PathInterpolator
private set
lateinit var entryWidthTowardsEdgeInterpolator: PathInterpolator
@@ -133,23 +122,17 @@
deactivationSwipeTriggerThreshold =
getDimen(R.dimen.navigation_edge_action_deactivation_drag_threshold)
swipeProgressThreshold = getDimen(R.dimen.navigation_edge_action_progress_threshold)
- minDeltaForSwitch = getPx(R.dimen.navigation_edge_minimum_x_delta_for_switch)
- minDragToStartAnimation =
- getDimen(R.dimen.navigation_edge_action_min_distance_to_start_animation)
entryWidthInterpolator = PathInterpolator(.19f, 1.27f, .71f, .86f)
entryWidthTowardsEdgeInterpolator = PathInterpolator(1f, -3f, 1f, 1.2f)
- activeWidthInterpolator = PathInterpolator(.32f, 0f, .16f, .94f)
+ activeWidthInterpolator = PathInterpolator(.7f, .06f, .34f, .97f)
arrowAngleInterpolator = entryWidthInterpolator
translationInterpolator = PathInterpolator(0.2f, 1.0f, 1.0f, 1.0f)
farCornerInterpolator = PathInterpolator(.03f, .19f, .14f, 1.09f)
edgeCornerInterpolator = PathInterpolator(0f, 1.11f, .85f, .84f)
heightInterpolator = PathInterpolator(1f, .05f, .9f, -0.29f)
- val showArrowOnProgressValue = .23f
- val showArrowOnProgressValueFactor = 1.05f
-
- val entryActiveHorizontalTranslationSpring = createSpring(800f, 0.8f)
+ val entryActiveHorizontalTranslationSpring = createSpring(800f, 0.76f)
val activeCommittedArrowLengthSpring = createSpring(1500f, 0.29f)
val activeCommittedArrowHeightSpring = createSpring(1500f, 0.29f)
val flungCommittedEdgeCornerSpring = createSpring(10000f, 1f)
@@ -157,6 +140,8 @@
val flungCommittedWidthSpring = createSpring(10000f, 1f)
val flungCommittedHeightSpring = createSpring(10000f, 1f)
+ val entryIndicatorAlphaThreshold = .23f
+ val entryIndicatorAlphaFactor = 1.05f
entryIndicator = BackIndicatorDimens(
horizontalTranslation = getDimen(R.dimen.navigation_edge_entry_margin),
scale = getDimenFloat(R.dimen.navigation_edge_entry_scale),
@@ -168,9 +153,20 @@
length = getDimen(R.dimen.navigation_edge_entry_arrow_length),
height = getDimen(R.dimen.navigation_edge_entry_arrow_height),
alpha = 0f,
- alphaSpring = createSpring(200f, 1f),
lengthSpring = createSpring(600f, 0.4f),
heightSpring = createSpring(600f, 0.4f),
+ alphaSpring = Step(
+ threshold = entryIndicatorAlphaThreshold,
+ factor = entryIndicatorAlphaFactor,
+ postThreshold = createSpring(200f, 1f),
+ preThreshold = createSpring(2000f, 0.6f)
+ ),
+ alphaInterpolator = Step(
+ threshold = entryIndicatorAlphaThreshold,
+ factor = entryIndicatorAlphaFactor,
+ postThreshold = 1f,
+ preThreshold = 0f
+ )
),
backgroundDimens = BackgroundDimens(
alpha = 1f,
@@ -186,6 +182,20 @@
)
)
+ val preThresholdAndActiveIndicatorAlphaThreshold = .355f
+ val preThresholdAndActiveIndicatorAlphaFactor = 1.05f
+ val preThresholdAndActiveAlphaSpring = Step(
+ threshold = preThresholdAndActiveIndicatorAlphaThreshold,
+ factor = preThresholdAndActiveIndicatorAlphaFactor,
+ postThreshold = createSpring(180f, 0.9f),
+ preThreshold = createSpring(2000f, 0.6f)
+ )
+ val preThresholdAndActiveAlphaSpringInterpolator = Step(
+ threshold = preThresholdAndActiveIndicatorAlphaThreshold,
+ factor = preThresholdAndActiveIndicatorAlphaFactor,
+ postThreshold = 1f,
+ preThreshold = 0f
+ )
activeIndicator = BackIndicatorDimens(
horizontalTranslation = getDimen(R.dimen.navigation_edge_active_margin),
scale = getDimenFloat(R.dimen.navigation_edge_active_scale),
@@ -197,6 +207,8 @@
alpha = 1f,
lengthSpring = activeCommittedArrowLengthSpring,
heightSpring = activeCommittedArrowHeightSpring,
+ alphaSpring = preThresholdAndActiveAlphaSpring,
+ alphaInterpolator = preThresholdAndActiveAlphaSpringInterpolator
),
backgroundDimens = BackgroundDimens(
alpha = 1f,
@@ -204,7 +216,7 @@
height = getDimen(R.dimen.navigation_edge_active_background_height),
edgeCornerRadius = getDimen(R.dimen.navigation_edge_active_edge_corners),
farCornerRadius = getDimen(R.dimen.navigation_edge_active_far_corners),
- widthSpring = createSpring(375f, 0.675f),
+ widthSpring = createSpring(650f, 0.75f),
heightSpring = createSpring(10000f, 1f),
edgeCornerRadiusSpring = createSpring(600f, 0.36f),
farCornerRadiusSpring = createSpring(2500f, 0.855f),
@@ -223,6 +235,8 @@
alpha = 1f,
lengthSpring = createSpring(100f, 0.6f),
heightSpring = createSpring(100f, 0.6f),
+ alphaSpring = preThresholdAndActiveAlphaSpring,
+ alphaInterpolator = preThresholdAndActiveAlphaSpringInterpolator
),
backgroundDimens = BackgroundDimens(
alpha = 1f,
@@ -255,6 +269,7 @@
heightSpring = flungCommittedHeightSpring,
edgeCornerRadiusSpring = flungCommittedEdgeCornerSpring,
farCornerRadiusSpring = flungCommittedFarCornerSpring,
+ alphaSpring = createSpring(1100f, 1f),
),
scale = 0.85f,
scaleSpring = createSpring(1150f, 1f),
@@ -276,7 +291,11 @@
)
cancelledIndicator = entryIndicator.copy(
- backgroundDimens = entryIndicator.backgroundDimens.copy(width = 0f)
+ backgroundDimens = entryIndicator.backgroundDimens.copy(
+ width = 0f,
+ alpha = 0f,
+ alphaSpring = createSpring(450f, 1f)
+ )
)
fullyStretchedIndicator = BackIndicatorDimens(
@@ -306,22 +325,6 @@
farCornerRadiusSpring = null,
)
)
-
- arrowStrokeAlphaInterpolator = Step(
- threshold = showArrowOnProgressValue,
- factor = showArrowOnProgressValueFactor,
- postThreshold = 1f,
- preThreshold = 0f
- )
-
- entryIndicator.arrowDimens.alphaSpring?.let { alphaSpring ->
- arrowStrokeAlphaSpring = Step(
- threshold = showArrowOnProgressValue,
- factor = showArrowOnProgressValueFactor,
- postThreshold = alphaSpring,
- preThreshold = SpringForce().setStiffness(2000f).setDampingRatio(1f)
- )
- }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
index ac22b7c..58ac5b3 100644
--- a/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
+++ b/packages/SystemUI/src/com/android/systemui/notetask/NoteTaskController.kt
@@ -27,6 +27,7 @@
import android.content.Intent.FLAG_ACTIVITY_NEW_TASK
import android.content.pm.PackageManager
import android.os.Build
+import android.os.UserHandle
import android.os.UserManager
import android.util.Log
import androidx.annotation.VisibleForTesting
@@ -100,6 +101,14 @@
fun showNoteTask(
entryPoint: NoteTaskEntryPoint,
) {
+ showNoteTaskAsUser(entryPoint, userTracker.userHandle)
+ }
+
+ /** A variant of [showNoteTask] which launches note task in the given [user]. */
+ fun showNoteTaskAsUser(
+ entryPoint: NoteTaskEntryPoint,
+ user: UserHandle,
+ ) {
if (!isEnabled) return
val bubbles = optionalBubbles.getOrNull() ?: return
@@ -113,7 +122,7 @@
// note task when the screen is locked.
if (
isKeyguardLocked &&
- devicePolicyManager.areKeyguardShortcutsDisabled(userId = userTracker.userId)
+ devicePolicyManager.areKeyguardShortcutsDisabled(userId = user.identifier)
) {
logDebug { "Enterprise policy disallows launching note app when the screen is locked." }
return
@@ -126,16 +135,16 @@
// TODO(b/266686199): We should handle when app not available. For now, we log.
val intent = createNoteIntent(info)
try {
- logDebug { "onShowNoteTask - start: $info" }
+ logDebug { "onShowNoteTask - start: $info on user#${user.identifier}" }
when (info.launchMode) {
is NoteTaskLaunchMode.AppBubble -> {
- // TODO(b/267634412, b/268351693): Should use `showOrHideAppBubbleAsUser`
- bubbles.showOrHideAppBubble(intent)
+ // TODO: provide app bubble icon
+ bubbles.showOrHideAppBubble(intent, userTracker.userHandle, null /* icon */)
// App bubble logging happens on `onBubbleExpandChanged`.
logDebug { "onShowNoteTask - opened as app bubble: $info" }
}
is NoteTaskLaunchMode.Activity -> {
- context.startActivityAsUser(intent, userTracker.userHandle)
+ context.startActivityAsUser(intent, user)
eventLogger.logNoteTaskOpened(info)
logDebug { "onShowNoteTask - opened as activity: $info" }
}
diff --git a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java
index 95f1419..fbf1a0e 100644
--- a/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java
+++ b/packages/SystemUI/src/com/android/systemui/plugins/PluginsModule.java
@@ -73,7 +73,7 @@
return new PluginInstance.Factory(
PluginModule.class.getClassLoader(),
new PluginInstance.InstanceFactory<>(),
- new PluginInstance.VersionChecker(),
+ new PluginInstance.VersionCheckerImpl(),
privilegedPlugins,
isDebug);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
index baa812c..584d27f8 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSFragment.java
@@ -635,7 +635,8 @@
&& mLastKeyguardAndExpanded == onKeyguardAndExpanded
&& mLastViewHeight == currentHeight
&& mLastHeaderTranslation == headerTranslation
- && mSquishinessFraction == squishinessFraction) {
+ && mSquishinessFraction == squishinessFraction
+ && mLastPanelFraction == panelExpansionFraction) {
return;
}
mLastHeaderTranslation = headerTranslation;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
index a71e6dd..9ece72d 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSHost.java
@@ -26,6 +26,7 @@
import com.android.systemui.plugins.qs.QSFactory;
import com.android.systemui.plugins.qs.QSTile;
import com.android.systemui.plugins.qs.QSTileView;
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
import com.android.systemui.util.leak.GarbageMonitor;
import java.util.ArrayList;
@@ -33,7 +34,7 @@
import java.util.Collection;
import java.util.List;
-public interface QSHost {
+public interface QSHost extends PanelInteractor {
String TILES_SETTING = Settings.Secure.QS_TILES;
int POSITION_AT_END = -1;
@@ -57,9 +58,6 @@
}
void warn(String message, Throwable t);
- void collapsePanels();
- void forceCollapsePanels();
- void openPanels();
Context getContext();
Context getUserContext();
int getUserId();
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
index 2668d2e..fdab9b1 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanelControllerBase.java
@@ -91,16 +91,19 @@
new QSPanel.OnConfigurationChangedListener() {
@Override
public void onConfigurationChange(Configuration newConfig) {
- mQSLogger.logOnConfigurationChanged(
- /* lastOrientation= */ mLastOrientation,
- /* newOrientation= */ newConfig.orientation,
- /* containerName= */ mView.getDumpableTag());
-
- boolean previousSplitShadeState = mShouldUseSplitNotificationShade;
+ final boolean previousSplitShadeState = mShouldUseSplitNotificationShade;
+ final int previousOrientation = mLastOrientation;
mShouldUseSplitNotificationShade =
- LargeScreenUtils.shouldUseSplitNotificationShade(getResources());
+ LargeScreenUtils.shouldUseSplitNotificationShade(getResources());
mLastOrientation = newConfig.orientation;
+ mQSLogger.logOnConfigurationChanged(
+ /* oldOrientation= */ previousOrientation,
+ /* newOrientation= */ mLastOrientation,
+ /* oldShouldUseSplitShade= */ previousSplitShadeState,
+ /* newShouldUseSplitShade= */ mShouldUseSplitNotificationShade,
+ /* containerName= */ mView.getDumpableTag());
+
switchTileLayoutIfNeeded();
onConfigurationChanged();
if (previousSplitShadeState != mShouldUseSplitNotificationShade) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSHostModule.kt b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSHostModule.kt
new file mode 100644
index 0000000..958fa71
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSHostModule.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.systemui.qs.dagger
+
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.qs.QSHost
+import com.android.systemui.qs.QSTileHost
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractorImpl
+import dagger.Binds
+import dagger.Module
+import dagger.Provides
+
+@Module
+interface QSHostModule {
+
+ @Binds fun provideQsHost(controllerImpl: QSTileHost): QSHost
+
+ @Module
+ companion object {
+ @Provides
+ @JvmStatic
+ fun providePanelInteractor(
+ featureFlags: FeatureFlags,
+ qsHost: QSHost,
+ panelInteractorImpl: PanelInteractorImpl
+ ): PanelInteractor {
+ return if (featureFlags.isEnabled(Flags.QS_PIPELINE_NEW_HOST)) {
+ panelInteractorImpl
+ } else {
+ qsHost
+ }
+ }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
index 431d6e8..cfe9313 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/dagger/QSModule.java
@@ -27,7 +27,6 @@
import com.android.systemui.media.dagger.MediaModule;
import com.android.systemui.qs.AutoAddTracker;
import com.android.systemui.qs.QSHost;
-import com.android.systemui.qs.QSTileHost;
import com.android.systemui.qs.ReduceBrightColorsController;
import com.android.systemui.qs.external.QSExternalModule;
import com.android.systemui.qs.tileimpl.QSTileImpl;
@@ -45,7 +44,6 @@
import javax.inject.Named;
-import dagger.Binds;
import dagger.Module;
import dagger.Provides;
import dagger.multibindings.Multibinds;
@@ -54,7 +52,13 @@
* Module for QS dependencies
*/
@Module(subcomponents = {QSFragmentComponent.class},
- includes = {MediaModule.class, QSExternalModule.class, QSFlagsModule.class})
+ includes = {
+ MediaModule.class,
+ QSExternalModule.class,
+ QSFlagsModule.class,
+ QSHostModule.class
+ }
+)
public interface QSModule {
/** A map of internal QS tiles. Ensures that this can be injected even if
@@ -100,8 +104,4 @@
manager.init();
return manager;
}
-
- /** */
- @Binds
- QSHost provideQsHost(QSTileHost controllerImpl);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
index adc7165..5e4f531 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/external/TileServices.java
@@ -40,6 +40,7 @@
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dagger.qualifiers.Main;
import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -74,6 +75,7 @@
private final CommandQueue mCommandQueue;
private final UserTracker mUserTracker;
private final StatusBarIconController mStatusBarIconController;
+ private final PanelInteractor mPanelInteractor;
private int mMaxBound = DEFAULT_MAX_BOUND;
@@ -85,7 +87,8 @@
UserTracker userTracker,
KeyguardStateController keyguardStateController,
CommandQueue commandQueue,
- StatusBarIconController statusBarIconController) {
+ StatusBarIconController statusBarIconController,
+ PanelInteractor panelInteractor) {
mHost = host;
mKeyguardStateController = keyguardStateController;
mContext = mHost.getContext();
@@ -96,6 +99,7 @@
mCommandQueue = commandQueue;
mStatusBarIconController = statusBarIconController;
mCommandQueue.addCallback(mRequestListeningCallback);
+ mPanelInteractor = panelInteractor;
}
public Context getContext() {
@@ -132,9 +136,8 @@
mServices.remove(tile);
mTokenMap.remove(service.getToken());
mTiles.remove(tile.getComponent());
- final String slot = tile.getComponent().getClassName();
- // TileServices doesn't know how to add more than 1 icon per slot, so remove all
- mMainHandler.post(() -> mStatusBarIconController.removeAllIconsForSlot(slot));
+ final String slot = getStatusBarIconSlotName(tile.getComponent());
+ mMainHandler.post(() -> mStatusBarIconController.removeIconForTile(slot));
}
}
@@ -255,7 +258,7 @@
if (customTile != null) {
verifyCaller(customTile);
customTile.onDialogShown();
- mHost.forceCollapsePanels();
+ mPanelInteractor.forceCollapsePanels();
Objects.requireNonNull(mServices.get(customTile)).setShowingDialog(true);
}
}
@@ -275,7 +278,7 @@
CustomTile customTile = getTileForToken(token);
if (customTile != null) {
verifyCaller(customTile);
- mHost.forceCollapsePanels();
+ mPanelInteractor.forceCollapsePanels();
}
}
@@ -308,12 +311,11 @@
? new StatusBarIcon(userHandle, packageName, icon, 0, 0,
contentDescription)
: null;
+ final String slot = getStatusBarIconSlotName(componentName);
mMainHandler.post(new Runnable() {
@Override
public void run() {
- StatusBarIconController iconController = mStatusBarIconController;
- iconController.setIcon(componentName.getClassName(), statusIcon);
- iconController.setExternalIcon(componentName.getClassName());
+ mStatusBarIconController.setIconFromTile(slot, statusIcon);
}
});
}
@@ -373,6 +375,12 @@
mCommandQueue.removeCallback(mRequestListeningCallback);
}
+ /** Returns the slot name that should be used when adding or removing status bar icons. */
+ private String getStatusBarIconSlotName(ComponentName componentName) {
+ return componentName.getClassName();
+ }
+
+
private final CommandQueue.Callbacks mRequestListeningCallback = new CommandQueue.Callbacks() {
@Override
public void requestTileServiceListeningState(@NonNull ComponentName componentName) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
index 23c41db..5b461a6 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/logging/QSLogger.kt
@@ -16,8 +16,12 @@
package com.android.systemui.qs.logging
+import android.content.res.Configuration.ORIENTATION_LANDSCAPE
+import android.content.res.Configuration.ORIENTATION_PORTRAIT
+import android.content.res.Configuration.Orientation
import android.service.quicksettings.Tile
import android.view.View
+import com.android.systemui.log.dagger.QSConfigLog
import com.android.systemui.log.dagger.QSLog
import com.android.systemui.plugins.log.ConstantStringsLogger
import com.android.systemui.plugins.log.ConstantStringsLoggerImpl
@@ -32,8 +36,12 @@
private const val TAG = "QSLog"
-class QSLogger @Inject constructor(@QSLog private val buffer: LogBuffer) :
- ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) {
+class QSLogger
+@Inject
+constructor(
+ @QSLog private val buffer: LogBuffer,
+ @QSConfigLog private val configChangedBuffer: LogBuffer,
+) : ConstantStringsLogger by ConstantStringsLoggerImpl(buffer, TAG) {
fun logException(@CompileTimeConstant logMsg: String, ex: Exception) {
buffer.log(TAG, ERROR, {}, { logMsg }, exception = ex)
@@ -264,19 +272,28 @@
}
fun logOnConfigurationChanged(
- lastOrientation: Int,
- newOrientation: Int,
+ @Orientation oldOrientation: Int,
+ @Orientation newOrientation: Int,
+ newShouldUseSplitShade: Boolean,
+ oldShouldUseSplitShade: Boolean,
containerName: String
) {
- buffer.log(
+ configChangedBuffer.log(
TAG,
DEBUG,
{
str1 = containerName
- int1 = lastOrientation
+ int1 = oldOrientation
int2 = newOrientation
+ bool1 = oldShouldUseSplitShade
+ bool2 = newShouldUseSplitShade
},
- { "configuration change: $str1 orientation was $int1, now $int2" }
+ {
+ "config change: " +
+ "$str1 orientation=${toOrientationString(int2)} " +
+ "(was ${toOrientationString(int1)}), " +
+ "splitShade=$bool2 (was $bool1)"
+ }
)
}
@@ -353,3 +370,11 @@
}
}
}
+
+private inline fun toOrientationString(@Orientation orientation: Int): String {
+ return when (orientation) {
+ ORIENTATION_LANDSCAPE -> "land"
+ ORIENTATION_PORTRAIT -> "port"
+ else -> "undefined"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractor.kt b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractor.kt
new file mode 100644
index 0000000..260caa7
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractor.kt
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2015 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.systemui.qs.pipeline.domain.interactor
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import java.util.Optional
+import javax.inject.Inject
+
+/** Encapsulates business logic for interacting with the QS panel. */
+interface PanelInteractor {
+
+ /** Collapse the shade */
+ fun collapsePanels()
+
+ /** Collapse the shade forcefully, skipping some animations. */
+ fun forceCollapsePanels()
+
+ /** Open the Quick Settings panel */
+ fun openPanels()
+}
+
+@SysUISingleton
+class PanelInteractorImpl
+@Inject
+constructor(
+ private val centralSurfaces: Optional<CentralSurfaces>,
+) : PanelInteractor {
+ override fun collapsePanels() {
+ centralSurfaces.ifPresent { it.postAnimateCollapsePanels() }
+ }
+
+ override fun forceCollapsePanels() {
+ centralSurfaces.ifPresent { it.postAnimateForceCollapsePanels() }
+ }
+
+ override fun openPanels() {
+ centralSurfaces.ifPresent { it.postAnimateOpenPanels() }
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
index a915ddb..3f514344 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/FontScalingTile.kt
@@ -17,6 +17,7 @@
import android.content.Intent
import android.os.Handler
+import android.os.HandlerExecutor
import android.os.Looper
import android.provider.Settings
import android.view.View
@@ -38,6 +39,7 @@
import com.android.systemui.qs.logging.QSLogger
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.statusbar.phone.SystemUIDialog
+import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.settings.SystemSettings
import javax.inject.Inject
@@ -54,6 +56,7 @@
qsLogger: QSLogger,
private val dialogLaunchAnimator: DialogLaunchAnimator,
private val systemSettings: SystemSettings,
+ private val secureSettings: SecureSettings,
private val featureFlags: FeatureFlags
) :
QSTileImpl<QSTile.State?>(
@@ -78,7 +81,13 @@
override fun handleClick(view: View?) {
mUiHandler.post {
- val dialog: SystemUIDialog = FontScalingDialog(mContext, systemSettings)
+ val dialog: SystemUIDialog =
+ FontScalingDialog(
+ mContext,
+ systemSettings,
+ secureSettings,
+ HandlerExecutor(mHandler)
+ )
if (view != null) {
dialogLaunchAnimator.showFromView(
dialog,
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
index aa2ea0b6..46412a3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/InternetTile.java
@@ -35,6 +35,7 @@
import androidx.annotation.Nullable;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.logging.MetricsLogger;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settingslib.graph.SignalDrawable;
@@ -174,6 +175,15 @@
@Nullable
String mEthernetContentDescription;
+ public void copyTo(EthernetCallbackInfo ethernetCallbackInfo) {
+ if (ethernetCallbackInfo == null) {
+ throw new IllegalArgumentException();
+ }
+ ethernetCallbackInfo.mConnected = this.mConnected;
+ ethernetCallbackInfo.mEthernetSignalIconId = this.mEthernetSignalIconId;
+ ethernetCallbackInfo.mEthernetContentDescription = this.mEthernetContentDescription;
+ }
+
@Override
public String toString() {
return new StringBuilder("EthernetCallbackInfo[")
@@ -200,6 +210,23 @@
boolean mNoValidatedNetwork;
boolean mNoNetworksAvailable;
+ public void copyTo(WifiCallbackInfo wifiCallbackInfo) {
+ if (wifiCallbackInfo == null) {
+ throw new IllegalArgumentException();
+ }
+ wifiCallbackInfo.mAirplaneModeEnabled = this.mAirplaneModeEnabled;
+ wifiCallbackInfo.mEnabled = this.mEnabled;
+ wifiCallbackInfo.mConnected = this.mConnected;
+ wifiCallbackInfo.mWifiSignalIconId = this.mWifiSignalIconId;
+ wifiCallbackInfo.mSsid = this.mSsid;
+ wifiCallbackInfo.mWifiSignalContentDescription = this.mWifiSignalContentDescription;
+ wifiCallbackInfo.mIsTransient = this.mIsTransient;
+ wifiCallbackInfo.mStatusLabel = this.mStatusLabel;
+ wifiCallbackInfo.mNoDefaultNetwork = this.mNoDefaultNetwork;
+ wifiCallbackInfo.mNoValidatedNetwork = this.mNoValidatedNetwork;
+ wifiCallbackInfo.mNoNetworksAvailable = this.mNoNetworksAvailable;
+ }
+
@Override
public String toString() {
return new StringBuilder("WifiCallbackInfo[")
@@ -232,6 +259,23 @@
boolean mNoValidatedNetwork;
boolean mNoNetworksAvailable;
+ public void copyTo(CellularCallbackInfo cellularCallbackInfo) {
+ if (cellularCallbackInfo == null) {
+ throw new IllegalArgumentException();
+ }
+ cellularCallbackInfo.mAirplaneModeEnabled = this.mAirplaneModeEnabled;
+ cellularCallbackInfo.mDataSubscriptionName = this.mDataSubscriptionName;
+ cellularCallbackInfo.mDataContentDescription = this.mDataContentDescription;
+ cellularCallbackInfo.mMobileSignalIconId = this.mMobileSignalIconId;
+ cellularCallbackInfo.mQsTypeIcon = this.mQsTypeIcon;
+ cellularCallbackInfo.mNoSim = this.mNoSim;
+ cellularCallbackInfo.mRoaming = this.mRoaming;
+ cellularCallbackInfo.mMultipleSubs = this.mMultipleSubs;
+ cellularCallbackInfo.mNoDefaultNetwork = this.mNoDefaultNetwork;
+ cellularCallbackInfo.mNoValidatedNetwork = this.mNoValidatedNetwork;
+ cellularCallbackInfo.mNoNetworksAvailable = this.mNoNetworksAvailable;
+ }
+
@Override
public String toString() {
return new StringBuilder("CellularCallbackInfo[")
@@ -251,8 +295,11 @@
}
protected final class InternetSignalCallback implements SignalCallback {
+ @GuardedBy("mWifiInfo")
final WifiCallbackInfo mWifiInfo = new WifiCallbackInfo();
+ @GuardedBy("mCellularInfo")
final CellularCallbackInfo mCellularInfo = new CellularCallbackInfo();
+ @GuardedBy("mEthernetInfo")
final EthernetCallbackInfo mEthernetInfo = new EthernetCallbackInfo();
@@ -261,19 +308,23 @@
if (DEBUG) {
Log.d(TAG, "setWifiIndicators: " + indicators);
}
- mWifiInfo.mEnabled = indicators.enabled;
- mWifiInfo.mSsid = indicators.description;
- mWifiInfo.mIsTransient = indicators.isTransient;
- mWifiInfo.mStatusLabel = indicators.statusLabel;
+ synchronized (mWifiInfo) {
+ mWifiInfo.mEnabled = indicators.enabled;
+ mWifiInfo.mSsid = indicators.description;
+ mWifiInfo.mIsTransient = indicators.isTransient;
+ mWifiInfo.mStatusLabel = indicators.statusLabel;
+ if (indicators.qsIcon != null) {
+ mWifiInfo.mConnected = indicators.qsIcon.visible;
+ mWifiInfo.mWifiSignalIconId = indicators.qsIcon.icon;
+ mWifiInfo.mWifiSignalContentDescription = indicators.qsIcon.contentDescription;
+ } else {
+ mWifiInfo.mConnected = false;
+ mWifiInfo.mWifiSignalIconId = 0;
+ mWifiInfo.mWifiSignalContentDescription = null;
+ }
+ }
if (indicators.qsIcon != null) {
- mWifiInfo.mConnected = indicators.qsIcon.visible;
- mWifiInfo.mWifiSignalIconId = indicators.qsIcon.icon;
- mWifiInfo.mWifiSignalContentDescription = indicators.qsIcon.contentDescription;
refreshState(mWifiInfo);
- } else {
- mWifiInfo.mConnected = false;
- mWifiInfo.mWifiSignalIconId = 0;
- mWifiInfo.mWifiSignalContentDescription = null;
}
}
@@ -286,14 +337,16 @@
// Not data sim, don't display.
return;
}
- mCellularInfo.mDataSubscriptionName = indicators.qsDescription == null
+ synchronized (mCellularInfo) {
+ mCellularInfo.mDataSubscriptionName = indicators.qsDescription == null
? mController.getMobileDataNetworkName() : indicators.qsDescription;
- mCellularInfo.mDataContentDescription = indicators.qsDescription != null
+ mCellularInfo.mDataContentDescription = indicators.qsDescription != null
? indicators.typeContentDescriptionHtml : null;
- mCellularInfo.mMobileSignalIconId = indicators.qsIcon.icon;
- mCellularInfo.mQsTypeIcon = indicators.qsType;
- mCellularInfo.mRoaming = indicators.roaming;
- mCellularInfo.mMultipleSubs = mController.getNumberSubscriptions() > 1;
+ mCellularInfo.mMobileSignalIconId = indicators.qsIcon.icon;
+ mCellularInfo.mQsTypeIcon = indicators.qsType;
+ mCellularInfo.mRoaming = indicators.roaming;
+ mCellularInfo.mMultipleSubs = mController.getNumberSubscriptions() > 1;
+ }
refreshState(mCellularInfo);
}
@@ -303,9 +356,11 @@
Log.d(TAG, "setEthernetIndicators: "
+ "icon = " + (icon == null ? "" : icon.toString()));
}
- mEthernetInfo.mConnected = icon.visible;
- mEthernetInfo.mEthernetSignalIconId = icon.icon;
- mEthernetInfo.mEthernetContentDescription = icon.contentDescription;
+ synchronized (mEthernetInfo) {
+ mEthernetInfo.mConnected = icon.visible;
+ mEthernetInfo.mEthernetSignalIconId = icon.icon;
+ mEthernetInfo.mEthernetContentDescription = icon.contentDescription;
+ }
if (icon.visible) {
refreshState(mEthernetInfo);
}
@@ -318,11 +373,13 @@
+ "show = " + show + ","
+ "simDetected = " + simDetected);
}
- mCellularInfo.mNoSim = show;
- if (mCellularInfo.mNoSim) {
- // Make sure signal gets cleared out when no sims.
- mCellularInfo.mMobileSignalIconId = 0;
- mCellularInfo.mQsTypeIcon = 0;
+ synchronized (mCellularInfo) {
+ mCellularInfo.mNoSim = show;
+ if (mCellularInfo.mNoSim) {
+ // Make sure signal gets cleared out when no sims.
+ mCellularInfo.mMobileSignalIconId = 0;
+ mCellularInfo.mQsTypeIcon = 0;
+ }
}
}
@@ -335,8 +392,12 @@
if (mCellularInfo.mAirplaneModeEnabled == icon.visible) {
return;
}
- mCellularInfo.mAirplaneModeEnabled = icon.visible;
- mWifiInfo.mAirplaneModeEnabled = icon.visible;
+ synchronized (mCellularInfo) {
+ mCellularInfo.mAirplaneModeEnabled = icon.visible;
+ }
+ synchronized (mWifiInfo) {
+ mWifiInfo.mAirplaneModeEnabled = icon.visible;
+ }
if (!mSignalCallback.mEthernetInfo.mConnected) {
// Always use mWifiInfo to refresh the Internet Tile if airplane mode is enabled,
// because Internet Tile will show different information depending on whether WiFi
@@ -363,12 +424,16 @@
+ "noValidatedNetwork = " + noValidatedNetwork + ","
+ "noNetworksAvailable = " + noNetworksAvailable);
}
- mCellularInfo.mNoDefaultNetwork = noDefaultNetwork;
- mCellularInfo.mNoValidatedNetwork = noValidatedNetwork;
- mCellularInfo.mNoNetworksAvailable = noNetworksAvailable;
- mWifiInfo.mNoDefaultNetwork = noDefaultNetwork;
- mWifiInfo.mNoValidatedNetwork = noValidatedNetwork;
- mWifiInfo.mNoNetworksAvailable = noNetworksAvailable;
+ synchronized (mCellularInfo) {
+ mCellularInfo.mNoDefaultNetwork = noDefaultNetwork;
+ mCellularInfo.mNoValidatedNetwork = noValidatedNetwork;
+ mCellularInfo.mNoNetworksAvailable = noNetworksAvailable;
+ }
+ synchronized (mWifiInfo) {
+ mWifiInfo.mNoDefaultNetwork = noDefaultNetwork;
+ mWifiInfo.mNoValidatedNetwork = noValidatedNetwork;
+ mWifiInfo.mNoNetworksAvailable = noNetworksAvailable;
+ }
if (!noDefaultNetwork) {
return;
}
@@ -403,11 +468,23 @@
// arg = null, in this case the last updated CellularCallbackInfo or WifiCallbackInfo
// should be used to refresh the tile.
if (mLastTileState == LAST_STATE_CELLULAR) {
- handleUpdateCellularState(state, mSignalCallback.mCellularInfo);
+ CellularCallbackInfo cellularInfo = new CellularCallbackInfo();
+ synchronized (mSignalCallback.mCellularInfo) {
+ mSignalCallback.mCellularInfo.copyTo(cellularInfo);
+ }
+ handleUpdateCellularState(state, cellularInfo);
} else if (mLastTileState == LAST_STATE_WIFI) {
- handleUpdateWifiState(state, mSignalCallback.mWifiInfo);
+ WifiCallbackInfo mifiInfo = new WifiCallbackInfo();
+ synchronized (mSignalCallback.mWifiInfo) {
+ mSignalCallback.mWifiInfo.copyTo(mifiInfo);
+ }
+ handleUpdateCellularState(state, mifiInfo);
} else if (mLastTileState == LAST_STATE_ETHERNET) {
- handleUpdateEthernetState(state, mSignalCallback.mEthernetInfo);
+ EthernetCallbackInfo ethernetInfo = new EthernetCallbackInfo();
+ synchronized (mSignalCallback.mEthernetInfo) {
+ mSignalCallback.mEthernetInfo.copyTo(ethernetInfo);
+ }
+ handleUpdateCellularState(state, ethernetInfo);
}
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
index 89d402a3..27f5826 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/LocationTile.java
@@ -38,6 +38,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.statusbar.policy.KeyguardStateController;
import com.android.systemui.statusbar.policy.LocationController;
@@ -52,6 +53,7 @@
private final LocationController mController;
private final KeyguardStateController mKeyguard;
+ private final PanelInteractor mPanelInteractor;
private final Callback mCallback = new Callback();
@Inject
@@ -65,12 +67,14 @@
ActivityStarter activityStarter,
QSLogger qsLogger,
LocationController locationController,
- KeyguardStateController keyguardStateController
+ KeyguardStateController keyguardStateController,
+ PanelInteractor panelInteractor
) {
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
statusBarStateController, activityStarter, qsLogger);
mController = locationController;
mKeyguard = keyguardStateController;
+ mPanelInteractor = panelInteractor;
mController.observe(this, mCallback);
mKeyguard.observe(this, mCallback);
}
@@ -90,7 +94,7 @@
if (mKeyguard.isMethodSecure() && mKeyguard.isShowing()) {
mActivityStarter.postQSRunnableDismissingKeyguard(() -> {
final boolean wasEnabled = mState.value;
- mHost.openPanels();
+ mPanelInteractor.openPanels();
mController.setLocationEnabled(!wasEnabled);
});
return;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
index 07b50c9..65592a7 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/tiles/ScreenRecordTile.java
@@ -42,6 +42,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
@@ -66,6 +67,7 @@
private final Callback mCallback = new Callback();
private final DialogLaunchAnimator mDialogLaunchAnimator;
private final FeatureFlags mFlags;
+ private final PanelInteractor mPanelInteractor;
private long mMillisUntilFinished = 0;
@@ -83,7 +85,8 @@
RecordingController controller,
KeyguardDismissUtil keyguardDismissUtil,
KeyguardStateController keyguardStateController,
- DialogLaunchAnimator dialogLaunchAnimator
+ DialogLaunchAnimator dialogLaunchAnimator,
+ PanelInteractor panelInteractor
) {
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
statusBarStateController, activityStarter, qsLogger);
@@ -93,6 +96,7 @@
mKeyguardDismissUtil = keyguardDismissUtil;
mKeyguardStateController = keyguardStateController;
mDialogLaunchAnimator = dialogLaunchAnimator;
+ mPanelInteractor = panelInteractor;
}
@Override
@@ -171,7 +175,7 @@
// disable the exit animation which looks weird when it happens at the same time as the
// shade collapsing.
mDialogLaunchAnimator.disableAllCurrentDialogsExitAnimations();
- getHost().collapsePanels();
+ mPanelInteractor.collapsePanels();
};
final Dialog dialog = mController.createScreenRecordDialog(mContext, mFlags,
diff --git a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
index 8a3ecc6..0748bcb 100644
--- a/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
+++ b/packages/SystemUI/src/com/android/systemui/recents/OverviewProxyService.java
@@ -21,7 +21,6 @@
import static android.view.MotionEvent.ACTION_DOWN;
import static android.view.MotionEvent.ACTION_UP;
import static android.view.WindowManagerPolicyConstants.NAV_BAR_MODE_3BUTTON;
-
import static com.android.internal.accessibility.common.ShortcutConstants.CHOOSER_PACKAGE_NAME;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SUPPORTS_WINDOW_CORNERS;
import static com.android.systemui.shared.system.QuickStepContract.KEY_EXTRA_SYSUI_PROXY;
@@ -713,6 +712,7 @@
}
public void startConnectionToCurrentUser() {
+ Log.v(TAG_OPS, "startConnectionToCurrentUser: connection is restarted");
if (mHandler.getLooper() != Looper.myLooper()) {
mHandler.post(mConnectionRunnable);
} else {
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
index 557e95c..7ad594e 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotController.java
@@ -115,6 +115,8 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.TimeoutException;
import java.util.function.Consumer;
import java.util.function.Supplier;
@@ -613,11 +615,13 @@
// Note that this may block if the sound is still being loaded (very unlikely) but we can't
// reliably release in the background because the service is being destroyed.
try {
- MediaPlayer player = mCameraSound.get();
+ MediaPlayer player = mCameraSound.get(1, TimeUnit.SECONDS);
if (player != null) {
player.release();
}
- } catch (InterruptedException | ExecutionException e) {
+ } catch (InterruptedException | ExecutionException | TimeoutException e) {
+ mCameraSound.cancel(true);
+ Log.w(TAG, "Error releasing shutter sound", e);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt
index 48aa60f..253f07d 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/ScreenshotDetectionController.kt
@@ -17,6 +17,8 @@
package com.android.systemui.screenshot
import android.content.pm.PackageManager
+import android.content.pm.PackageManager.ComponentInfoFlags
+import android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS
import android.view.Display
import android.view.IWindowManager
import android.view.ViewGroup
@@ -45,7 +47,7 @@
// Convert component names to app names.
return components.map {
packageManager
- .getActivityInfo(it, PackageManager.ComponentInfoFlags.of(0))
+ .getActivityInfo(it, ComponentInfoFlags.of(MATCH_DISABLED_COMPONENTS.toLong()))
.loadLabel(packageManager)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
index 236213c..798c490 100644
--- a/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
+++ b/packages/SystemUI/src/com/android/systemui/screenshot/WorkProfileMessageController.kt
@@ -19,6 +19,7 @@
import android.content.ComponentName
import android.content.Context
import android.content.pm.PackageManager
+import android.content.pm.PackageManager.ComponentInfoFlags
import android.graphics.drawable.Drawable
import android.os.UserHandle
import android.os.UserManager
@@ -53,12 +54,9 @@
var badgedIcon: Drawable? = null
var label: CharSequence? = null
val fileManager = fileManagerComponentName()
+ ?: return WorkProfileFirstRunData(defaultFileAppName(), null)
try {
- val info =
- packageManager.getActivityInfo(
- fileManager,
- PackageManager.ComponentInfoFlags.of(0)
- )
+ val info = packageManager.getActivityInfo(fileManager, ComponentInfoFlags.of(0L))
val icon = packageManager.getActivityIcon(fileManager)
badgedIcon = packageManager.getUserBadgedIcon(icon, userHandle)
label = info.loadLabel(packageManager)
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
index 06426b3..3360511 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationPanelViewController.java
@@ -159,6 +159,7 @@
import com.android.systemui.navigationbar.NavigationBarController;
import com.android.systemui.navigationbar.NavigationBarView;
import com.android.systemui.navigationbar.NavigationModeController;
+import com.android.systemui.plugins.ClockAnimations;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.FalsingManager.FalsingTapListener;
import com.android.systemui.plugins.qs.QS;
@@ -849,7 +850,7 @@
mLayoutInflater = layoutInflater;
mFeatureFlags = featureFlags;
mAnimateBack = mFeatureFlags.isEnabled(Flags.WM_SHADE_ANIMATE_BACK_GESTURE);
- mTrackpadGestureBack = mFeatureFlags.isEnabled(Flags.TRACKPAD_GESTURE_BACK);
+ mTrackpadGestureBack = mFeatureFlags.isEnabled(Flags.TRACKPAD_GESTURE_FEATURES);
mFalsingCollector = falsingCollector;
mPowerManager = powerManager;
mWakeUpCoordinator = coordinator;
@@ -1592,10 +1593,9 @@
transition.setInterpolator(Interpolators.FAST_OUT_SLOW_IN);
transition.setDuration(StackStateAnimator.ANIMATION_DURATION_STANDARD);
- boolean customClockAnimation =
- mKeyguardStatusViewController.getClockAnimations() != null
- && mKeyguardStatusViewController.getClockAnimations()
- .getHasCustomPositionUpdatedAnimation();
+ ClockAnimations clockAnims = mKeyguardStatusViewController.getClockAnimations();
+ boolean customClockAnimation = clockAnims != null
+ && clockAnims.getHasCustomPositionUpdatedAnimation();
if (mFeatureFlags.isEnabled(Flags.STEP_CLOCK_ANIMATION) && customClockAnimation) {
// Find the clock, so we can exclude it from this transition.
@@ -2805,6 +2805,7 @@
public void setIsLaunchAnimationRunning(boolean running) {
boolean wasRunning = mIsLaunchAnimationRunning;
mIsLaunchAnimationRunning = running;
+ mCentralSurfaces.updateIsKeyguard();
if (wasRunning != mIsLaunchAnimationRunning) {
mShadeExpansionStateManager.notifyLaunchingActivityChanged(running);
}
@@ -2896,15 +2897,7 @@
mHeadsUpManager.addListener(mOnHeadsUpChangedListener);
mHeadsUpTouchHelper = new HeadsUpTouchHelper(headsUpManager,
mNotificationStackScrollLayoutController.getHeadsUpCallback(),
- NotificationPanelViewController.this);
- }
-
- public void setTrackedHeadsUp(ExpandableNotificationRow pickedChild) {
- if (pickedChild != null) {
- updateTrackingHeadsUp(pickedChild);
- mExpandingFromHeadsUp = true;
- }
- // otherwise we update the state when the expansion is finished
+ new HeadsUpNotificationViewControllerImpl());
}
private void onClosingFinished() {
@@ -2952,7 +2945,8 @@
}
/** Called when a HUN is dragged up or down to indicate the starting height for shade motion. */
- public void setHeadsUpDraggingStartingHeight(int startHeight) {
+ @VisibleForTesting
+ void setHeadsUpDraggingStartingHeight(int startHeight) {
mHeadsUpStartHeight = startHeight;
float scrimMinFraction;
if (mSplitShadeEnabled) {
@@ -2986,10 +2980,6 @@
mScrimController.setPanelScrimMinFraction(mMinFraction);
}
- public void clearNotificationEffects() {
- mCentralSurfaces.clearNotificationEffects();
- }
-
private boolean isPanelVisibleBecauseOfHeadsUp() {
return (mHeadsUpManager.hasPinnedHeadsUp() || mHeadsUpAnimatingAway)
&& mBarState == StatusBarState.SHADE;
@@ -3581,15 +3571,12 @@
}
private void endMotionEvent(MotionEvent event, float x, float y, boolean forceCancel) {
- // don't fling while in keyguard to avoid jump in shade expand animation
- boolean fullyExpandedInKeyguard = mBarState == KEYGUARD && mExpandedFraction >= 1.0;
mTrackingPointer = -1;
mAmbientState.setSwipingUp(false);
- if (!fullyExpandedInKeyguard && ((mTracking && mTouchSlopExceeded)
- || Math.abs(x - mInitialExpandX) > mTouchSlop
+ if ((mTracking && mTouchSlopExceeded) || Math.abs(x - mInitialExpandX) > mTouchSlop
|| Math.abs(y - mInitialExpandY) > mTouchSlop
|| (!isFullyExpanded() && !isFullyCollapsed())
- || event.getActionMasked() == MotionEvent.ACTION_CANCEL || forceCancel)) {
+ || event.getActionMasked() == MotionEvent.ACTION_CANCEL || forceCancel) {
mVelocityTracker.computeCurrentVelocity(1000);
float vel = mVelocityTracker.getYVelocity();
float vectorVel = (float) Math.hypot(
@@ -3631,15 +3618,21 @@
: (mKeyguardStateController.canDismissLockScreen()
? UNLOCK : BOUNCER_UNLOCK);
- fling(vel, expand, isFalseTouch(x, y, interactionType));
+ // don't fling while in keyguard to avoid jump in shade expand animation;
+ // touch has been intercepted already so flinging here is redundant
+ if (mBarState == KEYGUARD && mExpandedFraction >= 1.0) {
+ mShadeLog.d("NPVC endMotionEvent - skipping fling on keyguard");
+ } else {
+ fling(vel, expand, isFalseTouch(x, y, interactionType));
+ }
onTrackingStopped(expand);
mUpdateFlingOnLayout = expand && mPanelClosedOnDown && !mHasLayoutedSinceDown;
if (mUpdateFlingOnLayout) {
mUpdateFlingVelocity = vel;
}
- } else if (fullyExpandedInKeyguard || (!mCentralSurfaces.isBouncerShowing()
+ } else if (!mCentralSurfaces.isBouncerShowing()
&& !mAlternateBouncerInteractor.isVisibleState()
- && !mKeyguardStateController.isKeyguardGoingAway())) {
+ && !mKeyguardStateController.isKeyguardGoingAway()) {
onEmptySpaceClick();
onTrackingStopped(true);
}
@@ -3782,10 +3775,10 @@
mHeightAnimator.end();
}
}
- mQsController.setShadeExpandedHeight(mExpandedHeight);
- mExpansionDragDownAmountPx = h;
mExpandedFraction = Math.min(1f,
maxPanelHeight == 0 ? 0 : mExpandedHeight / maxPanelHeight);
+ mQsController.setShadeExpansion(mExpandedHeight, mExpandedFraction);
+ mExpansionDragDownAmountPx = h;
mAmbientState.setExpansionFraction(mExpandedFraction);
onHeightUpdated(mExpandedHeight);
updatePanelExpansionAndVisibility();
@@ -3865,6 +3858,10 @@
return mClosing || mIsLaunchAnimationRunning;
}
+ public boolean isLaunchAnimationRunning() {
+ return mIsLaunchAnimationRunning;
+ }
+
public boolean isTracking() {
return mTracking;
}
@@ -5110,17 +5107,26 @@
captureValues(transitionValues);
}
+ @Nullable
@Override
- public Animator createAnimator(ViewGroup sceneRoot, TransitionValues startValues,
- TransitionValues endValues) {
+ public Animator createAnimator(ViewGroup sceneRoot, @Nullable TransitionValues startValues,
+ @Nullable TransitionValues endValues) {
+ if (startValues == null || endValues == null) {
+ return null;
+ }
ValueAnimator anim = ValueAnimator.ofFloat(0, 1);
Rect from = (Rect) startValues.values.get(PROP_BOUNDS);
Rect to = (Rect) endValues.values.get(PROP_BOUNDS);
- anim.addUpdateListener(
- animation -> mController.getClockAnimations().onPositionUpdated(
- from, to, animation.getAnimatedFraction()));
+ anim.addUpdateListener(animation -> {
+ ClockAnimations clockAnims = mController.getClockAnimations();
+ if (clockAnims == null) {
+ return;
+ }
+
+ clockAnims.onPositionUpdated(from, to, animation.getAnimatedFraction());
+ });
return anim;
}
@@ -5131,6 +5137,33 @@
}
}
+ private final class HeadsUpNotificationViewControllerImpl implements
+ HeadsUpTouchHelper.HeadsUpNotificationViewController {
+ @Override
+ public void setHeadsUpDraggingStartingHeight(int startHeight) {
+ NotificationPanelViewController.this.setHeadsUpDraggingStartingHeight(startHeight);
+ }
+
+ @Override
+ public void setTrackedHeadsUp(ExpandableNotificationRow pickedChild) {
+ if (pickedChild != null) {
+ updateTrackingHeadsUp(pickedChild);
+ mExpandingFromHeadsUp = true;
+ }
+ // otherwise we update the state when the expansion is finished
+ }
+
+ @Override
+ public void startExpand(float x, float y, boolean startTracking, float expandedHeight) {
+ startExpandMotion(x, y, startTracking, expandedHeight);
+ }
+
+ @Override
+ public void clearNotificationEffects() {
+ mCentralSurfaces.clearNotificationEffects();
+ }
+ }
+
private final class ShadeAccessibilityDelegate extends AccessibilityDelegate {
@Override
public void onInitializeAccessibilityNodeInfo(View host,
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
index 156e4fd..e7759df 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowControllerImpl.java
@@ -301,9 +301,11 @@
}
private void applyKeyguardFlags(NotificationShadeWindowState state) {
- final boolean keyguardOrAod = state.keyguardShowing
+ // Keyguard is visible if it's showing or if it's fading away (in which case we're animating
+ // it out, but the wallpaper should remain visible as a backdrop for the animation);
+ final boolean keyguardOrAodVisible = (state.keyguardShowing || state.keyguardFadingAway)
|| (state.dozing && mDozeParameters.getAlwaysOn());
- if ((keyguardOrAod && !state.mediaBackdropShowing && !state.lightRevealScrimOpaque)
+ if ((keyguardOrAodVisible && !state.mediaBackdropShowing && !state.lightRevealScrimOpaque)
|| mKeyguardViewMediator.isAnimatingBetweenKeyguardAndSurfaceBehind()) {
// Show the wallpaper if we're on keyguard/AOD and the wallpaper is not occluded by a
// solid backdrop. Also, show it if we are currently animating between the
diff --git a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
index 2899081..0318fa5 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/NotificationShadeWindowViewController.java
@@ -16,14 +16,13 @@
package com.android.systemui.shade;
-import static com.android.systemui.flags.Flags.TRACKPAD_GESTURE_BACK;
+import static com.android.systemui.flags.Flags.TRACKPAD_GESTURE_COMMON;
import static com.android.systemui.util.kotlin.JavaAdapterKt.collectFlow;
import android.app.StatusBarManager;
import android.media.AudioManager;
import android.media.session.MediaSessionLegacyHelper;
import android.os.PowerManager;
-import android.os.SystemClock;
import android.util.Log;
import android.view.GestureDetector;
import android.view.InputDevice;
@@ -31,24 +30,30 @@
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
+import android.view.ViewStub;
+
+import androidx.annotation.Nullable;
import com.android.internal.annotations.VisibleForTesting;
import com.android.keyguard.AuthKeyguardMessageArea;
import com.android.keyguard.LockIconViewController;
import com.android.keyguard.dagger.KeyguardBouncerComponent;
import com.android.systemui.R;
-import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
import com.android.systemui.classifier.FalsingCollector;
+import com.android.systemui.compose.ComposeFacade;
import com.android.systemui.dock.DockManager;
import com.android.systemui.flags.FeatureFlags;
+import com.android.systemui.flags.Flags;
import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
-import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
import com.android.systemui.keyguard.shared.model.TransitionState;
import com.android.systemui.keyguard.shared.model.TransitionStep;
import com.android.systemui.keyguard.ui.binder.KeyguardBouncerViewBinder;
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
+import com.android.systemui.multishade.domain.interactor.MultiShadeInteractor;
+import com.android.systemui.multishade.domain.interactor.MultiShadeMotionEventInteractor;
+import com.android.systemui.multishade.ui.view.MultiShadeView;
import com.android.systemui.statusbar.DragDownHelper;
import com.android.systemui.statusbar.LockscreenShadeTransitionController;
import com.android.systemui.statusbar.NotificationInsetsController;
@@ -63,11 +68,13 @@
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
import com.android.systemui.statusbar.phone.dagger.CentralSurfacesComponent;
import com.android.systemui.statusbar.window.StatusBarWindowStateController;
+import com.android.systemui.util.time.SystemClock;
import java.io.PrintWriter;
import java.util.function.Consumer;
import javax.inject.Inject;
+import javax.inject.Provider;
/**
* Controller for {@link NotificationShadeWindowView}.
@@ -88,9 +95,7 @@
private final AmbientState mAmbientState;
private final PulsingGestureListener mPulsingGestureListener;
private final NotificationInsetsController mNotificationInsetsController;
- private final AlternateBouncerInteractor mAlternateBouncerInteractor;
- private final UdfpsOverlayInteractor mUdfpsOverlayInteractor;
- private final boolean mIsTrackpadGestureBackEnabled;
+ private final boolean mIsTrackpadCommonEnabled;
private GestureDetector mPulsingWakeupGestureHandler;
private View mBrightnessMirror;
private boolean mTouchActive;
@@ -115,6 +120,8 @@
mIsOcclusionTransitionRunning =
step.getTransitionState() == TransitionState.RUNNING;
};
+ private final SystemClock mClock;
+ private final @Nullable MultiShadeMotionEventInteractor mMultiShadeMotionEventInteractor;
@Inject
public NotificationShadeWindowViewController(
@@ -138,11 +145,12 @@
PulsingGestureListener pulsingGestureListener,
KeyguardBouncerViewModel keyguardBouncerViewModel,
KeyguardBouncerComponent.Factory keyguardBouncerComponentFactory,
- AlternateBouncerInteractor alternateBouncerInteractor,
- UdfpsOverlayInteractor udfpsOverlayInteractor,
KeyguardTransitionInteractor keyguardTransitionInteractor,
PrimaryBouncerToGoneTransitionViewModel primaryBouncerToGoneTransitionViewModel,
- FeatureFlags featureFlags) {
+ FeatureFlags featureFlags,
+ Provider<MultiShadeInteractor> multiShadeInteractorProvider,
+ SystemClock clock,
+ Provider<MultiShadeMotionEventInteractor> multiShadeMotionEventInteractorProvider) {
mLockscreenShadeTransitionController = transitionController;
mFalsingCollector = falsingCollector;
mStatusBarStateController = statusBarStateController;
@@ -161,9 +169,7 @@
mAmbientState = ambientState;
mPulsingGestureListener = pulsingGestureListener;
mNotificationInsetsController = notificationInsetsController;
- mAlternateBouncerInteractor = alternateBouncerInteractor;
- mUdfpsOverlayInteractor = udfpsOverlayInteractor;
- mIsTrackpadGestureBackEnabled = featureFlags.isEnabled(TRACKPAD_GESTURE_BACK);
+ mIsTrackpadCommonEnabled = featureFlags.isEnabled(TRACKPAD_GESTURE_COMMON);
// This view is not part of the newly inflated expanded status bar.
mBrightnessMirror = mView.findViewById(R.id.brightness_mirror_container);
@@ -175,13 +181,19 @@
collectFlow(mView, keyguardTransitionInteractor.getLockscreenToDreamingTransition(),
mLockscreenToDreamingTransition);
- }
- /**
- * @return Location where to place the KeyguardBouncer
- */
- public ViewGroup getBouncerContainer() {
- return mView.findViewById(R.id.keyguard_bouncer_container);
+ mClock = clock;
+ if (ComposeFacade.INSTANCE.isComposeAvailable()
+ && featureFlags.isEnabled(Flags.DUAL_SHADE)) {
+ mMultiShadeMotionEventInteractor = multiShadeMotionEventInteractorProvider.get();
+ final ViewStub multiShadeViewStub = mView.findViewById(R.id.multi_shade_stub);
+ if (multiShadeViewStub != null) {
+ final MultiShadeView multiShadeView = (MultiShadeView) multiShadeViewStub.inflate();
+ multiShadeView.init(multiShadeInteractorProvider.get(), clock);
+ }
+ } else {
+ mMultiShadeMotionEventInteractor = null;
+ }
}
/**
@@ -250,6 +262,9 @@
mFalsingCollector.onTouchEvent(ev);
mPulsingWakeupGestureHandler.onTouchEvent(ev);
+ if (mStatusBarKeyguardViewManager.dispatchTouchEvent(ev)) {
+ return true;
+ }
if (mBrightnessMirror != null
&& mBrightnessMirror.getVisibility() == View.VISIBLE) {
// Disallow new pointers while the brightness mirror is visible. This is so that
@@ -269,7 +284,7 @@
mLockIconViewController.onTouchEvent(
ev,
() -> mService.wakeUpIfDozing(
- SystemClock.uptimeMillis(),
+ mClock.uptimeMillis(),
mView,
"LOCK_ICON_TOUCH",
PowerManager.WAKE_REASON_GESTURE)
@@ -324,9 +339,10 @@
return true;
}
- if (mAlternateBouncerInteractor.isVisibleState()) {
- // If using UDFPS, don't intercept touches that are within its overlay bounds
- return mUdfpsOverlayInteractor.canInterceptTouchInUdfpsBounds(ev);
+ if (mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(ev)) {
+ // Don't allow touches to proceed to underlying views if alternate
+ // bouncer is showing
+ return true;
}
if (mLockIconViewController.onInterceptTouchEvent(ev)) {
@@ -334,16 +350,17 @@
return true;
}
- boolean intercept = false;
- if (mNotificationPanelViewController.isFullyExpanded()
+ if (mMultiShadeMotionEventInteractor != null) {
+ // This interactor is not null only if the dual shade feature is enabled.
+ return mMultiShadeMotionEventInteractor.shouldIntercept(ev);
+ } else if (mNotificationPanelViewController.isFullyExpanded()
&& mDragDownHelper.isDragDownEnabled()
&& !mService.isBouncerShowing()
&& !mStatusBarStateController.isDozing()) {
- intercept = mDragDownHelper.onInterceptTouchEvent(ev);
+ return mDragDownHelper.onInterceptTouchEvent(ev);
+ } else {
+ return false;
}
-
- return intercept;
-
}
@Override
@@ -362,19 +379,24 @@
handled = !mService.isPulsing();
}
- if (mAlternateBouncerInteractor.isVisibleState()) {
- // eat the touch
- mStatusBarKeyguardViewManager.onTouch(ev);
- handled = true;
+ if (mStatusBarKeyguardViewManager.onTouch(ev)) {
+ return true;
}
- if ((mDragDownHelper.isDragDownEnabled() && !handled)
+ if (handled) {
+ return true;
+ }
+
+ if (mMultiShadeMotionEventInteractor != null) {
+ // This interactor is not null only if the dual shade feature is enabled.
+ return mMultiShadeMotionEventInteractor.onTouchEvent(ev, mView.getWidth());
+ } else if (mDragDownHelper.isDragDownEnabled()
|| mDragDownHelper.isDraggingDown()) {
// we still want to finish our drag down gesture when locking the screen
- handled = mDragDownHelper.onTouchEvent(ev);
+ return mDragDownHelper.onTouchEvent(ev);
+ } else {
+ return false;
}
-
- return handled;
}
@Override
@@ -453,9 +475,9 @@
public void cancelCurrentTouch() {
if (mTouchActive) {
- final long now = SystemClock.uptimeMillis();
+ final long now = mClock.uptimeMillis();
final MotionEvent event;
- if (mIsTrackpadGestureBackEnabled) {
+ if (mIsTrackpadCommonEnabled) {
event = MotionEvent.obtain(mDownEvent);
event.setDownTime(now);
event.setAction(MotionEvent.ACTION_CANCEL);
diff --git a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
index df8ae50..9f46707 100644
--- a/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
+++ b/packages/SystemUI/src/com/android/systemui/shade/QuickSettingsController.java
@@ -351,7 +351,6 @@
mFeatureFlags = featureFlags;
mInteractionJankMonitor = interactionJankMonitor;
- mShadeExpansionStateManager.addExpansionListener(this::onPanelExpansionChanged);
mLockscreenShadeTransitionController.addCallback(new LockscreenShadeTransitionCallback());
}
@@ -878,8 +877,9 @@
mCollapsedOnDown = collapsedOnDown;
}
- void setShadeExpandedHeight(float shadeExpandedHeight) {
- mShadeExpandedHeight = shadeExpandedHeight;
+ void setShadeExpansion(float expandedHeight, float expandedFraction) {
+ mShadeExpandedHeight = expandedHeight;
+ mShadeExpandedFraction = expandedFraction;
}
@VisibleForTesting
@@ -1749,11 +1749,6 @@
return false;
}
- @VisibleForTesting
- void onPanelExpansionChanged(ShadeExpansionChangeEvent event) {
- mShadeExpandedFraction = event.getFraction();
- }
-
/**
* Animate QS closing by flinging it.
* If QS is expanded, it will collapse into QQS and stop.
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
index 01e042b..c920e1e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcutListSearch.java
@@ -657,25 +657,6 @@
R.string.input_switch_input_language_previous),
KeyEvent.KEYCODE_SPACE,
KeyEvent.META_META_ON | KeyEvent.META_SHIFT_ON),
- null))),
- /* Access emoji: Meta + . */
- new ShortcutMultiMappingInfo(
- context.getString(R.string.input_access_emoji),
- null,
- Arrays.asList(
- new ShortcutKeyGroup(new KeyboardShortcutInfo(
- context.getString(R.string.input_access_emoji),
- KeyEvent.KEYCODE_PERIOD,
- KeyEvent.META_META_ON),
- null))),
- /* Access voice typing: Meta + V */
- new ShortcutMultiMappingInfo(
- context.getString(R.string.input_access_voice_typing),
- null,
- Arrays.asList(
- new ShortcutKeyGroup(new KeyboardShortcutInfo(
- context.getString(R.string.input_access_voice_typing),
- KeyEvent.KEYCODE_V, KeyEvent.META_META_ON),
null)))
);
return new KeyboardShortcutMultiMappingGroup(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
index 779be2b..fda2277 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyguardIndicationController.java
@@ -28,7 +28,6 @@
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_AVAILABLE;
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FACE_NOT_RECOGNIZED;
import static com.android.keyguard.KeyguardUpdateMonitor.BIOMETRIC_HELP_FINGERPRINT_NOT_RECOGNIZED;
-import static com.android.keyguard.KeyguardUpdateMonitor.getCurrentUser;
import static com.android.systemui.DejankUtils.whitelistIpcs;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.IMPORTANT_MSG_MIN_DURATION;
import static com.android.systemui.keyguard.KeyguardIndicationRotateTextViewController.INDICATION_TYPE_ALIGNMENT;
@@ -99,6 +98,7 @@
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.log.LogLevel;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -146,6 +146,7 @@
private final KeyguardUpdateMonitor mKeyguardUpdateMonitor;
private final AuthController mAuthController;
private final KeyguardLogger mKeyguardLogger;
+ private final UserTracker mUserTracker;
private ViewGroup mIndicationArea;
private KeyguardIndicationTextView mTopIndicationView;
private KeyguardIndicationTextView mLockScreenIndicationView;
@@ -251,7 +252,8 @@
FaceHelpMessageDeferral faceHelpMessageDeferral,
KeyguardLogger keyguardLogger,
AlternateBouncerInteractor alternateBouncerInteractor,
- AlarmManager alarmManager
+ AlarmManager alarmManager,
+ UserTracker userTracker
) {
mContext = context;
mBroadcastDispatcher = broadcastDispatcher;
@@ -275,6 +277,7 @@
mKeyguardLogger = keyguardLogger;
mScreenLifecycle.addObserver(mScreenObserver);
mAlternateBouncerInteractor = alternateBouncerInteractor;
+ mUserTracker = userTracker;
mFaceAcquiredMessageDeferral = faceHelpMessageDeferral;
mCoExFaceAcquisitionMsgIdsToShow = new HashSet<>();
@@ -475,6 +478,10 @@
}
}
+ private int getCurrentUser() {
+ return mUserTracker.getUserId();
+ }
+
private void updateLockScreenOwnerInfo() {
// Check device owner info on a bg thread.
// It makes multiple IPCs that could block the thread it's run on.
@@ -1166,8 +1173,7 @@
mContext.getString(R.string.keyguard_unlock)
);
} else if (fpAuthFailed
- && mKeyguardUpdateMonitor.getUserHasTrust(
- KeyguardUpdateMonitor.getCurrentUser())) {
+ && mKeyguardUpdateMonitor.getUserHasTrust(getCurrentUser())) {
showBiometricMessage(
getTrustGrantedIndication(),
mContext.getString(R.string.keyguard_unlock)
@@ -1421,7 +1427,7 @@
private boolean canUnlockWithFingerprint() {
return mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- KeyguardUpdateMonitor.getCurrentUser());
+ getCurrentUser());
}
private void showErrorMessageNowOrLater(String errString, @Nullable String followUpMsg) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
index 51c5183..cac4251 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationLockscreenUserManagerImpl.java
@@ -16,7 +16,6 @@
package com.android.systemui.statusbar;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_MANAGER_STATE_CHANGED;
-
import static com.android.systemui.DejankUtils.whitelistIpcs;
import android.app.KeyguardManager;
@@ -145,7 +144,10 @@
break;
case Intent.ACTION_USER_UNLOCKED:
// Start the overview connection to the launcher service
- mOverviewProxyServiceLazy.get().startConnectionToCurrentUser();
+ // Connect if user hasn't connected yet
+ if (mOverviewProxyServiceLazy.get().getProxy() == null) {
+ mOverviewProxyServiceLazy.get().startConnectionToCurrentUser();
+ }
break;
case NOTIFICATION_UNLOCKED_BY_WORK_CHALLENGE_ACTION:
final IntentSender intentSender = intent.getParcelableExtra(
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
index 99081e9..9e2a07e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationRemoteInputManager.java
@@ -54,6 +54,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.dagger.CentralSurfacesDependenciesModule;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
+import com.android.systemui.statusbar.notification.RemoteInputControllerLogger;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntry.EditedSuggestionInfo;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
@@ -65,6 +66,8 @@
import com.android.systemui.util.DumpUtilsKt;
import com.android.systemui.util.ListenerSet;
+import dagger.Lazy;
+
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
@@ -72,8 +75,6 @@
import java.util.Optional;
import java.util.function.Consumer;
-import dagger.Lazy;
-
/**
* Class for handling remote input state over a set of notifications. This class handles things
* like keeping notifications temporarily that were cancelled as a response to a remote input
@@ -104,6 +105,8 @@
private final KeyguardManager mKeyguardManager;
private final StatusBarStateController mStatusBarStateController;
private final RemoteInputUriController mRemoteInputUriController;
+
+ private final RemoteInputControllerLogger mRemoteInputControllerLogger;
private final NotificationClickNotifier mClickNotifier;
protected RemoteInputController mRemoteInputController;
@@ -259,6 +262,7 @@
Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
StatusBarStateController statusBarStateController,
RemoteInputUriController remoteInputUriController,
+ RemoteInputControllerLogger remoteInputControllerLogger,
NotificationClickNotifier clickNotifier,
ActionClickLogger logger,
DumpManager dumpManager) {
@@ -275,6 +279,7 @@
mKeyguardManager = context.getSystemService(KeyguardManager.class);
mStatusBarStateController = statusBarStateController;
mRemoteInputUriController = remoteInputUriController;
+ mRemoteInputControllerLogger = remoteInputControllerLogger;
mClickNotifier = clickNotifier;
dumpManager.registerDumpable(this);
@@ -294,7 +299,8 @@
/** Initializes this component with the provided dependencies. */
public void setUpWithCallback(Callback callback, RemoteInputController.Delegate delegate) {
mCallback = callback;
- mRemoteInputController = new RemoteInputController(delegate, mRemoteInputUriController);
+ mRemoteInputController = new RemoteInputController(delegate,
+ mRemoteInputUriController, mRemoteInputControllerLogger);
if (mRemoteInputListener != null) {
mRemoteInputListener.setRemoteInputController(mRemoteInputController);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
index f44f598..a37b2a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/RemoteInputController.java
@@ -28,6 +28,7 @@
import androidx.annotation.NonNull;
+import com.android.systemui.statusbar.notification.RemoteInputControllerLogger;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.policy.RemoteInputUriController;
import com.android.systemui.statusbar.policy.RemoteInputView;
@@ -52,10 +53,14 @@
private final Delegate mDelegate;
private final RemoteInputUriController mRemoteInputUriController;
+ private final RemoteInputControllerLogger mLogger;
+
public RemoteInputController(Delegate delegate,
- RemoteInputUriController remoteInputUriController) {
+ RemoteInputUriController remoteInputUriController,
+ RemoteInputControllerLogger logger) {
mDelegate = delegate;
mRemoteInputUriController = remoteInputUriController;
+ mLogger = logger;
}
/**
@@ -117,6 +122,9 @@
boolean isActive = isRemoteInputActive(entry);
boolean found = pruneWeakThenRemoveAndContains(
entry /* contains */, null /* remove */, token /* removeToken */);
+ mLogger.logAddRemoteInput(entry.getKey()/* entryKey */,
+ isActive /* isRemoteInputAlreadyActive */,
+ found /* isRemoteInputFound */);
if (!found) {
mOpen.add(new Pair<>(new WeakReference<>(entry), token));
}
@@ -137,9 +145,22 @@
*/
public void removeRemoteInput(NotificationEntry entry, Object token) {
Objects.requireNonNull(entry);
- if (entry.mRemoteEditImeVisible && entry.mRemoteEditImeAnimatingAway) return;
+ if (entry.mRemoteEditImeVisible && entry.mRemoteEditImeAnimatingAway) {
+ mLogger.logRemoveRemoteInput(
+ entry.getKey() /* entryKey*/,
+ true /* remoteEditImeVisible */,
+ true /* remoteEditImeAnimatingAway */);
+ return;
+ }
// If the view is being removed, this may be called even though we're not active
- if (!isRemoteInputActive(entry)) return;
+ boolean remoteInputActive = isRemoteInputActive(entry);
+ mLogger.logRemoveRemoteInput(
+ entry.getKey() /* entryKey*/,
+ entry.mRemoteEditImeVisible /* remoteEditImeVisible */,
+ entry.mRemoteEditImeAnimatingAway /* remoteEditImeAnimatingAway */,
+ remoteInputActive /* isRemoteInputActive */);
+
+ if (!remoteInputActive) return;
pruneWeakThenRemoveAndContains(null /* contains */, entry /* remove */, token);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
index b9ac918..79d01b4a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/StatusBarStateControllerImpl.java
@@ -56,6 +56,7 @@
import com.android.systemui.shade.ShadeExpansionStateManager;
import com.android.systemui.statusbar.notification.stack.StackStateAnimator;
import com.android.systemui.statusbar.policy.CallbackController;
+import com.android.systemui.util.Compile;
import java.io.PrintWriter;
import java.util.ArrayList;
@@ -299,7 +300,7 @@
@Override
public boolean setIsDreaming(boolean isDreaming) {
- if (Log.isLoggable(TAG, Log.DEBUG)) {
+ if (Log.isLoggable(TAG, Log.DEBUG) || Compile.IS_DEBUG) {
Log.d(TAG, "setIsDreaming:" + isDreaming);
}
if (mIsDreaming == isDreaming) {
@@ -321,6 +322,11 @@
}
@Override
+ public boolean isDreaming() {
+ return mIsDreaming;
+ }
+
+ @Override
public void setAndInstrumentDozeAmount(View view, float dozeAmount, boolean animated) {
if (mDarkAnimator != null && mDarkAnimator.isRunning()) {
if (animated && mDozeAmountTarget == dozeAmount) {
@@ -580,6 +586,7 @@
pw.println(" mLeaveOpenOnKeyguardHide=" + mLeaveOpenOnKeyguardHide);
pw.println(" mKeyguardRequested=" + mKeyguardRequested);
pw.println(" mIsDozing=" + mIsDozing);
+ pw.println(" mIsDreaming=" + mIsDreaming);
pw.println(" mListeners{" + mListeners.size() + "}=");
for (RankedListener rl : mListeners) {
pw.println(" " + rl.mListener);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
index d7568a9..565c0a9 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/dagger/CentralSurfacesDependenciesModule.java
@@ -54,6 +54,7 @@
import com.android.systemui.statusbar.commandline.CommandRegistry;
import com.android.systemui.statusbar.gesture.SwipeStatusBarAwayGestureHandler;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
+import com.android.systemui.statusbar.notification.RemoteInputControllerLogger;
import com.android.systemui.statusbar.notification.collection.NotifCollection;
import com.android.systemui.statusbar.notification.collection.NotifPipeline;
import com.android.systemui.statusbar.notification.collection.notifcollection.CommonNotifCollection;
@@ -77,14 +78,14 @@
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.time.SystemClock;
-import java.util.Optional;
-import java.util.concurrent.Executor;
-
import dagger.Binds;
import dagger.Lazy;
import dagger.Module;
import dagger.Provides;
+import java.util.Optional;
+import java.util.concurrent.Executor;
+
/**
* This module provides instances needed to construct {@link CentralSurfacesImpl}. These are moved to
* this separate from {@link CentralSurfacesModule} module so that components that wish to build
@@ -105,6 +106,7 @@
Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
StatusBarStateController statusBarStateController,
RemoteInputUriController remoteInputUriController,
+ RemoteInputControllerLogger remoteInputControllerLogger,
NotificationClickNotifier clickNotifier,
ActionClickLogger actionClickLogger,
DumpManager dumpManager) {
@@ -117,6 +119,7 @@
centralSurfacesOptionalLazy,
statusBarStateController,
remoteInputUriController,
+ remoteInputControllerLogger,
clickNotifier,
actionClickLogger,
dumpManager);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/RemoteInputControllerLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/RemoteInputControllerLogger.kt
new file mode 100644
index 0000000..9582dfad
--- /dev/null
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/RemoteInputControllerLogger.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.statusbar.notification
+
+import com.android.systemui.dagger.SysUISingleton
+import com.android.systemui.log.dagger.NotificationRemoteInputLog
+import com.android.systemui.plugins.log.LogBuffer
+import com.android.systemui.plugins.log.LogLevel.DEBUG
+import javax.inject.Inject
+
+/** Logger class for [RemoteInputController]. */
+@SysUISingleton
+class RemoteInputControllerLogger
+@Inject
+constructor(@NotificationRemoteInputLog private val logBuffer: LogBuffer) {
+
+ /** logs addRemoteInput invocation of [RemoteInputController] */
+ fun logAddRemoteInput(
+ entryKey: String,
+ isRemoteInputAlreadyActive: Boolean,
+ isRemoteInputFound: Boolean
+ ) =
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = entryKey
+ bool1 = isRemoteInputAlreadyActive
+ bool2 = isRemoteInputFound
+ },
+ { "addRemoteInput entry: $str1, isAlreadyActive: $bool1, isFound:$bool2" }
+ )
+
+ /** logs removeRemoteInput invocation of [RemoteInputController] */
+ @JvmOverloads
+ fun logRemoveRemoteInput(
+ entryKey: String,
+ remoteEditImeVisible: Boolean,
+ remoteEditImeAnimatingAway: Boolean,
+ isRemoteInputActive: Boolean? = null
+ ) =
+ logBuffer.log(
+ TAG,
+ DEBUG,
+ {
+ str1 = entryKey
+ bool1 = remoteEditImeVisible
+ bool2 = remoteEditImeAnimatingAway
+ str2 = isRemoteInputActive?.toString() ?: "N/A"
+ },
+ {
+ "removeRemoteInput entry: $str1, remoteEditImeVisible: $bool1" +
+ ", remoteEditImeAnimatingAway: $bool2, isActive: $str2"
+ }
+ )
+
+ private companion object {
+ private const val TAG = "RemoteInputControllerLog"
+ }
+}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
index 82b1268..02bf3b3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/collection/coordinator/GroupCountCoordinator.kt
@@ -1,3 +1,19 @@
+/*
+ * Copyright 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
package com.android.systemui.statusbar.notification.collection.coordinator
import android.util.ArrayMap
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
index 5ba8801..bfb6416 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProvider.java
@@ -94,7 +94,11 @@
/**
* No conditions blocking FSI launch.
*/
- FSI_EXPECTED_NOT_TO_HUN(true);
+ FSI_EXPECTED_NOT_TO_HUN(true),
+ /**
+ * The notification is coming from a suspended packages, so FSI is suppressed.
+ */
+ NO_FSI_SUSPENDED(false);
public final boolean shouldLaunch;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
index 274377f..4aaa7ca 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImpl.java
@@ -28,12 +28,8 @@
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.PowerManager;
-import android.os.RemoteException;
-import android.os.SystemProperties;
import android.provider.Settings;
-import android.service.dreams.IDreamManager;
import android.service.notification.StatusBarNotification;
-import android.util.Log;
import androidx.annotation.NonNull;
@@ -70,7 +66,6 @@
private final KeyguardStateController mKeyguardStateController;
private final ContentResolver mContentResolver;
private final PowerManager mPowerManager;
- private final IDreamManager mDreamManager;
private final AmbientDisplayConfiguration mAmbientDisplayConfiguration;
private final BatteryController mBatteryController;
private final HeadsUpManager mHeadsUpManager;
@@ -112,7 +107,6 @@
public NotificationInterruptStateProviderImpl(
ContentResolver contentResolver,
PowerManager powerManager,
- IDreamManager dreamManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
BatteryController batteryController,
StatusBarStateController statusBarStateController,
@@ -126,7 +120,6 @@
UserTracker userTracker) {
mContentResolver = contentResolver;
mPowerManager = powerManager;
- mDreamManager = dreamManager;
mBatteryController = batteryController;
mAmbientDisplayConfiguration = ambientDisplayConfiguration;
mStatusBarStateController = statusBarStateController;
@@ -280,6 +273,12 @@
suppressedByDND);
}
+ // Notification is coming from a suspended package, block FSI
+ if (entry.getRanking().isSuspended()) {
+ return getDecisionGivenSuppression(FullScreenIntentDecision.NO_FSI_SUSPENDED,
+ suppressedByDND);
+ }
+
// If the screen is off, then launch the FullScreenIntent
if (!mPowerManager.isInteractive()) {
return getDecisionGivenSuppression(FullScreenIntentDecision.FSI_DEVICE_NOT_INTERACTIVE,
@@ -287,7 +286,9 @@
}
// If the device is currently dreaming, then launch the FullScreenIntent
- if (isDreaming()) {
+ // We avoid using IDreamManager#isDreaming here as that method will return false during
+ // the dream's wake-up phase.
+ if (mStatusBarStateController.isDreaming()) {
return getDecisionGivenSuppression(FullScreenIntentDecision.FSI_DEVICE_IS_DREAMING,
suppressedByDND);
}
@@ -365,16 +366,6 @@
}
}
}
-
- private boolean isDreaming() {
- try {
- return mDreamManager.isDreaming();
- } catch (RemoteException e) {
- Log.e(TAG, "Failed to query dream manager.", e);
- return false;
- }
- }
-
private boolean shouldHeadsUpWhenAwake(NotificationEntry entry, boolean log) {
StatusBarNotification sbn = entry.getSbn();
@@ -424,7 +415,7 @@
return false;
}
- boolean inUse = mPowerManager.isScreenOn() && !isDreaming();
+ boolean inUse = mPowerManager.isScreenOn() && !mStatusBarStateController.isDreaming();
if (!inUse) {
if (log) mLogger.logNoHeadsUpNotInUse(entry);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
index 87d54a4..78392f7 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/row/NotificationContentView.java
@@ -2062,6 +2062,23 @@
pw.print("null");
}
pw.println();
+
+ pw.print("RemoteInputViews { ");
+ pw.print(" visibleType: " + mVisibleType);
+ if (mHeadsUpRemoteInputController != null) {
+ pw.print(", headsUpRemoteInputController.isActive: "
+ + mHeadsUpRemoteInputController.isActive());
+ } else {
+ pw.print(", headsUpRemoteInputController: null");
+ }
+
+ if (mExpandedRemoteInputController != null) {
+ pw.print(", expandedRemoteInputController.isActive: "
+ + mExpandedRemoteInputController.isActive());
+ } else {
+ pw.print(", expandedRemoteInputController: null");
+ }
+ pw.println(" }");
}
/** Add any existing SmartReplyView to the dump */
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 2c088fa..c0aed7a 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
@@ -732,19 +732,28 @@
return;
}
// TODO: move this logic to controller, which will invoke updateFooterView directly
- boolean showDismissView = mClearAllEnabled &&
- mController.hasActiveClearableNotifications(ROWS_ALL);
- boolean showFooterView = (showDismissView || mController.getVisibleNotificationCount() > 0)
- && mIsCurrentUserSetup // see: b/193149550
+ final boolean showHistory = mController.isHistoryEnabled();
+ final boolean showDismissView = shouldShowDismissView();
+
+ updateFooterView(shouldShowFooterView(showDismissView)/* visible */,
+ showDismissView /* showDismissView */,
+ showHistory/* showHistory */);
+ }
+
+ private boolean shouldShowDismissView() {
+ return mClearAllEnabled
+ && mController.hasActiveClearableNotifications(ROWS_ALL);
+ }
+
+ private boolean shouldShowFooterView(boolean showDismissView) {
+ return (showDismissView || mController.getVisibleNotificationCount() > 0)
+ && mIsCurrentUserSetup // see: b/193149550
&& !onKeyguard()
&& mUpcomingStatusBarState != StatusBarState.KEYGUARD
// quick settings don't affect notifications when not in full screen
&& (mQsExpansionFraction != 1 || !mQsFullScreen)
&& !mScreenOffAnimationController.shouldHideNotificationsFooter()
&& !mIsRemoteInputActive;
- boolean showHistory = mController.isHistoryEnabled();
-
- updateFooterView(showFooterView, showDismissView, showHistory);
}
/**
@@ -5278,29 +5287,71 @@
});
pw.println();
pw.println("Contents:");
- DumpUtilsKt.withIncreasedIndent(pw, () -> {
- int childCount = getChildCount();
- pw.println("Number of children: " + childCount);
- pw.println();
+ DumpUtilsKt.withIncreasedIndent(
+ pw,
+ () -> {
+ int childCount = getChildCount();
+ pw.println("Number of children: " + childCount);
+ pw.println();
- for (int i = 0; i < childCount; i++) {
- ExpandableView child = getChildAtIndex(i);
- child.dump(pw, args);
- pw.println();
- }
- int transientViewCount = getTransientViewCount();
- pw.println("Transient Views: " + transientViewCount);
- for (int i = 0; i < transientViewCount; i++) {
- ExpandableView child = (ExpandableView) getTransientView(i);
- child.dump(pw, args);
- }
- View swipedView = mSwipeHelper.getSwipedView();
- pw.println("Swiped view: " + swipedView);
- if (swipedView instanceof ExpandableView) {
- ExpandableView expandableView = (ExpandableView) swipedView;
- expandableView.dump(pw, args);
- }
- });
+ for (int i = 0; i < childCount; i++) {
+ ExpandableView child = getChildAtIndex(i);
+ child.dump(pw, args);
+ if (child instanceof FooterView) {
+ DumpUtilsKt.withIncreasedIndent(pw, () -> dumpFooterViewVisibility(pw));
+ }
+ pw.println();
+ }
+ int transientViewCount = getTransientViewCount();
+ pw.println("Transient Views: " + transientViewCount);
+ for (int i = 0; i < transientViewCount; i++) {
+ ExpandableView child = (ExpandableView) getTransientView(i);
+ child.dump(pw, args);
+ }
+ View swipedView = mSwipeHelper.getSwipedView();
+ pw.println("Swiped view: " + swipedView);
+ if (swipedView instanceof ExpandableView) {
+ ExpandableView expandableView = (ExpandableView) swipedView;
+ expandableView.dump(pw, args);
+ }
+ });
+ }
+
+ private void dumpFooterViewVisibility(IndentingPrintWriter pw) {
+ final boolean showDismissView = shouldShowDismissView();
+
+ pw.println("showFooterView: " + shouldShowFooterView(showDismissView));
+ DumpUtilsKt.withIncreasedIndent(
+ pw,
+ () -> {
+ pw.println("showDismissView: " + showDismissView);
+ DumpUtilsKt.withIncreasedIndent(
+ pw,
+ () -> {
+ pw.println("mClearAllEnabled: " + mClearAllEnabled);
+ pw.println(
+ "hasActiveClearableNotifications: "
+ + mController.hasActiveClearableNotifications(
+ ROWS_ALL));
+ });
+ pw.println();
+ pw.println("showHistory: " + mController.isHistoryEnabled());
+ pw.println();
+ pw.println(
+ "visibleNotificationCount: "
+ + mController.getVisibleNotificationCount());
+ pw.println("mIsCurrentUserSetup: " + mIsCurrentUserSetup);
+ pw.println("onKeyguard: " + onKeyguard());
+ pw.println("mUpcomingStatusBarState: " + mUpcomingStatusBarState);
+ pw.println("mQsExpansionFraction: " + mQsExpansionFraction);
+ pw.println("mQsFullScreen: " + mQsFullScreen);
+ pw.println(
+ "mScreenOffAnimationController"
+ + ".shouldHideNotificationsFooter: "
+ + mScreenOffAnimationController
+ .shouldHideNotificationsFooter());
+ pw.println("mIsRemoteInputActive: " + mIsRemoteInputActive);
+ });
}
@ShadeViewRefactor(RefactorComponent.SHADE_VIEW)
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 e8058b8..769edf7 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
@@ -831,18 +831,16 @@
private boolean isInVisibleLocation(NotificationEntry entry) {
ExpandableNotificationRow row = entry.getRow();
- ExpandableViewState childViewState = row.getViewState();
-
- if (childViewState == null) {
+ if (row == null) {
return false;
}
+
+ ExpandableViewState childViewState = row.getViewState();
if ((childViewState.location & ExpandableViewState.VISIBLE_LOCATIONS) == 0) {
return false;
}
- if (row.getVisibility() != View.VISIBLE) {
- return false;
- }
- return true;
+
+ return row.getVisibility() == View.VISIBLE;
}
public boolean isViewAffectedBySwipe(ExpandableView expandableView) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
index 55fa479..7f8c135 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfaces.java
@@ -217,8 +217,6 @@
NotificationPanelViewController getNotificationPanelViewController();
- ViewGroup getBouncerContainer();
-
/** Get the Keyguard Message Area that displays auth messages. */
AuthKeyguardMessageArea getKeyguardMessageArea();
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 87f33a4a..f105d1c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/CentralSurfacesImpl.java
@@ -1053,6 +1053,8 @@
// The light reveal scrim should always be fully revealed by the time the keyguard
// is done going away. Double check that this is true.
if (!mKeyguardStateController.isKeyguardGoingAway()) {
+ updateIsKeyguard();
+
if (mLightRevealScrim.getRevealAmount() != 1f) {
Log.e(TAG, "Keyguard is done going away, but someone left the light reveal "
+ "scrim at reveal amount: " + mLightRevealScrim.getRevealAmount());
@@ -1723,11 +1725,6 @@
}
@Override
- public ViewGroup getBouncerContainer() {
- return mNotificationShadeWindowViewController.getBouncerContainer();
- }
-
- @Override
public AuthKeyguardMessageArea getKeyguardMessageArea() {
return mNotificationShadeWindowViewController.getKeyguardMessageArea();
}
@@ -2946,6 +2943,10 @@
showKeyguardImpl();
}
} else {
+ final boolean isLaunchingOrGoingAway =
+ mNotificationPanelViewController.isLaunchAnimationRunning()
+ || mKeyguardStateController.isKeyguardGoingAway();
+
// During folding a foldable device this might be called as a result of
// 'onScreenTurnedOff' call for the inner display.
// In this case:
@@ -2957,7 +2958,14 @@
if (!mScreenOffAnimationController.isKeyguardHideDelayed()
// If we're animating occluded, there's an activity launching over the keyguard
// UI. Wait to hide it until after the animation concludes.
- && !mKeyguardViewMediator.isOccludeAnimationPlaying()) {
+ && !mKeyguardViewMediator.isOccludeAnimationPlaying()
+ // If we're occluded, but playing an animation (launch or going away animations)
+ // the keyguard is visible behind the animation.
+ && !(mKeyguardStateController.isOccluded() && isLaunchingOrGoingAway)) {
+ // If we're going away and occluded, it means we are launching over the
+ // unsecured keyguard, which will subsequently go away. Wait to hide it until
+ // after the animation concludes to avoid the lockscreen UI changing into the
+ // shade UI behind the launch animation.
return hideKeyguardImpl(forceStateChange);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
index 90d0b69..16c2e36 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/HeadsUpTouchHelper.java
@@ -21,7 +21,6 @@
import android.view.ViewConfiguration;
import com.android.systemui.Gefingerpoken;
-import com.android.systemui.shade.NotificationPanelViewController;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.row.ExpandableNotificationRow;
import com.android.systemui.statusbar.notification.row.ExpandableView;
@@ -31,21 +30,21 @@
*/
public class HeadsUpTouchHelper implements Gefingerpoken {
- private HeadsUpManagerPhone mHeadsUpManager;
- private Callback mCallback;
+ private final HeadsUpManagerPhone mHeadsUpManager;
+ private final Callback mCallback;
private int mTrackingPointer;
- private float mTouchSlop;
+ private final float mTouchSlop;
private float mInitialTouchX;
private float mInitialTouchY;
private boolean mTouchingHeadsUpView;
private boolean mTrackingHeadsUp;
private boolean mCollapseSnoozes;
- private NotificationPanelViewController mPanel;
+ private final HeadsUpNotificationViewController mPanel;
private ExpandableNotificationRow mPickedChild;
public HeadsUpTouchHelper(HeadsUpManagerPhone headsUpManager,
Callback callback,
- NotificationPanelViewController notificationPanelView) {
+ HeadsUpNotificationViewController notificationPanelView) {
mHeadsUpManager = headsUpManager;
mCallback = callback;
mPanel = notificationPanelView;
@@ -116,7 +115,7 @@
int startHeight = (int) (mPickedChild.getActualHeight()
+ mPickedChild.getTranslationY());
mPanel.setHeadsUpDraggingStartingHeight(startHeight);
- mPanel.startExpandMotion(x, y, true /* startTracking */, startHeight);
+ mPanel.startExpand(x, y, true /* startTracking */, startHeight);
// This call needs to be after the expansion start otherwise we will get a
// flicker of one frame as it's not expanded yet.
mHeadsUpManager.unpinAll(true);
@@ -181,4 +180,19 @@
boolean isExpanded();
Context getContext();
}
+
+ /** The controller for a view that houses heads up notifications. */
+ public interface HeadsUpNotificationViewController {
+ /** Called when a HUN is dragged to indicate the starting height for shade motion. */
+ void setHeadsUpDraggingStartingHeight(int startHeight);
+
+ /** Sets notification that is being expanded. */
+ void setTrackedHeadsUp(ExpandableNotificationRow expandableNotificationRow);
+
+ /** Called when a MotionEvent is about to trigger expansion. */
+ void startExpand(float newX, float newY, boolean startTracking, float expandedHeight);
+
+ /** Clear any effects that were added for the expansion. */
+ void clearNotificationEffects();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
index 9a5d1b5..62d302f 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewController.kt
@@ -26,6 +26,8 @@
import android.view.ViewTreeObserver
import com.android.systemui.Gefingerpoken
import com.android.systemui.R
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.shade.ShadeController
import com.android.systemui.shade.ShadeLogger
import com.android.systemui.shared.animation.UnfoldMoveFromCenterAnimator
@@ -215,6 +217,7 @@
private val unfoldComponent: Optional<SysUIUnfoldComponent>,
@Named(UNFOLD_STATUS_BAR)
private val progressProvider: Optional<ScopedUnfoldTransitionProgressProvider>,
+ private val featureFlags: FeatureFlags,
private val userChipViewModel: StatusBarUserChipViewModel,
private val centralSurfaces: CentralSurfaces,
private val shadeController: ShadeController,
@@ -224,17 +227,25 @@
) {
fun create(
view: PhoneStatusBarView
- ) =
- PhoneStatusBarViewController(
- view,
- progressProvider.getOrNull(),
- centralSurfaces,
- shadeController,
- shadeLogger,
- unfoldComponent.getOrNull()?.getStatusBarMoveFromCenterAnimationController(),
- userChipViewModel,
- viewUtil,
- configurationController
+ ): PhoneStatusBarViewController {
+ val statusBarMoveFromCenterAnimationController =
+ if (featureFlags.isEnabled(Flags.ENABLE_UNFOLD_STATUS_BAR_ANIMATIONS)) {
+ unfoldComponent.getOrNull()?.getStatusBarMoveFromCenterAnimationController()
+ } else {
+ null
+ }
+
+ return PhoneStatusBarViewController(
+ view,
+ progressProvider.getOrNull(),
+ centralSurfaces,
+ shadeController,
+ shadeLogger,
+ statusBarMoveFromCenterAnimationController,
+ userChipViewModel,
+ viewUtil,
+ configurationController
)
+ }
}
}
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 0bded73..46603df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimController.java
@@ -809,6 +809,11 @@
public void setOccludeAnimationPlaying(boolean occludeAnimationPlaying) {
mOccludeAnimationPlaying = occludeAnimationPlaying;
+
+ for (ScrimState state : ScrimState.values()) {
+ state.setOccludeAnimationPlaying(occludeAnimationPlaying);
+ }
+
applyAndDispatchState();
}
@@ -853,7 +858,6 @@
if (mState == ScrimState.UNLOCKED || mState == ScrimState.DREAMING) {
final boolean occluding =
mOccludeAnimationPlaying || mState.mLaunchingAffordanceWithPreview;
-
// Darken scrim as it's pulled down while unlocked. If we're unlocked but playing the
// screen off/occlusion animations, ignore expansion changes while those animations
// play.
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 0e9d3ce..7b20283 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ScrimState.java
@@ -243,7 +243,12 @@
: CentralSurfaces.FADE_KEYGUARD_DURATION;
boolean fromAod = previousState == AOD || previousState == PULSING;
- mAnimateChange = !mLaunchingAffordanceWithPreview && !fromAod;
+ // If launch/occlude animations were playing, they already animated the scrim
+ // alpha to 0f as part of the animation. If we animate it now, we'll set it back
+ // to 1f and animate it back to 0f, causing an unwanted scrim flash.
+ mAnimateChange = !mLaunchingAffordanceWithPreview
+ && !mOccludeAnimationPlaying
+ && !fromAod;
mFrontTint = Color.TRANSPARENT;
mBehindTint = Color.BLACK;
@@ -308,6 +313,7 @@
boolean mWallpaperSupportsAmbientMode;
boolean mHasBackdrop;
boolean mLaunchingAffordanceWithPreview;
+ boolean mOccludeAnimationPlaying;
boolean mWakeLockScreenSensorActive;
boolean mKeyguardFadingAway;
long mKeyguardFadingAwayDuration;
@@ -411,6 +417,10 @@
mLaunchingAffordanceWithPreview = launchingAffordanceWithPreview;
}
+ public void setOccludeAnimationPlaying(boolean occludeAnimationPlaying) {
+ mOccludeAnimationPlaying = occludeAnimationPlaying;
+ }
+
public boolean isLowPowerState() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
index 04cc8ce..30d2295 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconController.java
@@ -81,28 +81,22 @@
void refreshIconGroup(IconManager iconManager);
/**
- * Adds or updates an icon for a given slot for a **tile service icon**.
+ * Adds or updates an icon that comes from an active tile service.
*
- * TODO(b/265307726): Merge with {@link #setIcon(String, StatusBarIcon)} or make this method
- * much more clearly distinct from that method.
+ * If the icon is null, the icon will be removed.
*/
- void setExternalIcon(String slot);
+ void setIconFromTile(String slot, @Nullable StatusBarIcon icon);
+
+ /** Removes an icon that had come from an active tile service. */
+ void removeIconForTile(String slot);
/**
* Adds or updates an icon for the given slot for **internal system icons**.
*
- * TODO(b/265307726): Rename to `setInternalIcon`, or merge this appropriately with the
- * {@link #setIcon(String, StatusBarIcon)} method.
+ * TODO(b/265307726): Re-name this to `setInternalIcon`.
*/
void setIcon(String slot, int resourceId, CharSequence contentDescription);
- /**
- * Adds or updates an icon for the given slot for an **externally-provided icon**.
- *
- * TODO(b/265307726): Rename to `setExternalIcon` or something similar.
- */
- void setIcon(String slot, StatusBarIcon icon);
-
/** */
void setWifiIcon(String slot, WifiIconState state);
@@ -152,15 +146,10 @@
*/
void removeIcon(String slot, int tag);
- /** */
- void removeAllIconsForSlot(String slot);
-
/**
- * Removes all the icons for the given slot.
- *
- * Only use this for icons that have come from **an external process**.
+ * TODO(b/265307726): Re-name this to `removeAllIconsForInternalSlot`.
*/
- void removeAllIconsForExternalSlot(String slot);
+ void removeAllIconsForSlot(String slot);
// TODO: See if we can rename this tunable name.
String ICON_HIDE_LIST = "icon_blacklist";
@@ -618,13 +607,6 @@
mGroup.removeAllViews();
}
- protected void onIconExternal(int viewIndex, int height) {
- ImageView imageView = (ImageView) mGroup.getChildAt(viewIndex);
- imageView.setScaleType(ImageView.ScaleType.FIT_CENTER);
- imageView.setAdjustViewBounds(true);
- setHeightAndCenter(imageView, height);
- }
-
protected void onDensityOrFontScaleChanged() {
for (int i = 0; i < mGroup.getChildCount(); i++) {
View child = mGroup.getChildAt(i);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
index 0727c5a..3a18423 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImpl.java
@@ -32,7 +32,6 @@
import com.android.internal.statusbar.StatusBarIcon;
import com.android.systemui.Dumpable;
-import com.android.systemui.R;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.demomode.DemoMode;
import com.android.systemui.demomode.DemoModeController;
@@ -62,7 +61,7 @@
*/
@SysUISingleton
public class StatusBarIconControllerImpl implements Tunable,
- ConfigurationListener, Dumpable, CommandQueue.Callbacks, StatusBarIconController, DemoMode {
+ ConfigurationListener, Dumpable, StatusBarIconController, DemoMode {
private static final String TAG = "StatusBarIconController";
// Use this suffix to prevent external icon slot names from unintentionally overriding our
@@ -93,7 +92,7 @@
mStatusBarPipelineFlags = statusBarPipelineFlags;
configurationController.addCallback(this);
- commandQueue.addCallback(this);
+ commandQueue.addCallback(mCommandQueueCallbacks);
tunerService.addTunable(this, ICON_HIDE_LIST);
demoModeController.addCallback(this);
dumpManager.registerDumpable(getClass().getSimpleName(), this);
@@ -350,26 +349,35 @@
}
}
- @Override
- public void setExternalIcon(String slot) {
- String slotName = createExternalSlotName(slot);
- int viewIndex = mStatusBarIconList.getViewIndex(slotName, 0);
- int height = mContext.getResources().getDimensionPixelSize(
- R.dimen.status_bar_icon_drawing_size);
- mIconGroups.forEach(l -> l.onIconExternal(viewIndex, height));
- }
-
- // Override for *both* CommandQueue.Callbacks AND StatusBarIconController.
- // TODO(b/265307726): Pull out the CommandQueue callbacks into a member variable to
- // differentiate between those callback methods and StatusBarIconController methods.
- @Override
- public void setIcon(String slot, StatusBarIcon icon) {
- String slotName = createExternalSlotName(slot);
- if (icon == null) {
- removeAllIconsForSlot(slotName);
- return;
+ private final CommandQueue.Callbacks mCommandQueueCallbacks = new CommandQueue.Callbacks() {
+ @Override
+ public void setIcon(String slot, StatusBarIcon icon) {
+ // Icons that come from CommandQueue are from external services.
+ setExternalIcon(slot, icon);
}
+ @Override
+ public void removeIcon(String slot) {
+ removeAllIconsForExternalSlot(slot);
+ }
+ };
+
+ @Override
+ public void setIconFromTile(String slot, StatusBarIcon icon) {
+ setExternalIcon(slot, icon);
+ }
+
+ @Override
+ public void removeIconForTile(String slot) {
+ removeAllIconsForExternalSlot(slot);
+ }
+
+ private void setExternalIcon(String slot, StatusBarIcon icon) {
+ if (icon == null) {
+ removeAllIconsForExternalSlot(slot);
+ return;
+ }
+ String slotName = createExternalSlotName(slot);
StatusBarIconHolder holder = StatusBarIconHolder.fromIcon(icon);
setIcon(slotName, holder);
}
@@ -417,14 +425,6 @@
}
}
- // CommandQueue.Callbacks override
- // TODO(b/265307726): Pull out the CommandQueue callbacks into a member variable to
- // differentiate between those callback methods and StatusBarIconController methods.
- @Override
- public void removeIcon(String slot) {
- removeAllIconsForExternalSlot(slot);
- }
-
/** */
@Override
public void removeIcon(String slot, int tag) {
@@ -444,8 +444,7 @@
mIconGroups.forEach(l -> l.onRemoveIcon(viewIndex));
}
- @Override
- public void removeAllIconsForExternalSlot(String slotName) {
+ private void removeAllIconsForExternalSlot(String slotName) {
removeAllIconsForSlot(createExternalSlotName(slotName));
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
index 69b683b..f06b5db 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManager.java
@@ -54,6 +54,7 @@
import com.android.keyguard.KeyguardUpdateMonitorCallback;
import com.android.keyguard.KeyguardViewController;
import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
import com.android.systemui.dagger.SysUISingleton;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dreams.DreamOverlayStateController;
@@ -282,6 +283,8 @@
final Set<KeyguardViewManagerCallback> mCallbacks = new HashSet<>();
private boolean mIsModernAlternateBouncerEnabled;
private boolean mIsBackAnimationEnabled;
+ private final boolean mUdfpsNewTouchDetectionEnabled;
+ private final UdfpsOverlayInteractor mUdfpsOverlayInteractor;
private OnDismissAction mAfterKeyguardGoneAction;
private Runnable mKeyguardGoneCancelAction;
@@ -336,7 +339,9 @@
PrimaryBouncerCallbackInteractor primaryBouncerCallbackInteractor,
PrimaryBouncerInteractor primaryBouncerInteractor,
BouncerView primaryBouncerView,
- AlternateBouncerInteractor alternateBouncerInteractor) {
+ AlternateBouncerInteractor alternateBouncerInteractor,
+ UdfpsOverlayInteractor udfpsOverlayInteractor
+ ) {
mContext = context;
mViewMediatorCallback = callback;
mLockPatternUtils = lockPatternUtils;
@@ -362,6 +367,8 @@
mAlternateBouncerInteractor = alternateBouncerInteractor;
mIsBackAnimationEnabled =
featureFlags.isEnabled(Flags.WM_ENABLE_PREDICTIVE_BACK_BOUNCER_ANIM);
+ mUdfpsNewTouchDetectionEnabled = featureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION);
+ mUdfpsOverlayInteractor = udfpsOverlayInteractor;
}
@Override
@@ -374,7 +381,6 @@
mCentralSurfaces = centralSurfaces;
mBiometricUnlockController = biometricUnlockController;
- ViewGroup container = mCentralSurfaces.getBouncerContainer();
mPrimaryBouncerCallbackInteractor.addBouncerExpansionCallback(mExpansionCallback);
mNotificationPanelViewController = notificationPanelViewController;
if (shadeExpansionStateManager != null) {
@@ -1443,16 +1449,48 @@
}
/**
+ * An opportunity for the AlternateBouncer to handle the touch instead of sending
+ * the touch to NPVC child views.
+ * @return true if the alternate bouncer should consime the touch and prevent it from
+ * going to its child views
+ */
+ public boolean dispatchTouchEvent(MotionEvent event) {
+ if (shouldInterceptTouchEvent(event)
+ && !mUdfpsOverlayInteractor.isTouchWithinUdfpsArea(event)) {
+ onTouch(event);
+ }
+ return shouldInterceptTouchEvent(event);
+ }
+
+ /**
+ * Whether the touch should be intercepted by the AlternateBouncer before going to the
+ * notification shade's child views.
+ */
+ public boolean shouldInterceptTouchEvent(MotionEvent event) {
+ return mAlternateBouncerInteractor.isVisibleState();
+ }
+
+ /**
* For any touches on the NPVC, show the primary bouncer if the alternate bouncer is currently
* showing.
*/
public boolean onTouch(MotionEvent event) {
- boolean handledTouch = false;
- if (event.getAction() == MotionEvent.ACTION_UP
- && mAlternateBouncerInteractor.isVisibleState()
- && mAlternateBouncerInteractor.hasAlternateBouncerShownWithMinTime()) {
- showPrimaryBouncer(true);
- handledTouch = true;
+ boolean handleTouch = shouldInterceptTouchEvent(event);
+ if (handleTouch) {
+ final boolean actionDown = event.getActionMasked() == MotionEvent.ACTION_DOWN;
+ final boolean actionDownThenUp = mAlternateBouncerInteractor.getReceivedDownTouch()
+ && event.getActionMasked() == MotionEvent.ACTION_UP;
+ final boolean udfpsOverlayWillForwardEventsOutsideNotificationShade =
+ mUdfpsNewTouchDetectionEnabled && mKeyguardUpdateManager.isUdfpsEnrolled();
+ final boolean actionOutsideShouldDismissAlternateBouncer =
+ event.getActionMasked() == MotionEvent.ACTION_OUTSIDE
+ && !udfpsOverlayWillForwardEventsOutsideNotificationShade;
+ if (actionDown) {
+ mAlternateBouncerInteractor.setReceivedDownTouch(true);
+ } else if ((actionDownThenUp || actionOutsideShouldDismissAlternateBouncer)
+ && mAlternateBouncerInteractor.hasAlternateBouncerShownWithMinTime()) {
+ showPrimaryBouncer(true);
+ }
}
// Forward NPVC touches to callbacks in case they want to respond to touches
@@ -1460,7 +1498,7 @@
callback.onTouch(event);
}
- return handledTouch;
+ return handleTouch;
}
/** Update keyguard position based on a tapped X coordinate. */
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
index ed978c3..24ddded 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragment.java
@@ -453,9 +453,6 @@
protected int adjustDisableFlags(int state) {
boolean headsUpVisible =
mStatusBarFragmentComponent.getHeadsUpAppearanceController().shouldBeVisible();
- if (headsUpVisible) {
- state |= DISABLE_CLOCK;
- }
if (!mKeyguardStateController.isLaunchTransitionFadingAway()
&& !mKeyguardStateController.isKeyguardFadingAway()
@@ -473,6 +470,13 @@
state |= DISABLE_ONGOING_CALL_CHIP;
}
+ if (headsUpVisible) {
+ // Disable everything on the left side of the status bar, since the app name for the
+ // heads up notification appears there instead.
+ state |= DISABLE_CLOCK;
+ state |= DISABLE_ONGOING_CALL_CHIP;
+ }
+
return state;
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
index 4156fc1..73bf188 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/MobileInputLogger.kt
@@ -179,6 +179,10 @@
fun logDefaultMobileIconGroup(group: SignalIcon.MobileIconGroup) {
buffer.log(TAG, LogLevel.INFO, { str1 = group.name }, { "defaultMobileIconGroup: $str1" })
}
+
+ fun logOnSubscriptionsChanged() {
+ buffer.log(TAG, LogLevel.INFO, {}, { "onSubscriptionsChanged" })
+ }
}
private const val TAG = "MobileInputLog"
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
index f866d65..d0c6215 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryImpl.kt
@@ -105,10 +105,14 @@
* The reason we need to do this is because TelephonyManager limits the number of registered
* listeners per-process, so we don't want to create a new listener for every callback.
*
- * A note on the design for back pressure here: We use the [coalesce] operator here to change
- * the backpressure strategy to store exactly the last callback event of _each type_ here, as
- * opposed to the default strategy which is to drop the oldest event (regardless of type). This
- * means that we should never miss any single event as long as the flow has been started.
+ * A note on the design for back pressure here: We don't control _which_ telephony callback
+ * comes in first, since we register every relevant bit of information as a batch. E.g., if a
+ * downstream starts collecting on a field which is backed by
+ * [TelephonyCallback.ServiceStateListener], it's not possible for us to guarantee that _that_
+ * callback comes in -- the first callback could very well be
+ * [TelephonyCallback.DataActivityListener], which would promptly be dropped if we didn't keep
+ * it tracked. We use the [scan] operator here to track the most recent callback of _each type_
+ * here. See [TelephonyCallbackState] to see how the callbacks are stored.
*/
private val callbackEvents: StateFlow<TelephonyCallbackState> = run {
val initial = TelephonyCallbackState()
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
index b7da3f2..991b786 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionsRepositoryImpl.kt
@@ -129,6 +129,7 @@
val callback =
object : SubscriptionManager.OnSubscriptionsChangedListener() {
override fun onSubscriptionsChanged() {
+ logger.logOnSubscriptionsChanged()
trySend(Unit)
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
index 805368c..f1269f2 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyguardStateControllerImpl.java
@@ -398,6 +398,7 @@
pw.println(" mFaceAuthEnabled: " + mFaceAuthEnabled);
pw.println(" isKeyguardFadingAway: " + isKeyguardFadingAway());
pw.println(" isKeyguardGoingAway: " + isKeyguardGoingAway());
+ pw.println(" isLaunchTransitionFadingAway: " + isLaunchTransitionFadingAway());
}
private class UpdateMonitorCallback extends KeyguardUpdateMonitorCallback {
diff --git a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
index 9952cfd..3805019 100644
--- a/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
+++ b/packages/SystemUI/src/com/android/systemui/stylus/StylusManager.kt
@@ -261,22 +261,26 @@
private fun trackAndLogUsiSession(deviceId: Int, batteryStateValid: Boolean) {
// TODO(b/268618918) handle cases where an invalid battery callback from a previous stylus
// is sent after the actual valid callback
+ val hasBtConnection = if (inputDeviceBtSessionIdMap.isEmpty()) 0 else 1
+
if (batteryStateValid && usiSessionId == null) {
logDebug { "USI battery newly present, entering new USI session: $deviceId" }
usiSessionId = instanceIdSequence.newInstanceId()
- uiEventLogger.logWithInstanceId(
+ uiEventLogger.logWithInstanceIdAndPosition(
StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_FIRST_DETECTED,
0,
null,
- usiSessionId
+ usiSessionId,
+ hasBtConnection,
)
} else if (!batteryStateValid && usiSessionId != null) {
logDebug { "USI battery newly absent, exiting USI session: $deviceId" }
- uiEventLogger.logWithInstanceId(
+ uiEventLogger.logWithInstanceIdAndPosition(
StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_REMOVED,
0,
null,
- usiSessionId
+ usiSessionId,
+ hasBtConnection,
)
usiSessionId = null
}
diff --git a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
index 125cc76..6e58f22 100644
--- a/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
+++ b/packages/SystemUI/src/com/android/systemui/temporarydisplay/chipbar/ChipbarInfo.kt
@@ -18,7 +18,8 @@
import android.os.VibrationEffect
import android.view.View
-import androidx.annotation.AttrRes
+import androidx.annotation.ColorRes
+import com.android.systemui.R
import com.android.systemui.common.shared.model.Text
import com.android.systemui.common.shared.model.TintedIcon
import com.android.systemui.temporarydisplay.TemporaryViewInfo
@@ -48,7 +49,7 @@
override val priority: ViewPriority,
) : TemporaryViewInfo() {
companion object {
- @AttrRes const val DEFAULT_ICON_TINT_ATTR = android.R.attr.textColorPrimary
+ @ColorRes val DEFAULT_ICON_TINT = R.color.chipbar_text_and_icon_color
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
index 6ef828f..9d8c4a5 100644
--- a/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
+++ b/packages/SystemUI/src/com/android/systemui/unfold/UnfoldLightRevealOverlayAnimation.kt
@@ -87,6 +87,7 @@
private var isFolded: Boolean = false
private var isUnfoldHandled: Boolean = true
private var overlayAddReason: AddOverlayReason? = null
+ private var isTouchBlocked: Boolean = true
private var currentRotation: Int = context.display!!.rotation
@@ -254,7 +255,15 @@
params.layoutInDisplayCutoutMode =
WindowManager.LayoutParams.LAYOUT_IN_DISPLAY_CUTOUT_MODE_ALWAYS
params.fitInsetsTypes = 0
- params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
+
+ val touchFlags =
+ if (isTouchBlocked) {
+ // Touchable by default, so it will block the touches
+ 0
+ } else {
+ WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE
+ }
+ params.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE or touchFlags
params.setTrustedOverlay()
val packageName: String = context.opPackageName
@@ -263,6 +272,24 @@
return params
}
+ private fun updateTouchBlockIfNeeded(progress: Float) {
+ // When unfolding unblock touches a bit earlier than the animation end as the
+ // interpolation has a long tail of very slight movement at the end which should not
+ // affect much the usage of the device
+ val shouldBlockTouches =
+ if (overlayAddReason == UNFOLD) {
+ progress < UNFOLD_BLOCK_TOUCHES_UNTIL_PROGRESS
+ } else {
+ true
+ }
+
+ if (isTouchBlocked != shouldBlockTouches) {
+ isTouchBlocked = shouldBlockTouches
+
+ traceSection("$TAG#relayoutToUpdateTouch") { root?.relayout(getLayoutParams()) }
+ }
+ }
+
private fun createLightRevealEffect(): LightRevealEffect {
val isVerticalFold =
currentRotation == Surface.ROTATION_0 || currentRotation == Surface.ROTATION_180
@@ -289,7 +316,10 @@
private inner class TransitionListener : TransitionProgressListener {
override fun onTransitionProgress(progress: Float) {
- executeInBackground { scrimView?.revealAmount = calculateRevealAmount(progress) }
+ executeInBackground {
+ scrimView?.revealAmount = calculateRevealAmount(progress)
+ updateTouchBlockIfNeeded(progress)
+ }
}
override fun onTransitionFinished() {
@@ -361,5 +391,7 @@
// constants for revealAmount.
const val TRANSPARENT = 1f
const val BLACK = 0f
+
+ private const val UNFOLD_BLOCK_TOUCHES_UNTIL_PROGRESS = 0.8f
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
index a0a0372..209ea41 100644
--- a/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/leak/GarbageMonitor.java
@@ -59,6 +59,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.MessageRouter;
@@ -412,6 +413,7 @@
private final GarbageMonitor gm;
private ProcessMemInfo pmi;
private boolean dumpInProgress;
+ private final PanelInteractor mPanelInteractor;
@Inject
public MemoryTile(
@@ -423,11 +425,13 @@
StatusBarStateController statusBarStateController,
ActivityStarter activityStarter,
QSLogger qsLogger,
- GarbageMonitor monitor
+ GarbageMonitor monitor,
+ PanelInteractor panelInteractor
) {
super(host, backgroundLooper, mainHandler, falsingManager, metricsLogger,
statusBarStateController, activityStarter, qsLogger);
gm = monitor;
+ mPanelInteractor = panelInteractor;
}
@Override
@@ -457,7 +461,7 @@
mHandler.post(() -> {
dumpInProgress = false;
refreshState();
- getHost().collapsePanels();
+ mPanelInteractor.collapsePanels();
mActivityStarter.postStartActivityDismissingKeyguard(shareIntent, 0);
});
}
diff --git a/packages/SystemUI/src/com/android/systemui/util/sensors/PostureDependentProximitySensor.java b/packages/SystemUI/src/com/android/systemui/util/sensors/PostureDependentProximitySensor.java
index 460b7d9..a5828c7 100644
--- a/packages/SystemUI/src/com/android/systemui/util/sensors/PostureDependentProximitySensor.java
+++ b/packages/SystemUI/src/com/android/systemui/util/sensors/PostureDependentProximitySensor.java
@@ -23,6 +23,8 @@
import com.android.systemui.util.concurrency.DelayableExecutor;
import com.android.systemui.util.concurrency.Execution;
+import java.util.HashSet;
+
import javax.inject.Inject;
/**
@@ -37,6 +39,7 @@
private final ThresholdSensor[] mPostureToPrimaryProxSensorMap;
private final ThresholdSensor[] mPostureToSecondaryProxSensorMap;
+ private final HashSet<Listener> mListenersRegisteredWhenProxUnavailable = new HashSet<>();
private final DevicePostureController mDevicePostureController;
@Inject
@@ -69,6 +72,25 @@
mDevicePostureController.removeCallback(mDevicePostureCallback);
}
+ @Override
+ public void register(ThresholdSensor.Listener listener) {
+ if (!isLoaded()) {
+ logDebug("No prox sensor when registering listener=" + listener);
+ mListenersRegisteredWhenProxUnavailable.add(listener);
+ }
+
+ super.register(listener);
+ }
+
+ @Override
+ public void unregister(ThresholdSensor.Listener listener) {
+ if (mListenersRegisteredWhenProxUnavailable.remove(listener)) {
+ logDebug("Removing listener from mListenersRegisteredWhenProxUnavailable "
+ + listener);
+ }
+ super.unregister(listener);
+ }
+
private void chooseSensors() {
if (mDevicePosture >= mPostureToPrimaryProxSensorMap.length
|| mDevicePosture >= mPostureToSecondaryProxSensorMap.length) {
@@ -98,6 +120,14 @@
mInitializedListeners = false;
registerInternal();
+
+ final Listener[] listenersToReregister =
+ mListenersRegisteredWhenProxUnavailable.toArray(new Listener[0]);
+ mListenersRegisteredWhenProxUnavailable.clear();
+ for (Listener listener : listenersToReregister) {
+ logDebug("Re-register listener " + listener);
+ register(listener);
+ }
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
index a062e7b..492f231 100644
--- a/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
+++ b/packages/SystemUI/src/com/android/systemui/wallet/ui/WalletScreenController.java
@@ -77,8 +77,11 @@
private final FalsingManager mFalsingManager;
private final UiEventLogger mUiEventLogger;
- @VisibleForTesting String mSelectedCardId;
- @VisibleForTesting boolean mIsDismissed;
+
+ @VisibleForTesting
+ String mSelectedCardId;
+ @VisibleForTesting
+ boolean mIsDismissed;
public WalletScreenController(
Context context,
@@ -124,9 +127,20 @@
}
Log.i(TAG, "Successfully retrieved wallet cards.");
List<WalletCard> walletCards = response.getWalletCards();
- List<WalletCardViewInfo> data = new ArrayList<>(walletCards.size());
+
+ boolean allUnknown = true;
for (WalletCard card : walletCards) {
- data.add(new QAWalletCardViewInfo(mContext, card));
+ if (card.getCardType() != WalletCard.CARD_TYPE_UNKNOWN) {
+ allUnknown = false;
+ break;
+ }
+ }
+
+ List<WalletCardViewInfo> paymentCardData = new ArrayList<>();
+ for (WalletCard card : walletCards) {
+ if (allUnknown || card.getCardType() == WalletCard.CARD_TYPE_PAYMENT) {
+ paymentCardData.add(new QAWalletCardViewInfo(mContext, card));
+ }
}
// Get on main thread for UI updates.
@@ -134,18 +148,18 @@
if (mIsDismissed) {
return;
}
- if (data.isEmpty()) {
+ if (paymentCardData.isEmpty()) {
showEmptyStateView();
} else {
int selectedIndex = response.getSelectedIndex();
- if (selectedIndex >= data.size()) {
+ if (selectedIndex >= paymentCardData.size()) {
Log.w(TAG, "Invalid selected card index, showing empty state.");
showEmptyStateView();
} else {
boolean isUdfpsEnabled = mKeyguardUpdateMonitor.isUdfpsEnrolled()
&& mKeyguardUpdateMonitor.isFingerprintDetectionRunning();
mWalletView.showCardCarousel(
- data,
+ paymentCardData,
selectedIndex,
!mKeyguardStateController.isUnlocked(),
isUdfpsEnabled);
@@ -213,7 +227,6 @@
}
-
@Override
public void onCardClicked(@NonNull WalletCardViewInfo cardInfo) {
if (mFalsingManager.isFalseTap(FalsingManager.LOW_PENALTY)) {
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
index a5f90f8..b15ac39 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardClockSwitchControllerTest.java
@@ -17,6 +17,7 @@
package com.android.keyguard;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.eq;
@@ -365,6 +366,12 @@
assertEquals(View.VISIBLE, mFakeWeatherView.getVisibility());
}
+ @Test
+ public void testGetClockAnimations_nullClock_returnsNull() {
+ when(mClockEventController.getClock()).thenReturn(null);
+ assertNull(mController.getClockAnimations());
+ }
+
private void verifyAttachment(VerificationMode times) {
verify(mClockRegistry, times).registerClockChangeListener(
any(ClockRegistry.ClockChangeListener.class));
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
index f966eb3..b73330f 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSecurityContainerControllerTest.java
@@ -196,6 +196,7 @@
.thenReturn(mKeyguardMessageAreaController);
when(mKeyguardPasswordView.getWindowInsetsController()).thenReturn(mWindowInsetsController);
when(mKeyguardSecurityModel.getSecurityMode(anyInt())).thenReturn(SecurityMode.PIN);
+ when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
mKeyguardPasswordViewController = new KeyguardPasswordViewController(
(KeyguardPasswordView) mKeyguardPasswordView, mKeyguardUpdateMonitor,
SecurityMode.Password, mLockPatternUtils, null,
@@ -554,6 +555,22 @@
}
@Test
+ public void testSecurityCallbackFinish() {
+ when(mKeyguardStateController.canDismissLockScreen()).thenReturn(true);
+ when(mKeyguardUpdateMonitor.isUserUnlocked(0)).thenReturn(true);
+ mKeyguardSecurityContainerController.finish(true, 0);
+ verify(mViewMediatorCallback).keyguardDone(anyBoolean(), anyInt());
+ }
+
+ @Test
+ public void testSecurityCallbackFinish_cannotDismissLockScreenAndNotStrongAuth() {
+ when(mFeatureFlags.isEnabled(Flags.PREVENT_BYPASS_KEYGUARD)).thenReturn(true);
+ when(mKeyguardStateController.canDismissLockScreen()).thenReturn(false);
+ mKeyguardSecurityContainerController.finish(false, 0);
+ verify(mViewMediatorCallback, never()).keyguardDone(anyBoolean(), anyInt());
+ }
+
+ @Test
public void testOnStartingToHide() {
mKeyguardSecurityContainerController.onStartingToHide();
verify(mInputViewController).onStartingToHide();
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
new file mode 100644
index 0000000..eb86c05
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPinViewControllerTest.kt
@@ -0,0 +1,131 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.telephony.PinResult
+import android.telephony.TelephonyManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import androidx.test.filters.SmallTest
+import com.android.internal.util.LatencyTracker
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.util.mockito.any
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.anyInt
+import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
+import org.mockito.Mockito.`when`
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class KeyguardSimPinViewControllerTest : SysuiTestCase() {
+ private lateinit var simPinView: KeyguardSimPinView
+ private lateinit var underTest: KeyguardSimPinViewController
+ @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+ @Mock private lateinit var securityMode: KeyguardSecurityModel.SecurityMode
+ @Mock private lateinit var lockPatternUtils: LockPatternUtils
+ @Mock private lateinit var keyguardSecurityCallback: KeyguardSecurityCallback
+ @Mock private lateinit var messageAreaControllerFactory: KeyguardMessageAreaController.Factory
+ @Mock private lateinit var latencyTracker: LatencyTracker
+ @Mock private lateinit var liftToActivateListener: LiftToActivateListener
+ @Mock private lateinit var telephonyManager: TelephonyManager
+ @Mock private lateinit var falsingCollector: FalsingCollector
+ @Mock private lateinit var emergencyButtonController: EmergencyButtonController
+ @Mock
+ private lateinit var keyguardMessageAreaController:
+ KeyguardMessageAreaController<BouncerKeyguardMessageArea>
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ `when`(messageAreaControllerFactory.create(Mockito.any(KeyguardMessageArea::class.java)))
+ .thenReturn(keyguardMessageAreaController)
+ `when`(telephonyManager.createForSubscriptionId(anyInt())).thenReturn(telephonyManager)
+ `when`(telephonyManager.supplyIccLockPin(anyString()))
+ .thenReturn(mock(PinResult::class.java))
+ simPinView =
+ LayoutInflater.from(context).inflate(R.layout.keyguard_sim_pin_view, null)
+ as KeyguardSimPinView
+ underTest =
+ KeyguardSimPinViewController(
+ simPinView,
+ keyguardUpdateMonitor,
+ securityMode,
+ lockPatternUtils,
+ keyguardSecurityCallback,
+ messageAreaControllerFactory,
+ latencyTracker,
+ liftToActivateListener,
+ telephonyManager,
+ falsingCollector,
+ emergencyButtonController
+ )
+ underTest.init()
+ }
+
+ @Test
+ fun onViewAttached() {
+ underTest.onViewAttached()
+ }
+
+ @Test
+ fun onViewDetached() {
+ underTest.onViewDetached()
+ }
+
+ @Test
+ fun onResume() {
+ underTest.onResume(KeyguardSecurityView.VIEW_REVEALED)
+ verify(keyguardUpdateMonitor)
+ .registerCallback(any(KeyguardUpdateMonitorCallback::class.java))
+ }
+
+ @Test
+ fun onPause() {
+ underTest.onPause()
+ verify(keyguardUpdateMonitor).removeCallback(any(KeyguardUpdateMonitorCallback::class.java))
+ }
+
+ @Test
+ fun startAppearAnimation() {
+ underTest.startAppearAnimation()
+ verify(keyguardMessageAreaController)
+ .setMessage(context.resources.getString(R.string.keyguard_enter_your_pin), false)
+ }
+
+ @Test
+ fun startDisappearAnimation() {
+ underTest.startDisappearAnimation {}
+ }
+
+ @Test
+ fun resetState() {
+ underTest.resetState()
+ verify(keyguardMessageAreaController).setMessage("")
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
new file mode 100644
index 0000000..2dcca55
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardSimPukViewControllerTest.kt
@@ -0,0 +1,132 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.keyguard
+
+import android.telephony.PinResult
+import android.telephony.TelephonyManager
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper
+import android.view.LayoutInflater
+import androidx.test.filters.SmallTest
+import com.android.internal.util.LatencyTracker
+import com.android.internal.widget.LockPatternUtils
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingCollector
+import com.android.systemui.util.mockito.any
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentMatchers.anyString
+import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+@TestableLooper.RunWithLooper
+class KeyguardSimPukViewControllerTest : SysuiTestCase() {
+ private lateinit var simPukView: KeyguardSimPukView
+ private lateinit var underTest: KeyguardSimPukViewController
+ @Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
+ @Mock private lateinit var securityMode: KeyguardSecurityModel.SecurityMode
+ @Mock private lateinit var lockPatternUtils: LockPatternUtils
+ @Mock private lateinit var keyguardSecurityCallback: KeyguardSecurityCallback
+ @Mock private lateinit var messageAreaControllerFactory: KeyguardMessageAreaController.Factory
+ @Mock private lateinit var latencyTracker: LatencyTracker
+ @Mock private lateinit var liftToActivateListener: LiftToActivateListener
+ @Mock private lateinit var telephonyManager: TelephonyManager
+ @Mock private lateinit var falsingCollector: FalsingCollector
+ @Mock private lateinit var emergencyButtonController: EmergencyButtonController
+ @Mock
+ private lateinit var keyguardMessageAreaController:
+ KeyguardMessageAreaController<BouncerKeyguardMessageArea>
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ Mockito.`when`(
+ messageAreaControllerFactory.create(Mockito.any(KeyguardMessageArea::class.java))
+ )
+ .thenReturn(keyguardMessageAreaController)
+ Mockito.`when`(telephonyManager.createForSubscriptionId(Mockito.anyInt()))
+ .thenReturn(telephonyManager)
+ Mockito.`when`(telephonyManager.supplyIccLockPuk(anyString(), anyString()))
+ .thenReturn(Mockito.mock(PinResult::class.java))
+ simPukView =
+ LayoutInflater.from(context).inflate(R.layout.keyguard_sim_puk_view, null)
+ as KeyguardSimPukView
+ underTest =
+ KeyguardSimPukViewController(
+ simPukView,
+ keyguardUpdateMonitor,
+ securityMode,
+ lockPatternUtils,
+ keyguardSecurityCallback,
+ messageAreaControllerFactory,
+ latencyTracker,
+ liftToActivateListener,
+ telephonyManager,
+ falsingCollector,
+ emergencyButtonController
+ )
+ underTest.init()
+ }
+
+ @Test
+ fun onViewAttached() {
+ underTest.onViewAttached()
+ Mockito.verify(keyguardUpdateMonitor)
+ .registerCallback(any(KeyguardUpdateMonitorCallback::class.java))
+ }
+
+ @Test
+ fun onViewDetached() {
+ underTest.onViewDetached()
+ Mockito.verify(keyguardUpdateMonitor)
+ .removeCallback(any(KeyguardUpdateMonitorCallback::class.java))
+ }
+
+ @Test
+ fun onResume() {
+ underTest.onResume(KeyguardSecurityView.VIEW_REVEALED)
+ }
+
+ @Test
+ fun onPause() {
+ underTest.onPause()
+ }
+
+ @Test
+ fun startAppearAnimation() {
+ underTest.startAppearAnimation()
+ Mockito.verify(keyguardMessageAreaController)
+ .setMessage(context.resources.getString(R.string.keyguard_enter_your_pin), false)
+ }
+
+ @Test
+ fun startDisappearAnimation() {
+ underTest.startDisappearAnimation {}
+ }
+
+ @Test
+ fun resetState() {
+ underTest.resetState()
+ Mockito.verify(keyguardMessageAreaController)
+ .setMessage(context.resources.getString(R.string.kg_puk_enter_puk_hint))
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
index 86ba30c..fb21db7 100644
--- a/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
+++ b/packages/SystemUI/tests/src/com/android/keyguard/KeyguardUpdateMonitorTest.java
@@ -2256,6 +2256,26 @@
}
@Test
+ public void assistantVisible_requestActiveUnlock() {
+ // GIVEN active unlock requests from the assistant are allowed
+ when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.ASSISTANT)).thenReturn(true);
+
+ // GIVEN should trigger active unlock
+ keyguardIsVisible();
+ keyguardNotGoingAway();
+ statusBarShadeIsNotLocked();
+ when(mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())).thenReturn(true);
+
+ // WHEN the assistant is visible
+ mKeyguardUpdateMonitor.setAssistantVisible(true);
+
+ // THEN request unlock with keyguard dismissal
+ verify(mTrustManager).reportUserRequestedUnlock(eq(KeyguardUpdateMonitor.getCurrentUser()),
+ eq(true));
+ }
+
+ @Test
public void fingerprintFailure_requestActiveUnlock_dismissKeyguard()
throws RemoteException {
// GIVEN shouldTriggerActiveUnlock
@@ -2489,6 +2509,57 @@
}
@Test
+ public void unfoldFromPostureChange_requestActiveUnlock_forceDismissKeyguard()
+ throws RemoteException {
+ // GIVEN shouldTriggerActiveUnlock
+ keyguardIsVisible();
+ when(mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())).thenReturn(true);
+
+ // GIVEN active unlock triggers on wakeup
+ when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE))
+ .thenReturn(true);
+
+ // GIVEN an unfold should force dismiss the keyguard
+ when(mActiveUnlockConfig.shouldWakeupForceDismissKeyguard(
+ PowerManager.WAKE_REASON_UNFOLD_DEVICE)).thenReturn(true);
+
+ // WHEN device posture changes to unfold
+ deviceInPostureStateOpened();
+ mTestableLooper.processAllMessages();
+
+ // THEN request unlock with a keyguard dismissal
+ verify(mTrustManager).reportUserRequestedUnlock(eq(KeyguardUpdateMonitor.getCurrentUser()),
+ eq(true));
+ }
+
+
+ @Test
+ public void unfoldFromPostureChange_requestActiveUnlock_noDismissKeyguard()
+ throws RemoteException {
+ // GIVEN shouldTriggerActiveUnlock on wake from UNFOLD_DEVICE
+ keyguardIsVisible();
+ when(mLockPatternUtils.isSecure(KeyguardUpdateMonitor.getCurrentUser())).thenReturn(true);
+
+ // GIVEN active unlock triggers on wakeup
+ when(mActiveUnlockConfig.shouldAllowActiveUnlockFromOrigin(
+ ActiveUnlockConfig.ActiveUnlockRequestOrigin.WAKE))
+ .thenReturn(true);
+
+ // GIVEN an unfold should NOT force dismiss the keyguard
+ when(mActiveUnlockConfig.shouldWakeupForceDismissKeyguard(
+ PowerManager.WAKE_REASON_UNFOLD_DEVICE)).thenReturn(false);
+
+ // WHEN device posture changes to unfold
+ deviceInPostureStateOpened();
+ mTestableLooper.processAllMessages();
+
+ // THEN request unlock WITHOUT a keyguard dismissal
+ verify(mTrustManager).reportUserRequestedUnlock(eq(KeyguardUpdateMonitor.getCurrentUser()),
+ eq(false));
+ }
+
+ @Test
public void detectFingerprint_onTemporaryLockoutReset_authenticateFingerprint() {
ArgumentCaptor<FingerprintManager.LockoutResetCallback> fpLockoutResetCallbackCaptor =
ArgumentCaptor.forClass(FingerprintManager.LockoutResetCallback.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
index ca6f426..eb82956 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/accessibility/fontscaling/FontScalingDialogTest.kt
@@ -25,12 +25,19 @@
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
import com.android.systemui.common.ui.view.SeekBarWithIconButtonsView
+import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.settings.FakeSettings
+import com.android.systemui.util.settings.SecureSettings
import com.android.systemui.util.settings.SystemSettings
+import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.MockitoAnnotations
+
+private const val ON: Int = 1
+private const val OFF: Int = 0
/** Tests for [FontScalingDialog]. */
@SmallTest
@@ -39,6 +46,8 @@
class FontScalingDialogTest : SysuiTestCase() {
private lateinit var fontScalingDialog: FontScalingDialog
private lateinit var systemSettings: SystemSettings
+ private lateinit var secureSettings: SecureSettings
+ private lateinit var backgroundExecutor: FakeExecutor
private val fontSizeValueArray: Array<String> =
mContext
.getResources()
@@ -46,9 +55,13 @@
@Before
fun setUp() {
+ MockitoAnnotations.initMocks(this)
val mainHandler = Handler(TestableLooper.get(this).getLooper())
systemSettings = FakeSettings()
- fontScalingDialog = FontScalingDialog(mContext, systemSettings as FakeSettings)
+ secureSettings = FakeSettings()
+ backgroundExecutor = FakeExecutor(FakeSystemClock())
+ fontScalingDialog =
+ FontScalingDialog(mContext, systemSettings, secureSettings, backgroundExecutor)
}
@Test
@@ -76,6 +89,7 @@
seekBarWithIconButtonsView.setProgress(0)
iconEndFrame.performClick()
+ backgroundExecutor.runAllReady()
val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f)
assertThat(seekBar.getProgress()).isEqualTo(1)
@@ -96,6 +110,7 @@
seekBarWithIconButtonsView.setProgress(fontSizeValueArray.size - 1)
iconStartFrame.performClick()
+ backgroundExecutor.runAllReady()
val currentScale = systemSettings.getFloat(Settings.System.FONT_SCALE, /* def = */ 1.0f)
assertThat(seekBar.getProgress()).isEqualTo(fontSizeValueArray.size - 2)
@@ -104,4 +119,26 @@
fontScalingDialog.dismiss()
}
+
+ @Test
+ fun progressChanged_keyWasNotSetBefore_fontScalingHasBeenChangedIsOn() {
+ fontScalingDialog.show()
+
+ val seekBarWithIconButtonsView: SeekBarWithIconButtonsView =
+ fontScalingDialog.findViewById(R.id.font_scaling_slider)!!
+ secureSettings.putInt(Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED, OFF)
+
+ // Default seekbar progress for font size is 1, set it to another progress 0
+ seekBarWithIconButtonsView.setProgress(0)
+ backgroundExecutor.runAllReady()
+
+ val currentSettings =
+ secureSettings.getInt(
+ Settings.Secure.ACCESSIBILITY_FONT_SCALING_HAS_BEEN_CHANGED,
+ /* def = */ OFF
+ )
+ assertThat(currentSettings).isEqualTo(ON)
+
+ fontScalingDialog.dismiss()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
index 0574838..bce98cf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/AuthBiometricFingerprintViewTest.kt
@@ -15,49 +15,27 @@
*/
package com.android.systemui.biometrics
-import android.content.Context
import android.hardware.biometrics.BiometricAuthenticator
-import android.hardware.biometrics.SensorLocationInternal
-import android.hardware.biometrics.SensorProperties
-import android.hardware.display.DisplayManagerGlobal
-import android.hardware.fingerprint.FingerprintManager
-import android.hardware.fingerprint.FingerprintSensorProperties
-import android.hardware.fingerprint.FingerprintSensorPropertiesInternal
import android.os.Bundle
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.testing.TestableLooper.RunWithLooper
-import android.view.Display
-import android.view.DisplayAdjustments
-import android.view.DisplayInfo
-import android.view.Surface
import android.view.View
-import android.view.ViewGroup
import androidx.test.filters.SmallTest
-import com.airbnb.lottie.LottieAnimationView
import com.android.systemui.R
-import com.android.systemui.biometrics.AuthBiometricView.STATE_AUTHENTICATING_ANIMATING_IN
import com.android.systemui.SysuiTestCase
-import com.android.systemui.SysuiTestableContext
import com.google.common.truth.Truth.assertThat
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.ArgumentMatchers.eq
import org.mockito.Mock
-import org.mockito.Mockito.mock
import org.mockito.Mockito.never
-import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnit
-import org.mockito.Mockito.`when` as whenEver
-
-private const val DISPLAY_ID = 2
-private const val SENSOR_ID = 1
@RunWith(AndroidTestingRunner::class)
@RunWithLooper(setAsMainLooper = true)
@@ -72,22 +50,9 @@
private lateinit var callback: AuthBiometricView.Callback
@Mock
- private lateinit var fingerprintManager: FingerprintManager
-
- @Mock
- private lateinit var iconView: LottieAnimationView
-
- @Mock
- private lateinit var iconViewOverlay: LottieAnimationView
-
- @Mock
- private lateinit var iconLayoutParamSize: Pair<Int, Int>
-
- @Mock
private lateinit var panelController: AuthPanelController
private lateinit var biometricView: AuthBiometricView
- private lateinit var iconController: AuthBiometricFingerprintIconController
private fun createView(allowDeviceCredential: Boolean = false): AuthBiometricFingerprintView {
val view: AuthBiometricFingerprintView =
@@ -312,186 +277,5 @@
verify(callback).onAction(AuthBiometricView.Callback.ACTION_USE_DEVICE_CREDENTIAL)
}
- private fun testWithSfpsDisplay(
- isReverseDefaultRotation: Boolean = false,
- inRearDisplayMode: Boolean = false,
- isFolded: Boolean = false,
- initInfo: DisplayInfo.() -> Unit = {},
- block: () -> Unit
- ) {
- val displayInfo = DisplayInfo()
- displayInfo.initInfo()
-
- val dmGlobal = mock(DisplayManagerGlobal::class.java)
- val display = Display(dmGlobal, DISPLAY_ID, displayInfo,
- DisplayAdjustments.DEFAULT_DISPLAY_ADJUSTMENTS)
-
- whenEver(dmGlobal.getDisplayInfo(eq(DISPLAY_ID))).thenReturn(displayInfo)
-
- val iconControllerContext = context.createDisplayContext(display) as SysuiTestableContext
- iconControllerContext.orCreateTestableResources.addOverride(
- com.android.internal.R.bool.config_reverseDefaultRotation,
- isReverseDefaultRotation
- )
-
- val rearDisplayDeviceStates = if (inRearDisplayMode) intArrayOf(3) else intArrayOf()
- iconControllerContext.orCreateTestableResources.addOverride(
- com.android.internal.R.array.config_rearDisplayDeviceStates,
- rearDisplayDeviceStates
- )
-
- val layoutParams = mock(ViewGroup.LayoutParams::class.java)
- whenEver(iconView.layoutParams).thenReturn(layoutParams)
- whenEver(iconViewOverlay.layoutParams).thenReturn(layoutParams)
-
- var locations = listOf(SensorLocationInternal("", 2500, 0, 0))
- whenEver(fingerprintManager.sensorPropertiesInternal)
- .thenReturn(
- listOf(
- FingerprintSensorPropertiesInternal(
- SENSOR_ID,
- SensorProperties.STRENGTH_STRONG,
- 5 /* maxEnrollmentsPerUser */,
- listOf() /* componentInfo */,
- FingerprintSensorProperties.TYPE_POWER_BUTTON,
- true /* halControlsIllumination */,
- true /* resetLockoutRequiresHardwareAuthToken */,
- locations
- )
- )
- )
- iconControllerContext.addMockSystemService(Context.FINGERPRINT_SERVICE, fingerprintManager)
-
- iconController = AuthBiometricFingerprintIconController(
- iconControllerContext,
- iconView,
- iconViewOverlay
- )
- iconController.onFoldUpdated(isFolded)
-
- biometricView.mIconController = iconController
- block()
- }
-
- @Test
- fun sfpsRearDisplay_showsCorrectAnimationAssetsAcrossRotations() {
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = true,
- isFolded = false,
- { rotation = Surface.ROTATION_0 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = true,
- isFolded = false,
- { rotation = Surface.ROTATION_90 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = true,
- isFolded = false,
- { rotation = Surface.ROTATION_180 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = true,
- isFolded = false,
- { rotation = Surface.ROTATION_270 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
- val expectedLottieAssetOrder: List<Int> = listOf(
- R.raw.biometricprompt_rear_landscape_base,
- R.raw.biometricprompt_rear_portrait_reverse_base,
- R.raw.biometricprompt_rear_landscape_base,
- R.raw.biometricprompt_rear_portrait_base,
- )
-
- val lottieAssetCaptor: ArgumentCaptor<Int> = ArgumentCaptor.forClass(Int::class.java)
- verify(iconView, times(4)).setAnimation(lottieAssetCaptor.capture())
- val observedLottieAssetOrder: List<Int> = lottieAssetCaptor.getAllValues()
- assertThat(observedLottieAssetOrder).containsExactlyElementsIn(expectedLottieAssetOrder)
- .inOrder()
- }
-
- @Test
- fun sfpsDefaultDisplayFolded_showsAnimationsAssetsCorrectlyAcrossRotations() {
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = false,
- isFolded = true,
- { rotation = Surface.ROTATION_0 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = false,
- isFolded = true,
- { rotation = Surface.ROTATION_90 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN); }
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = false,
- isFolded = true,
- { rotation = Surface.ROTATION_180 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN); }
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = false,
- isFolded = true,
- { rotation = Surface.ROTATION_270 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN); }
- val expectedLottieAssetOrder: List<Int> = listOf(
- R.raw.biometricprompt_folded_base_default,
- R.raw.biometricprompt_folded_base_topleft,
- R.raw.biometricprompt_folded_base_default,
- R.raw.biometricprompt_folded_base_bottomright,
- )
-
- val lottieAssetCaptor: ArgumentCaptor<Int> = ArgumentCaptor.forClass(Int::class.java)
- verify(iconView, times(4)).setAnimation(lottieAssetCaptor.capture())
- val observedLottieAssetOrder: List<Int> = lottieAssetCaptor.getAllValues()
- assertThat(observedLottieAssetOrder).containsExactlyElementsIn(expectedLottieAssetOrder)
- .inOrder()
- }
-
- @Test
- fun sfpsDefaultDisplayUnfolded_showsAnimationsAssetsCorrectlyAcrossRotations() {
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = false,
- isFolded = false,
- { rotation = Surface.ROTATION_0 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = false,
- isFolded = false,
- { rotation = Surface.ROTATION_90 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = false,
- isFolded = false,
- { rotation = Surface.ROTATION_180 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
- testWithSfpsDisplay(
- isReverseDefaultRotation = false,
- inRearDisplayMode = false,
- isFolded = false,
- { rotation = Surface.ROTATION_270 }
- ) { biometricView.updateState(STATE_AUTHENTICATING_ANIMATING_IN) }
- val expectedLottieAssetOrder: List<Int> = listOf(
- R.raw.biometricprompt_landscape_base,
- R.raw.biometricprompt_portrait_base_topleft,
- R.raw.biometricprompt_landscape_base,
- R.raw.biometricprompt_portrait_base_bottomright,
- )
-
- val lottieAssetCaptor: ArgumentCaptor<Int> = ArgumentCaptor.forClass(Int::class.java)
- verify(iconView, times(4)).setAnimation(lottieAssetCaptor.capture())
- val observedLottieAssetOrder: List<Int> = lottieAssetCaptor.getAllValues()
- assertThat(observedLottieAssetOrder).containsExactlyElementsIn(expectedLottieAssetOrder)
- .inOrder()
- }
-
override fun waitForIdleSync() = TestableLooper.get(this).processAllMessages()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
index 3ec49b2..0ab675c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/SideFpsControllerTest.kt
@@ -62,6 +62,7 @@
import com.android.systemui.keyguard.data.repository.FakeDeviceEntryFingerprintAuthRepository
import com.android.systemui.keyguard.data.repository.FakeKeyguardBouncerRepository
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
+import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.recents.OverviewProxyService
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.concurrency.FakeExecutor
@@ -98,7 +99,6 @@
@JvmField @Rule var rule = MockitoJUnit.rule()
- @Mock lateinit var keyguardStateController: KeyguardStateController
@Mock lateinit var layoutInflater: LayoutInflater
@Mock lateinit var fingerprintManager: FingerprintManager
@Mock lateinit var windowManager: WindowManager
@@ -138,7 +138,8 @@
keyguardBouncerRepository = FakeKeyguardBouncerRepository()
alternateBouncerInteractor =
AlternateBouncerInteractor(
- keyguardStateController,
+ mock(StatusBarStateController::class.java),
+ mock(KeyguardStateController::class.java),
keyguardBouncerRepository,
FakeBiometricSettingsRepository(),
FakeDeviceEntryFingerprintAuthRepository(),
@@ -172,7 +173,6 @@
isReverseDefaultRotation: Boolean = false,
initInfo: DisplayInfo.() -> Unit = {},
windowInsets: WindowInsets = insetsForSmallNavbar(),
- inRearDisplayMode: Boolean = false,
block: () -> Unit
) {
this.deviceConfig = deviceConfig
@@ -233,12 +233,6 @@
isReverseDefaultRotation
)
- val rearDisplayDeviceStates = if (inRearDisplayMode) intArrayOf(3) else intArrayOf()
- sideFpsControllerContext.orCreateTestableResources.addOverride(
- com.android.internal.R.array.config_rearDisplayDeviceStates,
- rearDisplayDeviceStates
- )
-
sideFpsController =
SideFpsController(
sideFpsControllerContext,
@@ -596,62 +590,10 @@
verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible = true)
}
- @Test
- fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_0() =
- testWithDisplay(
- deviceConfig = DeviceConfig.Y_ALIGNED,
- isReverseDefaultRotation = false,
- { rotation = Surface.ROTATION_0 },
- inRearDisplayMode = true,
- ) {
- verifySfpsIndicator_notAdded_InRearDisplayMode()
- }
-
- @Test
- fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_90() =
- testWithDisplay(
- deviceConfig = DeviceConfig.Y_ALIGNED,
- isReverseDefaultRotation = false,
- { rotation = Surface.ROTATION_90 },
- inRearDisplayMode = true,
- ) {
- verifySfpsIndicator_notAdded_InRearDisplayMode()
- }
-
- @Test
- fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_180() =
- testWithDisplay(
- deviceConfig = DeviceConfig.Y_ALIGNED,
- isReverseDefaultRotation = false,
- { rotation = Surface.ROTATION_180 },
- inRearDisplayMode = true,
- ) {
- verifySfpsIndicator_notAdded_InRearDisplayMode()
- }
-
- @Test
- fun verifiesSfpsIndicatorNotAddedInRearDisplayMode_270() =
- testWithDisplay(
- deviceConfig = DeviceConfig.Y_ALIGNED,
- isReverseDefaultRotation = false,
- { rotation = Surface.ROTATION_270 },
- inRearDisplayMode = true,
- ) {
- verifySfpsIndicator_notAdded_InRearDisplayMode()
- }
-
private fun verifySfpsIndicatorVisibilityOnTaskbarUpdate(sfpsViewVisible: Boolean) {
sideFpsController.overlayOffsets = sensorLocation
}
- private fun verifySfpsIndicator_notAdded_InRearDisplayMode() {
- sideFpsController.overlayOffsets = sensorLocation
- overlayController.show(SENSOR_ID, REASON_UNKNOWN)
- executor.runAllReady()
-
- verify(windowManager, never()).addView(any(), any())
- }
-
fun alternateBouncerVisibility_showAndHideSideFpsUI() = testWithDisplay {
// WHEN alternate bouncer is visible
keyguardBouncerRepository.setAlternateVisible(true)
@@ -688,7 +630,7 @@
* in other rotations have been omitted.
*/
@Test
- fun verifiesIndicatorPlacementForXAlignedSensor_0() =
+ fun verifiesIndicatorPlacementForXAlignedSensor_0() {
testWithDisplay(
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = false,
@@ -705,6 +647,7 @@
assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
}
+ }
/**
* {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_270
@@ -713,7 +656,7 @@
* correctly, tests for indicator placement in other rotations have been omitted.
*/
@Test
- fun verifiesIndicatorPlacementForXAlignedSensor_InReverseDefaultRotation_270() =
+ fun verifiesIndicatorPlacementForXAlignedSensor_InReverseDefaultRotation_270() {
testWithDisplay(
deviceConfig = DeviceConfig.X_ALIGNED,
isReverseDefaultRotation = true,
@@ -730,6 +673,7 @@
assertThat(overlayViewParamsCaptor.value.x).isEqualTo(sensorLocation.sensorLocationX)
assertThat(overlayViewParamsCaptor.value.y).isEqualTo(0)
}
+ }
/**
* {@link SideFpsController#updateOverlayParams} calculates indicator placement for ROTATION_0,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
index 9a73898..445cc87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsControllerTest.java
@@ -53,6 +53,7 @@
import android.hardware.fingerprint.FingerprintSensorPropertiesInternal;
import android.hardware.fingerprint.IUdfpsOverlayController;
import android.hardware.fingerprint.IUdfpsOverlayControllerCallback;
+import android.hardware.input.InputManager;
import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
@@ -63,6 +64,7 @@
import android.view.MotionEvent;
import android.view.Surface;
import android.view.View;
+import android.view.ViewRootImpl;
import android.view.WindowManager;
import android.view.accessibility.AccessibilityManager;
@@ -231,6 +233,10 @@
private FingerprintSensorPropertiesInternal mOpticalProps;
private FingerprintSensorPropertiesInternal mUltrasonicProps;
private UdfpsUtils mUdfpsUtils;
+ @Mock
+ private InputManager mInputManager;
+ @Mock
+ private ViewRootImpl mViewRootImpl;
@Before
public void setUp() {
@@ -248,6 +254,7 @@
when(mKeyguardUpdateMonitor.isFingerprintDetectionRunning()).thenReturn(true);
when(mSessionTracker.getSessionId(anyInt())).thenReturn(
(new InstanceIdSequence(1 << 20)).newInstanceId());
+ when(mUdfpsView.getViewRootImpl()).thenReturn(mViewRootImpl);
final List<ComponentInfoInternal> componentInfo = new ArrayList<>();
componentInfo.add(new ComponentInfoInternal("faceSensor" /* componentId */,
@@ -304,7 +311,7 @@
mUnlockedScreenOffAnimationController, mSystemUIDialogManager, mLatencyTracker,
mActivityLaunchAnimator, alternateTouchProvider, mBiometricExecutor,
mPrimaryBouncerInteractor, mSinglePointerTouchProcessor, mSessionTracker,
- mAlternateBouncerInteractor, mSecureSettings, mUdfpsUtils);
+ mAlternateBouncerInteractor, mSecureSettings, mInputManager, mUdfpsUtils);
verify(mFingerprintManager).setUdfpsOverlayController(mOverlayCaptor.capture());
mOverlayController = mOverlayCaptor.getValue();
verify(mScreenLifecycle).addObserver(mScreenObserverCaptor.capture());
@@ -1262,6 +1269,81 @@
}
@Test
+ public void onTouch_withNewTouchDetection_pilferPointer() throws RemoteException {
+ final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,
+ 0L);
+ final TouchProcessorResult processorResultDown = new TouchProcessorResult.ProcessedTouch(
+ InteractionEvent.DOWN, 1 /* pointerId */, touchData);
+
+ // Enable new touch detection.
+ when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true);
+
+ // Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider.
+ initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */);
+
+ // Configure UdfpsView to accept the ACTION_DOWN event
+ when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
+ when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(true);
+
+ // GIVEN that the overlay is showing and a11y touch exploration NOT enabled
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+ mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
+ BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+
+ verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+
+ // WHEN ACTION_DOWN is received
+ when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
+ processorResultDown);
+ MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
+ mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
+ mBiometricExecutor.runAllReady();
+ downEvent.recycle();
+
+ // THEN the touch is pilfered, expected twice (valid overlap and touch on sensor)
+ verify(mInputManager, times(2)).pilferPointers(any());
+ }
+
+ @Test
+ public void onTouch_withNewTouchDetection_doNotPilferPointer() throws RemoteException {
+ final NormalizedTouchData touchData = new NormalizedTouchData(0, 0f, 0f, 0f, 0f, 0f, 0L,
+ 0L);
+ final TouchProcessorResult processorResultUnchanged =
+ new TouchProcessorResult.ProcessedTouch(InteractionEvent.UNCHANGED,
+ 1 /* pointerId */, touchData);
+
+ // Enable new touch detection.
+ when(mFeatureFlags.isEnabled(Flags.UDFPS_NEW_TOUCH_DETECTION)).thenReturn(true);
+
+ // Configure UdfpsController to use FingerprintManager as opposed to AlternateTouchProvider.
+ initUdfpsController(mOpticalProps, false /* hasAlternateTouchProvider */);
+
+ // Configure UdfpsView to not accept the ACTION_DOWN event
+ when(mUdfpsView.isDisplayConfigured()).thenReturn(false);
+ when(mUdfpsView.isWithinSensorArea(anyFloat(), anyFloat())).thenReturn(false);
+
+ // GIVEN that the overlay is showing and a11y touch exploration NOT enabled
+ when(mAccessibilityManager.isTouchExplorationEnabled()).thenReturn(false);
+ mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
+ BiometricOverlayConstants.REASON_AUTH_KEYGUARD, mUdfpsOverlayControllerCallback);
+ mFgExecutor.runAllReady();
+
+ verify(mUdfpsView).setOnTouchListener(mTouchListenerCaptor.capture());
+
+ // WHEN ACTION_DOWN is received and touch is not within sensor
+ when(mSinglePointerTouchProcessor.processTouch(any(), anyInt(), any())).thenReturn(
+ processorResultUnchanged);
+ MotionEvent downEvent = MotionEvent.obtain(0, 0, ACTION_DOWN, 0, 0, 0);
+ mTouchListenerCaptor.getValue().onTouch(mUdfpsView, downEvent);
+ mBiometricExecutor.runAllReady();
+ downEvent.recycle();
+
+ // THEN the touch is NOT pilfered
+ verify(mInputManager, times(0)).pilferPointers(any());
+ }
+
+ @Test
public void onAodInterrupt_onAcquiredGood_fingerNoLongerDown() throws RemoteException {
// GIVEN UDFPS overlay is showing
mOverlayController.showUdfpsOverlay(TEST_REQUEST_ID, mOpticalProps.sensorId,
@@ -1285,6 +1367,5 @@
// THEN is fingerDown should be FALSE
assertFalse(mUdfpsController.isFingerDown());
-
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
index 786cb01..cefa9b1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/UdfpsKeyguardViewControllerWithCoroutinesTest.kt
@@ -35,6 +35,7 @@
import com.android.systemui.keyguard.domain.interactor.PrimaryBouncerInteractor
import com.android.systemui.keyguard.shared.constants.KeyguardBouncerConstants
import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.StatusBarState
import com.android.systemui.statusbar.phone.KeyguardBypassController
import com.android.systemui.statusbar.policy.KeyguardStateController
@@ -93,6 +94,7 @@
)
mAlternateBouncerInteractor =
AlternateBouncerInteractor(
+ mock(StatusBarStateController::class.java),
mock(KeyguardStateController::class.java),
keyguardBouncerRepository,
mock(BiometricSettingsRepository::class.java),
diff --git a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
index 87d5ae6..9431d86 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/biometrics/domain/interactor/UdfpsOverlayInteractorTest.kt
@@ -77,16 +77,14 @@
runCurrent()
- // Then touch should not be intercepted
- val canInterceptTrue = underTest.canInterceptTouchInUdfpsBounds(downEv)
- assertThat(canInterceptTrue).isFalse()
+ // Then touch is within udfps area
+ assertThat(underTest.isTouchWithinUdfpsArea(downEv)).isTrue()
// When touch is outside of bounds
whenever(overlayBounds.contains(downEv.x.toInt(), downEv.y.toInt())).thenReturn(false)
- // Then touch should be intercepted
- val canInterceptFalse = underTest.canInterceptTouchInUdfpsBounds(downEv)
- assertThat(canInterceptFalse).isTrue()
+ // Then touch is not within udfps area
+ assertThat(underTest.isTouchWithinUdfpsArea(downEv)).isFalse()
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
index 3f61bf7..5b3e518 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/ControlsUiControllerImplTest.kt
@@ -201,6 +201,56 @@
}
@Test
+ fun testSingleAppHeaderIsNotClickable() {
+ mockLayoutInflater()
+ val packageName = "pkg"
+ `when`(authorizedPanelsRepository.getAuthorizedPanels()).thenReturn(setOf(packageName))
+ val panel = SelectedItem.PanelItem("App name", ComponentName(packageName, "cls"))
+ val serviceInfo = setUpPanel(panel)
+
+ underTest.show(parent, {}, context)
+
+ val captor = argumentCaptor<ControlsListingController.ControlsListingCallback>()
+
+ verify(controlsListingController).addCallback(capture(captor))
+
+ captor.value.onServicesUpdated(listOf(serviceInfo))
+ FakeExecutor.exhaustExecutors(uiExecutor, bgExecutor)
+
+ val header: View = parent.requireViewById(R.id.controls_header)
+ assertThat(header.isClickable).isFalse()
+ assertThat(header.hasOnClickListeners()).isFalse()
+ }
+
+ @Test
+ fun testMultipleAppHeaderIsClickable() {
+ mockLayoutInflater()
+ val packageName1 = "pkg"
+ val panel1 = SelectedItem.PanelItem("App name 1", ComponentName(packageName1, "cls"))
+ val serviceInfo1 = setUpPanel(panel1)
+
+ val packageName2 = "pkg"
+ val panel2 = SelectedItem.PanelItem("App name 2", ComponentName(packageName2, "cls"))
+ val serviceInfo2 = setUpPanel(panel2)
+
+ `when`(authorizedPanelsRepository.getAuthorizedPanels())
+ .thenReturn(setOf(packageName1, packageName2))
+
+ underTest.show(parent, {}, context)
+
+ val captor = argumentCaptor<ControlsListingController.ControlsListingCallback>()
+
+ verify(controlsListingController).addCallback(capture(captor))
+
+ captor.value.onServicesUpdated(listOf(serviceInfo1, serviceInfo2))
+ FakeExecutor.exhaustExecutors(uiExecutor, bgExecutor)
+
+ val header: View = parent.requireViewById(R.id.controls_header)
+ assertThat(header.isClickable).isTrue()
+ assertThat(header.hasOnClickListeners()).isTrue()
+ }
+
+ @Test
fun testPanelControllerStartActivityWithCorrectArguments() {
mockLayoutInflater()
val packageName = "pkg"
@@ -347,7 +397,7 @@
whenever(controlsController.removeFavorites(eq(componentName))).thenReturn(true)
val panel = SelectedItem.PanelItem("App name", componentName)
preferredPanelRepository.setSelectedComponent(
- SelectedComponentRepository.SelectedComponent(panel)
+ SelectedComponentRepository.SelectedComponent(panel)
)
underTest.show(parent, {}, context)
underTest.startRemovingApp(componentName, "Test App")
@@ -362,6 +412,26 @@
}
@Test
+ fun testCancelRemovingAppsDoesntRemoveFavorite() {
+ val componentName = ComponentName(context, "cls")
+ whenever(controlsController.removeFavorites(eq(componentName))).thenReturn(true)
+ val panel = SelectedItem.PanelItem("App name", componentName)
+ preferredPanelRepository.setSelectedComponent(
+ SelectedComponentRepository.SelectedComponent(panel)
+ )
+ underTest.show(parent, {}, context)
+ underTest.startRemovingApp(componentName, "Test App")
+
+ fakeDialogController.clickNeutral()
+
+ verify(controlsController, never()).removeFavorites(eq(componentName))
+ assertThat(underTest.getPreferredSelectedItem(emptyList())).isEqualTo(panel)
+ assertThat(preferredPanelRepository.shouldAddDefaultComponent()).isTrue()
+ assertThat(preferredPanelRepository.getSelectedComponent())
+ .isEqualTo(SelectedComponentRepository.SelectedComponent(panel))
+ }
+
+ @Test
fun testHideCancelsTheRemoveAppDialog() {
val componentName = ComponentName(context, "cls")
underTest.show(parent, {}, context)
@@ -372,10 +442,42 @@
verify(fakeDialogController.dialog).cancel()
}
+ @Test
+ fun testOnRotationWithPanelUpdateBoundsCalled() {
+ mockLayoutInflater()
+ val packageName = "pkg"
+ `when`(authorizedPanelsRepository.getAuthorizedPanels()).thenReturn(setOf(packageName))
+ val panel = SelectedItem.PanelItem("App name", ComponentName(packageName, "cls"))
+ val serviceInfo = setUpPanel(panel)
+
+ underTest.show(parent, {}, context)
+
+ val captor = argumentCaptor<ControlsListingController.ControlsListingCallback>()
+
+ verify(controlsListingController).addCallback(capture(captor))
+ captor.value.onServicesUpdated(listOf(serviceInfo))
+ FakeExecutor.exhaustExecutors(uiExecutor, bgExecutor)
+
+ val taskViewConsumerCaptor = argumentCaptor<Consumer<TaskView>>()
+ verify(taskViewFactory).create(eq(context), eq(uiExecutor), capture(taskViewConsumerCaptor))
+
+ val taskView: TaskView = mock {
+ `when`(this.post(any())).thenAnswer {
+ uiExecutor.execute(it.arguments[0] as Runnable)
+ true
+ }
+ }
+
+ taskViewConsumerCaptor.value.accept(taskView)
+
+ underTest.onOrientationChange()
+ verify(taskView).onLocationChanged()
+ }
+
private fun setUpPanel(panel: SelectedItem.PanelItem): ControlsServiceInfo {
val activity = ComponentName(context, "activity")
preferredPanelRepository.setSelectedComponent(
- SelectedComponentRepository.SelectedComponent(panel)
+ SelectedComponentRepository.SelectedComponent(panel)
)
return ControlsServiceInfo(panel.componentName, panel.appName, activity)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
index de04ef8..9df7992 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/controls/ui/PanelTaskViewControllerTest.kt
@@ -152,4 +152,12 @@
listenerCaptor.value.onTaskRemovalStarted(0)
verify(taskView).release()
}
+
+ @Test
+ fun testOnRefreshBounds() {
+ underTest.launchTaskView()
+
+ underTest.refreshBounds()
+ verify(taskView).onLocationChanged()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java
index 3312c43..aad49f9 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/complication/DreamHomeControlsComplicationTest.java
@@ -35,7 +35,6 @@
import androidx.test.filters.SmallTest;
import com.android.internal.logging.UiEventLogger;
-import com.android.systemui.R;
import com.android.systemui.SysuiTestCase;
import com.android.systemui.animation.view.LaunchableImageView;
import com.android.systemui.condition.SelfExecutingMonitor;
@@ -89,9 +88,6 @@
private ArgumentCaptor<ControlsListingController.ControlsListingCallback> mCallbackCaptor;
@Mock
- private View mView;
-
- @Mock
private LaunchableImageView mHomeControlsView;
@Mock
@@ -115,7 +111,6 @@
when(mControlsComponent.getControlsListingController()).thenReturn(
Optional.of(mControlsListingController));
when(mControlsComponent.getVisibility()).thenReturn(AVAILABLE);
- when(mView.findViewById(R.id.home_controls_chip)).thenReturn(mHomeControlsView);
mMonitor = SelfExecutingMonitor.createInstance();
}
@@ -223,7 +218,7 @@
public void testClick_logsUiEvent() {
final DreamHomeControlsComplication.DreamHomeControlsChipViewController viewController =
new DreamHomeControlsComplication.DreamHomeControlsChipViewController(
- mView,
+ mHomeControlsView,
mActivityStarter,
mContext,
mControlsComponent,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
index 19347c7..58eb7d4 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/dreams/conditions/DreamConditionTest.java
@@ -21,9 +21,11 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.clearInvocations;
+import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import android.app.DreamManager;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
@@ -50,6 +52,9 @@
@Mock
Condition.Callback mCallback;
+ @Mock
+ DreamManager mDreamManager;
+
@Before
public void setup() {
MockitoAnnotations.initMocks(this);
@@ -59,29 +64,39 @@
* Ensure a dreaming state immediately triggers the condition.
*/
@Test
- public void testInitialState() {
- final Intent intent = new Intent(Intent.ACTION_DREAMING_STARTED);
- when(mContext.registerReceiver(any(), any())).thenReturn(intent);
- final DreamCondition condition = new DreamCondition(mContext);
+ public void testInitialDreamingState() {
+ when(mDreamManager.isDreaming()).thenReturn(true);
+ final DreamCondition condition = new DreamCondition(mContext, mDreamManager);
condition.addCallback(mCallback);
- condition.start();
verify(mCallback).onConditionChanged(eq(condition));
assertThat(condition.isConditionMet()).isTrue();
}
/**
+ * Ensure a non-dreaming state does not trigger the condition.
+ */
+ @Test
+ public void testInitialNonDreamingState() {
+ when(mDreamManager.isDreaming()).thenReturn(false);
+ final DreamCondition condition = new DreamCondition(mContext, mDreamManager);
+ condition.addCallback(mCallback);
+
+ verify(mCallback, never()).onConditionChanged(eq(condition));
+ assertThat(condition.isConditionMet()).isFalse();
+ }
+
+ /**
* Ensure that changing dream state triggers condition.
*/
@Test
public void testChange() {
- final Intent intent = new Intent(Intent.ACTION_DREAMING_STARTED);
final ArgumentCaptor<BroadcastReceiver> receiverCaptor =
ArgumentCaptor.forClass(BroadcastReceiver.class);
- when(mContext.registerReceiver(receiverCaptor.capture(), any())).thenReturn(intent);
- final DreamCondition condition = new DreamCondition(mContext);
+ when(mDreamManager.isDreaming()).thenReturn(true);
+ final DreamCondition condition = new DreamCondition(mContext, mDreamManager);
condition.addCallback(mCallback);
- condition.start();
+ verify(mContext).registerReceiver(receiverCaptor.capture(), any());
clearInvocations(mCallback);
receiverCaptor.getValue().onReceive(mContext, new Intent(Intent.ACTION_DREAMING_STOPPED));
verify(mCallback).onConditionChanged(eq(condition));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
index 2bcd75b..18f7db1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsDebugTest.kt
@@ -37,6 +37,7 @@
import org.mockito.Mockito.anyBoolean
import org.mockito.Mockito.anyString
import org.mockito.Mockito.inOrder
+import org.mockito.Mockito.never
import org.mockito.Mockito.times
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyNoMoreInteractions
@@ -53,7 +54,7 @@
*/
@SmallTest
class FeatureFlagsDebugTest : SysuiTestCase() {
- private lateinit var mFeatureFlagsDebug: FeatureFlagsDebug
+ private lateinit var featureFlagsDebug: FeatureFlagsDebug
@Mock
private lateinit var flagManager: FlagManager
@@ -85,7 +86,7 @@
flagMap.put(Flags.TEAMFOOD.name, Flags.TEAMFOOD)
flagMap.put(teamfoodableFlagA.name, teamfoodableFlagA)
flagMap.put(teamfoodableFlagB.name, teamfoodableFlagB)
- mFeatureFlagsDebug = FeatureFlagsDebug(
+ featureFlagsDebug = FeatureFlagsDebug(
flagManager,
mockContext,
globalSettings,
@@ -95,7 +96,7 @@
flagMap,
restarter
)
- mFeatureFlagsDebug.init()
+ featureFlagsDebug.init()
verify(flagManager).onSettingsChangedAction = any()
broadcastReceiver = withArgCaptor {
verify(mockContext).registerReceiver(
@@ -116,7 +117,7 @@
whenever(flagManager.readFlagValue<Boolean>(eq("4"), any())).thenReturn(false)
assertThat(
- mFeatureFlagsDebug.isEnabled(
+ featureFlagsDebug.isEnabled(
ReleasedFlag(
2,
name = "2",
@@ -125,7 +126,7 @@
)
).isTrue()
assertThat(
- mFeatureFlagsDebug.isEnabled(
+ featureFlagsDebug.isEnabled(
UnreleasedFlag(
3,
name = "3",
@@ -134,7 +135,7 @@
)
).isTrue()
assertThat(
- mFeatureFlagsDebug.isEnabled(
+ featureFlagsDebug.isEnabled(
ReleasedFlag(
4,
name = "4",
@@ -143,7 +144,7 @@
)
).isFalse()
assertThat(
- mFeatureFlagsDebug.isEnabled(
+ featureFlagsDebug.isEnabled(
UnreleasedFlag(
5,
name = "5",
@@ -157,8 +158,8 @@
fun teamFoodFlag_False() {
whenever(flagManager.readFlagValue<Boolean>(
eq(Flags.TEAMFOOD.name), any())).thenReturn(false)
- assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse()
- assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isFalse()
+ assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
// Regular boolean flags should still test the same.
// Only our teamfoodableFlag should change.
@@ -169,8 +170,8 @@
fun teamFoodFlag_True() {
whenever(flagManager.readFlagValue<Boolean>(
eq(Flags.TEAMFOOD.name), any())).thenReturn(true)
- assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
- assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isTrue()
// Regular boolean flags should still test the same.
// Only our teamfoodableFlag should change.
@@ -185,8 +186,8 @@
.thenReturn(false)
whenever(flagManager.readFlagValue<Boolean>(
eq(Flags.TEAMFOOD.name), any())).thenReturn(true)
- assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
- assertThat(mFeatureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse()
+ assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagA)).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(teamfoodableFlagB)).isFalse()
// Regular boolean flags should still test the same.
// Only our teamfoodableFlag should change.
@@ -205,7 +206,7 @@
whenever(flagManager.readFlagValue<Boolean>(eq("5"), any())).thenReturn(false)
assertThat(
- mFeatureFlagsDebug.isEnabled(
+ featureFlagsDebug.isEnabled(
ResourceBooleanFlag(
1,
"1",
@@ -214,16 +215,16 @@
)
)
).isFalse()
- assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(2, "2", "test", 1002))).isTrue()
- assertThat(mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(3, "3", "test", 1003))).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(ResourceBooleanFlag(2, "2", "test", 1002))).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(ResourceBooleanFlag(3, "3", "test", 1003))).isTrue()
Assert.assertThrows(NameNotFoundException::class.java) {
- mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(4, "4", "test", 1004))
+ featureFlagsDebug.isEnabled(ResourceBooleanFlag(4, "4", "test", 1004))
}
// Test that resource is loaded (and validated) even when the setting is set.
// This prevents developers from not noticing when they reference an invalid resource.
Assert.assertThrows(NameNotFoundException::class.java) {
- mFeatureFlagsDebug.isEnabled(ResourceBooleanFlag(5, "5", "test", 1005))
+ featureFlagsDebug.isEnabled(ResourceBooleanFlag(5, "5", "test", 1005))
}
}
@@ -236,11 +237,11 @@
return@thenAnswer it.getArgument(1)
}
- assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a", "test"))).isFalse()
- assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b", "test"))).isTrue()
- assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", "test", true))).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(1, "a", "test"))).isFalse()
+ assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(2, "b", "test"))).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(3, "c", "test", true))).isTrue()
assertThat(
- mFeatureFlagsDebug.isEnabled(
+ featureFlagsDebug.isEnabled(
SysPropBooleanFlag(
4,
"d",
@@ -249,17 +250,17 @@
)
)
).isFalse()
- assertThat(mFeatureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).isFalse()
+ assertThat(featureFlagsDebug.isEnabled(SysPropBooleanFlag(5, "e", "test"))).isFalse()
}
@Test
fun readStringFlag() {
whenever(flagManager.readFlagValue<String>(eq("3"), any())).thenReturn("foo")
whenever(flagManager.readFlagValue<String>(eq("4"), any())).thenReturn("bar")
- assertThat(mFeatureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz")
- assertThat(mFeatureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz")
- assertThat(mFeatureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo")
- assertThat(mFeatureFlagsDebug.getString(StringFlag(4, "4", "test", "buz"))).isEqualTo("bar")
+ assertThat(featureFlagsDebug.getString(StringFlag(1, "1", "test", "biz"))).isEqualTo("biz")
+ assertThat(featureFlagsDebug.getString(StringFlag(2, "2", "test", "baz"))).isEqualTo("baz")
+ assertThat(featureFlagsDebug.getString(StringFlag(3, "3", "test", "buz"))).isEqualTo("foo")
+ assertThat(featureFlagsDebug.getString(StringFlag(4, "4", "test", "buz"))).isEqualTo("bar")
}
@Test
@@ -276,7 +277,7 @@
whenever(flagManager.readFlagValue<String>(eq("6"), any())).thenReturn("override6")
assertThat(
- mFeatureFlagsDebug.getString(
+ featureFlagsDebug.getString(
ResourceStringFlag(
1,
"1",
@@ -286,7 +287,7 @@
)
).isEqualTo("")
assertThat(
- mFeatureFlagsDebug.getString(
+ featureFlagsDebug.getString(
ResourceStringFlag(
2,
"2",
@@ -296,7 +297,7 @@
)
).isEqualTo("resource2")
assertThat(
- mFeatureFlagsDebug.getString(
+ featureFlagsDebug.getString(
ResourceStringFlag(
3,
"3",
@@ -307,15 +308,15 @@
).isEqualTo("override3")
Assert.assertThrows(NullPointerException::class.java) {
- mFeatureFlagsDebug.getString(ResourceStringFlag(4, "4", "test", 1004))
+ featureFlagsDebug.getString(ResourceStringFlag(4, "4", "test", 1004))
}
Assert.assertThrows(NameNotFoundException::class.java) {
- mFeatureFlagsDebug.getString(ResourceStringFlag(5, "5", "test", 1005))
+ featureFlagsDebug.getString(ResourceStringFlag(5, "5", "test", 1005))
}
// Test that resource is loaded (and validated) even when the setting is set.
// This prevents developers from not noticing when they reference an invalid resource.
Assert.assertThrows(NameNotFoundException::class.java) {
- mFeatureFlagsDebug.getString(ResourceStringFlag(6, "6", "test", 1005))
+ featureFlagsDebug.getString(ResourceStringFlag(6, "6", "test", 1005))
}
}
@@ -323,10 +324,10 @@
fun readIntFlag() {
whenever(flagManager.readFlagValue<Int>(eq("3"), any())).thenReturn(22)
whenever(flagManager.readFlagValue<Int>(eq("4"), any())).thenReturn(48)
- assertThat(mFeatureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12)
- assertThat(mFeatureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93)
- assertThat(mFeatureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22)
- assertThat(mFeatureFlagsDebug.getInt(IntFlag(4, "4", "test", 234))).isEqualTo(48)
+ assertThat(featureFlagsDebug.getInt(IntFlag(1, "1", "test", 12))).isEqualTo(12)
+ assertThat(featureFlagsDebug.getInt(IntFlag(2, "2", "test", 93))).isEqualTo(93)
+ assertThat(featureFlagsDebug.getInt(IntFlag(3, "3", "test", 8))).isEqualTo(22)
+ assertThat(featureFlagsDebug.getInt(IntFlag(4, "4", "test", 234))).isEqualTo(48)
}
@Test
@@ -342,17 +343,17 @@
whenever(flagManager.readFlagValue<Int>(eq(4), any())).thenReturn(500)
whenever(flagManager.readFlagValue<Int>(eq(5), any())).thenReturn(9519)
- assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(1, "1", "test", 1001))).isEqualTo(88)
- assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(2, "2", "test", 1002))).isEqualTo(61)
- assertThat(mFeatureFlagsDebug.getInt(ResourceIntFlag(3, "3", "test", 1003))).isEqualTo(20)
+ assertThat(featureFlagsDebug.getInt(ResourceIntFlag(1, "1", "test", 1001))).isEqualTo(88)
+ assertThat(featureFlagsDebug.getInt(ResourceIntFlag(2, "2", "test", 1002))).isEqualTo(61)
+ assertThat(featureFlagsDebug.getInt(ResourceIntFlag(3, "3", "test", 1003))).isEqualTo(20)
Assert.assertThrows(NotFoundException::class.java) {
- mFeatureFlagsDebug.getInt(ResourceIntFlag(4, "4", "test", 1004))
+ featureFlagsDebug.getInt(ResourceIntFlag(4, "4", "test", 1004))
}
// Test that resource is loaded (and validated) even when the setting is set.
// This prevents developers from not noticing when they reference an invalid resource.
Assert.assertThrows(NotFoundException::class.java) {
- mFeatureFlagsDebug.getInt(ResourceIntFlag(5, "5", "test", 1005))
+ featureFlagsDebug.getInt(ResourceIntFlag(5, "5", "test", 1005))
}
}
@@ -432,11 +433,11 @@
whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("original")
// gets the flag & cache it
- assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original")
+ assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("original")
verify(flagManager, times(1)).readFlagValue(eq("1"), eq(StringFlagSerializer))
// hit the cache
- assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("original")
+ assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("original")
verifyNoMoreInteractions(flagManager)
// set the flag
@@ -444,7 +445,7 @@
verifyPutData("1", "{\"type\":\"string\",\"value\":\"new\"}", numReads = 2)
whenever(flagManager.readFlagValue<String>(eq("1"), any())).thenReturn("new")
- assertThat(mFeatureFlagsDebug.getString(flag1)).isEqualTo("new")
+ assertThat(featureFlagsDebug.getString(flag1)).isEqualTo("new")
verify(flagManager, times(3)).readFlagValue(eq("1"), eq(StringFlagSerializer))
}
@@ -454,7 +455,7 @@
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
- assertThat(mFeatureFlagsDebug.isEnabled(flag)).isFalse()
+ assertThat(featureFlagsDebug.isEnabled(flag)).isFalse()
}
@Test
@@ -462,7 +463,33 @@
val flag = UnreleasedFlag(100, name = "100", namespace = "test")
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
- assertThat(mFeatureFlagsDebug.isEnabled(flag)).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(flag)).isTrue()
+ }
+
+ @Test
+ fun serverSide_OverrideUncached_NoRestart() {
+ // No one has read the flag, so it's not in the cache.
+ serverFlagReader.setFlagValue(
+ teamfoodableFlagA.namespace, teamfoodableFlagA.name, !teamfoodableFlagA.default)
+ verify(restarter, never()).restartSystemUI(anyString())
+ }
+
+ @Test
+ fun serverSide_Override_Restarts() {
+ // Read it to put it in the cache.
+ featureFlagsDebug.isEnabled(teamfoodableFlagA)
+ serverFlagReader.setFlagValue(
+ teamfoodableFlagA.namespace, teamfoodableFlagA.name, !teamfoodableFlagA.default)
+ verify(restarter).restartSystemUI(anyString())
+ }
+
+ @Test
+ fun serverSide_RedundantOverride_NoRestart() {
+ // Read it to put it in the cache.
+ featureFlagsDebug.isEnabled(teamfoodableFlagA)
+ serverFlagReader.setFlagValue(
+ teamfoodableFlagA.namespace, teamfoodableFlagA.name, teamfoodableFlagA.default)
+ verify(restarter, never()).restartSystemUI(anyString())
}
@Test
@@ -482,13 +509,13 @@
.thenReturn("override7")
// WHEN the flags have been accessed
- assertThat(mFeatureFlagsDebug.isEnabled(flag1)).isTrue()
- assertThat(mFeatureFlagsDebug.isEnabled(flag2)).isTrue()
- assertThat(mFeatureFlagsDebug.isEnabled(flag3)).isFalse()
- assertThat(mFeatureFlagsDebug.getString(flag4)).isEmpty()
- assertThat(mFeatureFlagsDebug.getString(flag5)).isEqualTo("flag5default")
- assertThat(mFeatureFlagsDebug.getString(flag6)).isEqualTo("resource1006")
- assertThat(mFeatureFlagsDebug.getString(flag7)).isEqualTo("override7")
+ assertThat(featureFlagsDebug.isEnabled(flag1)).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(flag2)).isTrue()
+ assertThat(featureFlagsDebug.isEnabled(flag3)).isFalse()
+ assertThat(featureFlagsDebug.getString(flag4)).isEmpty()
+ assertThat(featureFlagsDebug.getString(flag5)).isEqualTo("flag5default")
+ assertThat(featureFlagsDebug.getString(flag6)).isEqualTo("resource1006")
+ assertThat(featureFlagsDebug.getString(flag7)).isEqualTo("override7")
// THEN the dump contains the flags and the default values
val dump = dumpToString()
@@ -527,7 +554,7 @@
private fun dumpToString(): String {
val sw = StringWriter()
val pw = PrintWriter(sw)
- mFeatureFlagsDebug.dump(pw, emptyArray<String>())
+ featureFlagsDebug.dump(pw, emptyArray<String>())
pw.flush()
return sw.toString()
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
index 4c6028c..917147b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/FeatureFlagsReleaseTest.kt
@@ -24,6 +24,8 @@
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
+import org.mockito.Mockito
+import org.mockito.Mockito.never
import org.mockito.MockitoAnnotations
import org.mockito.Mockito.`when` as whenever
@@ -33,7 +35,7 @@
*/
@SmallTest
class FeatureFlagsReleaseTest : SysuiTestCase() {
- private lateinit var mFeatureFlagsRelease: FeatureFlagsRelease
+ private lateinit var featureFlagsRelease: FeatureFlagsRelease
@Mock private lateinit var mResources: Resources
@Mock private lateinit var mSystemProperties: SystemPropertiesHelper
@@ -41,15 +43,21 @@
private val flagMap = mutableMapOf<String, Flag<*>>()
private val serverFlagReader = ServerFlagReaderFake()
+
+ private val flagA = ReleasedFlag(501, name = "a", namespace = "test")
+
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
- mFeatureFlagsRelease = FeatureFlagsRelease(
+ flagMap.put(flagA.name, flagA)
+ featureFlagsRelease = FeatureFlagsRelease(
mResources,
mSystemProperties,
serverFlagReader,
flagMap,
restarter)
+
+ featureFlagsRelease.init()
}
@Test
@@ -60,7 +68,7 @@
val flagNamespace = "test"
val flag = ResourceBooleanFlag(flagId, flagName, flagNamespace, flagResourceId)
whenever(mResources.getBoolean(flagResourceId)).thenReturn(true)
- assertThat(mFeatureFlagsRelease.isEnabled(flag)).isTrue()
+ assertThat(featureFlagsRelease.isEnabled(flag)).isTrue()
}
@Test
@@ -70,16 +78,16 @@
whenever(mResources.getString(1003)).thenReturn(null)
whenever(mResources.getString(1004)).thenAnswer { throw NameNotFoundException() }
- assertThat(mFeatureFlagsRelease.getString(
+ assertThat(featureFlagsRelease.getString(
ResourceStringFlag(1, "1", "test", 1001))).isEqualTo("")
- assertThat(mFeatureFlagsRelease.getString(
+ assertThat(featureFlagsRelease.getString(
ResourceStringFlag(2, "2", "test", 1002))).isEqualTo("res2")
assertThrows(NullPointerException::class.java) {
- mFeatureFlagsRelease.getString(ResourceStringFlag(3, "3", "test", 1003))
+ featureFlagsRelease.getString(ResourceStringFlag(3, "3", "test", 1003))
}
assertThrows(NameNotFoundException::class.java) {
- mFeatureFlagsRelease.getString(ResourceStringFlag(4, "4", "test", 1004))
+ featureFlagsRelease.getString(ResourceStringFlag(4, "4", "test", 1004))
}
}
@@ -92,7 +100,7 @@
val flag = SysPropBooleanFlag(flagId, flagName, flagNamespace, flagDefault)
whenever(mSystemProperties.getBoolean(flagName, flagDefault)).thenReturn(flagDefault)
- assertThat(mFeatureFlagsRelease.isEnabled(flag)).isEqualTo(flagDefault)
+ assertThat(featureFlagsRelease.isEnabled(flag)).isEqualTo(flagDefault)
}
@Test
@@ -101,7 +109,7 @@
serverFlagReader.setFlagValue(flag.namespace, flag.name, false)
- assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
+ assertThat(featureFlagsRelease.isEnabled(flag)).isFalse()
}
@Test
@@ -110,6 +118,32 @@
serverFlagReader.setFlagValue(flag.namespace, flag.name, true)
- assertThat(mFeatureFlagsRelease.isEnabled(flag)).isFalse()
+ assertThat(featureFlagsRelease.isEnabled(flag)).isFalse()
+ }
+
+ @Test
+ fun serverSide_OverrideUncached_NoRestart() {
+ // No one has read the flag, so it's not in the cache.
+ serverFlagReader.setFlagValue(
+ flagA.namespace, flagA.name, !flagA.default)
+ Mockito.verify(restarter, never()).restartSystemUI(Mockito.anyString())
+ }
+
+ @Test
+ fun serverSide_Override_Restarts() {
+ // Read it to put it in the cache.
+ featureFlagsRelease.isEnabled(flagA)
+ serverFlagReader.setFlagValue(
+ flagA.namespace, flagA.name, !flagA.default)
+ Mockito.verify(restarter).restartSystemUI(Mockito.anyString())
+ }
+
+ @Test
+ fun serverSide_RedundantOverride_NoRestart() {
+ // Read it to put it in the cache.
+ featureFlagsRelease.isEnabled(flagA)
+ serverFlagReader.setFlagValue(
+ flagA.namespace, flagA.name, flagA.default)
+ Mockito.verify(restarter, never()).restartSystemUI(Mockito.anyString())
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
index de0e511..2db4596 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/RestartDozeListenerTest.kt
@@ -20,6 +20,7 @@
import android.test.suitebuilder.annotation.SmallTest
import com.android.systemui.SysuiTestCase
import com.android.systemui.plugins.statusbar.StatusBarStateController
+import com.android.systemui.util.concurrency.FakeExecutor
import com.android.systemui.util.settings.FakeSettings
import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
@@ -41,13 +42,14 @@
@Mock lateinit var statusBarStateController: StatusBarStateController
@Mock lateinit var powerManager: PowerManager
val clock = FakeSystemClock()
+ val executor = FakeExecutor(clock)
lateinit var listener: StatusBarStateController.StateListener
@Before
fun setup() {
MockitoAnnotations.initMocks(this)
restartDozeListener =
- RestartDozeListener(settings, statusBarStateController, powerManager, clock)
+ RestartDozeListener(settings, statusBarStateController, powerManager, clock, executor)
val captor = ArgumentCaptor.forClass(StatusBarStateController.StateListener::class.java)
restartDozeListener.init()
@@ -58,12 +60,14 @@
@Test
fun testStoreDreamState_onDreamingStarted() {
listener.onDreamingChanged(true)
+ executor.runAllReady()
assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isTrue()
}
@Test
fun testStoreDreamState_onDreamingStopped() {
listener.onDreamingChanged(false)
+ executor.runAllReady()
assertThat(settings.getBool(RestartDozeListener.RESTART_NAP_KEY)).isFalse()
}
@@ -71,6 +75,8 @@
fun testRestoreDreamState_dreamingShouldStart() {
settings.putBool(RestartDozeListener.RESTART_NAP_KEY, true)
restartDozeListener.maybeRestartSleep()
+ executor.advanceClockToLast()
+ executor.runAllReady()
verify(powerManager).wakeUp(clock.uptimeMillis())
verify(powerManager).goToSleep(clock.uptimeMillis())
}
@@ -79,6 +85,8 @@
fun testRestoreDreamState_dreamingShouldNot() {
settings.putBool(RestartDozeListener.RESTART_NAP_KEY, false)
restartDozeListener.maybeRestartSleep()
+ executor.advanceClockToLast()
+ executor.runAllReady()
verify(powerManager, never()).wakeUp(anyLong())
verify(powerManager, never()).goToSleep(anyLong())
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
index 2e98006..953b7fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/flags/ServerFlagReaderImplTest.kt
@@ -21,11 +21,13 @@
import com.android.systemui.SysuiTestCase
import com.android.systemui.util.DeviceConfigProxyFake
import com.android.systemui.util.concurrency.FakeExecutor
+import com.android.systemui.util.mockito.any
import com.android.systemui.util.time.FakeSystemClock
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
+import org.mockito.Mockito.anyString
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@@ -57,18 +59,18 @@
deviceConfig.setProperty(NAMESPACE, "flag_1", "1", false)
executor.runAllReady()
- verify(changeListener).onChange(flag)
+ verify(changeListener).onChange(flag, "1")
}
@Test
fun testChange_ignoresListenersDuringTest() {
val serverFlagReader = ServerFlagReaderImpl(NAMESPACE, deviceConfig, executor, true)
- val flag = ReleasedFlag(1, "1", "test")
+ val flag = ReleasedFlag(1, "1", " test")
serverFlagReader.listenForChanges(listOf(flag), changeListener)
deviceConfig.setProperty(NAMESPACE, "flag_override_1", "1", false)
executor.runAllReady()
- verify(changeListener, never()).onChange(flag)
+ verify(changeListener, never()).onChange(any(), anyString())
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
index 1365132..86246f7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/keyguard/domain/interactor/AlternateBouncerInteractorTest.kt
@@ -28,6 +28,7 @@
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepository
import com.android.systemui.keyguard.data.repository.KeyguardBouncerRepositoryImpl
import com.android.systemui.log.table.TableLogBuffer
+import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.time.FakeSystemClock
@@ -39,8 +40,10 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
import org.mockito.Mock
import org.mockito.Mockito.mock
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@OptIn(ExperimentalCoroutinesApi::class)
@@ -52,6 +55,7 @@
private lateinit var biometricSettingsRepository: FakeBiometricSettingsRepository
private lateinit var deviceEntryFingerprintAuthRepository:
FakeDeviceEntryFingerprintAuthRepository
+ @Mock private lateinit var statusBarStateController: StatusBarStateController
@Mock private lateinit var keyguardStateController: KeyguardStateController
@Mock private lateinit var systemClock: SystemClock
@Mock private lateinit var keyguardUpdateMonitor: KeyguardUpdateMonitor
@@ -73,6 +77,7 @@
featureFlags = FakeFeatureFlags().apply { this.set(Flags.MODERN_ALTERNATE_BOUNCER, true) }
underTest =
AlternateBouncerInteractor(
+ statusBarStateController,
keyguardStateController,
bouncerRepository,
biometricSettingsRepository,
@@ -130,6 +135,14 @@
}
@Test
+ fun canShowAlternateBouncerForFingerprint_isDozing() {
+ givenCanShowAlternateBouncer()
+ whenever(statusBarStateController.isDozing).thenReturn(true)
+
+ assertFalse(underTest.canShowAlternateBouncerForFingerprint())
+ }
+
+ @Test
fun show_whenCanShow() {
givenCanShowAlternateBouncer()
@@ -169,6 +182,42 @@
assertFalse(bouncerRepository.alternateBouncerVisible.value)
}
+ @Test
+ fun onUnlockedIsFalse_doesNotHide() {
+ // GIVEN alternate bouncer is showing
+ bouncerRepository.setAlternateVisible(true)
+
+ val keyguardStateControllerCallbackCaptor =
+ ArgumentCaptor.forClass(KeyguardStateController.Callback::class.java)
+ verify(keyguardStateController).addCallback(keyguardStateControllerCallbackCaptor.capture())
+
+ // WHEN isUnlocked=false
+ givenCanShowAlternateBouncer()
+ whenever(keyguardStateController.isUnlocked).thenReturn(false)
+ keyguardStateControllerCallbackCaptor.value.onUnlockedChanged()
+
+ // THEN the alternate bouncer is still visible
+ assertTrue(bouncerRepository.alternateBouncerVisible.value)
+ }
+
+ @Test
+ fun onUnlockedChangedIsTrue_hide() {
+ // GIVEN alternate bouncer is showing
+ bouncerRepository.setAlternateVisible(true)
+
+ val keyguardStateControllerCallbackCaptor =
+ ArgumentCaptor.forClass(KeyguardStateController.Callback::class.java)
+ verify(keyguardStateController).addCallback(keyguardStateControllerCallbackCaptor.capture())
+
+ // WHEN isUnlocked=true
+ givenCanShowAlternateBouncer()
+ whenever(keyguardStateController.isUnlocked).thenReturn(true)
+ keyguardStateControllerCallbackCaptor.value.onUnlockedChanged()
+
+ // THEN the alternate bouncer is hidden
+ assertFalse(bouncerRepository.alternateBouncerVisible.value)
+ }
+
private fun givenCanShowAlternateBouncer() {
bouncerRepository.setAlternateBouncerUIAvailable(true)
biometricSettingsRepository.setFingerprintEnrolled(true)
@@ -176,6 +225,7 @@
biometricSettingsRepository.setFingerprintEnabledByDevicePolicy(true)
deviceEntryFingerprintAuthRepository.setLockedOut(false)
whenever(keyguardStateController.isUnlocked).thenReturn(false)
+ whenever(statusBarStateController.isDozing).thenReturn(false)
}
private fun givenCannotShowAlternateBouncer() {
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
index df13fdd..55b57f1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaControlPanelTest.kt
@@ -2350,6 +2350,48 @@
}
}
+ @Test
+ fun outputSwitcher_hasCustomIntent_openOverLockscreen() {
+ // When the device for a media player has an intent that opens over lockscreen
+ val pendingIntent = mock(PendingIntent::class.java)
+ whenever(pendingIntent.isActivity).thenReturn(true)
+ whenever(keyguardStateController.isShowing).thenReturn(true)
+ whenever(activityIntentHelper.wouldPendingShowOverLockscreen(any(), any())).thenReturn(true)
+
+ val customDevice = device.copy(intent = pendingIntent)
+ val dataWithDevice = mediaData.copy(device = customDevice)
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(dataWithDevice, KEY)
+
+ // When the user taps on the output switcher,
+ seamless.callOnClick()
+
+ // Then we send the pending intent as is, without modifying the original intent
+ verify(pendingIntent).send(any(Bundle::class.java))
+ verify(pendingIntent, never()).getIntent()
+ }
+
+ @Test
+ fun outputSwitcher_hasCustomIntent_requiresUnlock() {
+ // When the device for a media player has an intent that cannot open over lockscreen
+ val pendingIntent = mock(PendingIntent::class.java)
+ whenever(pendingIntent.isActivity).thenReturn(true)
+ whenever(keyguardStateController.isShowing).thenReturn(true)
+ whenever(activityIntentHelper.wouldPendingShowOverLockscreen(any(), any()))
+ .thenReturn(false)
+
+ val customDevice = device.copy(intent = pendingIntent)
+ val dataWithDevice = mediaData.copy(device = customDevice)
+ player.attachPlayer(viewHolder)
+ player.bindPlayer(dataWithDevice, KEY)
+
+ // When the user taps on the output switcher,
+ seamless.callOnClick()
+
+ // Then we request keyguard dismissal
+ verify(activityStarter).postStartActivityDismissingKeyguard(eq(pendingIntent))
+ }
+
private fun getScrubbingChangeListener(): SeekBarViewModel.ScrubbingChangeListener =
withArgCaptor {
verify(seekBarViewModel).setScrubbingChangeListener(capture())
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
index 0fac3db..4565762 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/controls/ui/MediaViewControllerTest.kt
@@ -21,7 +21,6 @@
import android.testing.AndroidTestingRunner
import android.testing.TestableLooper
import android.view.View
-import androidx.constraintlayout.widget.ConstraintSet
import androidx.test.filters.SmallTest
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
@@ -61,8 +60,6 @@
@Mock private lateinit var mediaSubTitleWidgetState: WidgetState
@Mock private lateinit var mediaContainerWidgetState: WidgetState
@Mock private lateinit var mediaFlags: MediaFlags
- @Mock private lateinit var expandedLayout: ConstraintSet
- @Mock private lateinit var collapsedLayout: ConstraintSet
val delta = 0.1F
@@ -82,16 +79,47 @@
}
@Test
- fun testOrientationChanged_layoutsAreLoaded() {
- mediaViewController.expandedLayout = expandedLayout
- mediaViewController.collapsedLayout = collapsedLayout
-
+ fun testOrientationChanged_heightOfPlayerIsUpdated() {
val newConfig = Configuration()
+
+ mediaViewController.attach(player, MediaViewController.TYPE.PLAYER)
+ // Change the height to see the effect of orientation change.
+ MediaViewController.backgroundIds.forEach { id ->
+ mediaViewController.expandedLayout.getConstraint(id).layout.mHeight = 10
+ }
newConfig.orientation = ORIENTATION_LANDSCAPE
configurationController.onConfigurationChanged(newConfig)
- verify(expandedLayout).load(context, R.xml.media_session_expanded)
- verify(collapsedLayout).load(context, R.xml.media_session_collapsed)
+ MediaViewController.backgroundIds.forEach { id ->
+ assertTrue(
+ mediaViewController.expandedLayout.getConstraint(id).layout.mHeight ==
+ context.resources.getDimensionPixelSize(
+ R.dimen.qs_media_session_height_expanded
+ )
+ )
+ }
+ }
+
+ @Test
+ fun testOrientationChanged_heightOfRecCardIsUpdated() {
+ val newConfig = Configuration()
+
+ mediaViewController.attach(recommendation, MediaViewController.TYPE.RECOMMENDATION)
+ // Change the height to see the effect of orientation change.
+ mediaViewController.expandedLayout
+ .getConstraint(MediaViewController.recSizingViewId)
+ .layout
+ .mHeight = 10
+ newConfig.orientation = ORIENTATION_LANDSCAPE
+ configurationController.onConfigurationChanged(newConfig)
+
+ assertTrue(
+ mediaViewController.expandedLayout
+ .getConstraint(MediaViewController.recSizingViewId)
+ .layout
+ .mHeight ==
+ context.resources.getDimensionPixelSize(R.dimen.qs_media_session_height_expanded)
+ )
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
index 85e8d07..6c3d6f5 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/media/taptotransfer/common/MediaTttUtilsTest.kt
@@ -25,6 +25,7 @@
import com.android.systemui.common.shared.model.ContentDescription
import com.android.systemui.common.shared.model.ContentDescription.Companion.loadContentDescription
import com.android.systemui.common.shared.model.Icon
+import com.android.systemui.temporarydisplay.chipbar.ChipbarInfo.Companion.DEFAULT_ICON_TINT
import com.android.systemui.util.mockito.any
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -140,6 +141,7 @@
context.getString(R.string.media_transfer_receiver_content_description_unknown_app)
)
assertThat(iconInfo.icon).isEqualTo(MediaTttIcon.Resource(R.drawable.ic_cast))
+ assertThat(iconInfo.tint).isEqualTo(DEFAULT_ICON_TINT)
}
@Test
@@ -232,40 +234,40 @@
fun iconInfo_toTintedIcon_loaded() {
val contentDescription = ContentDescription.Loaded("test")
val drawable = context.getDrawable(R.drawable.ic_cake)!!
- val tintAttr = android.R.attr.textColorTertiary
+ val tint = R.color.GM2_blue_500
val iconInfo =
IconInfo(
contentDescription,
MediaTttIcon.Loaded(drawable),
- tintAttr,
+ tint,
isAppIcon = false,
)
val tinted = iconInfo.toTintedIcon()
assertThat(tinted.icon).isEqualTo(Icon.Loaded(drawable, contentDescription))
- assertThat(tinted.tintAttr).isEqualTo(tintAttr)
+ assertThat(tinted.tint).isEqualTo(tint)
}
@Test
fun iconInfo_toTintedIcon_resource() {
val contentDescription = ContentDescription.Loaded("test")
val drawableRes = R.drawable.ic_cake
- val tintAttr = android.R.attr.textColorTertiary
+ val tint = R.color.GM2_blue_500
val iconInfo =
IconInfo(
contentDescription,
MediaTttIcon.Resource(drawableRes),
- tintAttr,
+ tint,
isAppIcon = false
)
val tinted = iconInfo.toTintedIcon()
assertThat(tinted.icon).isEqualTo(Icon.Resource(drawableRes, contentDescription))
- assertThat(tinted.tintAttr).isEqualTo(tintAttr)
+ assertThat(tinted.tint).isEqualTo(tint)
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/multishade/domain/interactor/MultiShadeInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/multishade/domain/interactor/MultiShadeInteractorTest.kt
index 415e68f..bcc99bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/multishade/domain/interactor/MultiShadeInteractorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/multishade/domain/interactor/MultiShadeInteractorTest.kt
@@ -73,6 +73,28 @@
}
@Test
+ fun isAnyShadeExpanded() =
+ testScope.runTest {
+ val underTest = create()
+ val isAnyShadeExpanded: Boolean? by collectLastValue(underTest.isAnyShadeExpanded)
+ assertWithMessage("isAnyShadeExpanded must start with false!")
+ .that(isAnyShadeExpanded)
+ .isFalse()
+
+ underTest.setExpansion(shadeId = ShadeId.LEFT, expansion = 0.441f)
+ assertThat(isAnyShadeExpanded).isTrue()
+
+ underTest.setExpansion(shadeId = ShadeId.RIGHT, expansion = 0.442f)
+ assertThat(isAnyShadeExpanded).isTrue()
+
+ underTest.setExpansion(shadeId = ShadeId.RIGHT, expansion = 0f)
+ assertThat(isAnyShadeExpanded).isTrue()
+
+ underTest.setExpansion(shadeId = ShadeId.LEFT, expansion = 0f)
+ assertThat(isAnyShadeExpanded).isFalse()
+ }
+
+ @Test
fun isVisible_dualShadeConfig() =
testScope.runTest {
overrideResource(R.bool.dual_shade_enabled, true)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/multishade/domain/interactor/MultiShadeMotionEventInteractorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/multishade/domain/interactor/MultiShadeMotionEventInteractorTest.kt
new file mode 100644
index 0000000..f807146c
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/multishade/domain/interactor/MultiShadeMotionEventInteractorTest.kt
@@ -0,0 +1,334 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.multishade.domain.interactor
+
+import android.view.MotionEvent
+import android.view.ViewConfiguration
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.coroutines.collectLastValue
+import com.android.systemui.multishade.data.remoteproxy.MultiShadeInputProxy
+import com.android.systemui.multishade.data.repository.MultiShadeRepository
+import com.android.systemui.multishade.shared.model.ProxiedInputModel
+import com.android.systemui.multishade.shared.model.ShadeId
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.currentTime
+import kotlinx.coroutines.test.runCurrent
+import kotlinx.coroutines.test.runTest
+import org.junit.After
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@SmallTest
+@RunWith(JUnit4::class)
+class MultiShadeMotionEventInteractorTest : SysuiTestCase() {
+
+ private lateinit var underTest: MultiShadeMotionEventInteractor
+
+ private lateinit var testScope: TestScope
+ private lateinit var motionEvents: MutableSet<MotionEvent>
+ private lateinit var repository: MultiShadeRepository
+ private lateinit var interactor: MultiShadeInteractor
+ private val touchSlop: Int = ViewConfiguration.get(context).scaledTouchSlop
+
+ @Before
+ fun setUp() {
+ testScope = TestScope()
+ motionEvents = mutableSetOf()
+
+ val inputProxy = MultiShadeInputProxy()
+ repository =
+ MultiShadeRepository(
+ applicationContext = context,
+ inputProxy = inputProxy,
+ )
+ interactor =
+ MultiShadeInteractor(
+ applicationScope = testScope.backgroundScope,
+ repository = repository,
+ inputProxy = inputProxy,
+ )
+ underTest =
+ MultiShadeMotionEventInteractor(
+ applicationContext = context,
+ applicationScope = testScope.backgroundScope,
+ interactor = interactor,
+ )
+ }
+
+ @After
+ fun tearDown() {
+ motionEvents.forEach { motionEvent -> motionEvent.recycle() }
+ }
+
+ @Test
+ fun shouldIntercept_initialDown_returnsFalse() =
+ testScope.runTest {
+ assertThat(underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))).isFalse()
+ }
+
+ @Test
+ fun shouldIntercept_moveBelowTouchSlop_returnsFalse() =
+ testScope.runTest {
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
+
+ assertThat(
+ underTest.shouldIntercept(
+ motionEvent(
+ MotionEvent.ACTION_MOVE,
+ y = touchSlop - 1f,
+ )
+ )
+ )
+ .isFalse()
+ }
+
+ @Test
+ fun shouldIntercept_moveAboveTouchSlop_returnsTrue() =
+ testScope.runTest {
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
+
+ assertThat(
+ underTest.shouldIntercept(
+ motionEvent(
+ MotionEvent.ACTION_MOVE,
+ y = touchSlop + 1f,
+ )
+ )
+ )
+ .isTrue()
+ }
+
+ @Test
+ fun shouldIntercept_moveAboveTouchSlop_butHorizontalFirst_returnsFalse() =
+ testScope.runTest {
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
+
+ assertThat(
+ underTest.shouldIntercept(
+ motionEvent(
+ MotionEvent.ACTION_MOVE,
+ x = touchSlop + 1f,
+ )
+ )
+ )
+ .isFalse()
+ assertThat(
+ underTest.shouldIntercept(
+ motionEvent(
+ MotionEvent.ACTION_MOVE,
+ y = touchSlop + 1f,
+ )
+ )
+ )
+ .isFalse()
+ }
+
+ @Test
+ fun shouldIntercept_up_afterMovedAboveTouchSlop_returnsTrue() =
+ testScope.runTest {
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_MOVE, y = touchSlop + 1f))
+
+ assertThat(underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_UP))).isTrue()
+ }
+
+ @Test
+ fun shouldIntercept_cancel_afterMovedAboveTouchSlop_returnsTrue() =
+ testScope.runTest {
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_MOVE, y = touchSlop + 1f))
+
+ assertThat(underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_CANCEL))).isTrue()
+ }
+
+ @Test
+ fun shouldIntercept_moveAboveTouchSlopAndUp_butShadeExpanded_returnsFalse() =
+ testScope.runTest {
+ repository.setExpansion(ShadeId.LEFT, 0.1f)
+ runCurrent()
+
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
+
+ assertThat(
+ underTest.shouldIntercept(
+ motionEvent(
+ MotionEvent.ACTION_MOVE,
+ y = touchSlop + 1f,
+ )
+ )
+ )
+ .isFalse()
+ assertThat(underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_UP))).isFalse()
+ }
+
+ @Test
+ fun shouldIntercept_moveAboveTouchSlopAndCancel_butShadeExpanded_returnsFalse() =
+ testScope.runTest {
+ repository.setExpansion(ShadeId.LEFT, 0.1f)
+ runCurrent()
+
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
+
+ assertThat(
+ underTest.shouldIntercept(
+ motionEvent(
+ MotionEvent.ACTION_MOVE,
+ y = touchSlop + 1f,
+ )
+ )
+ )
+ .isFalse()
+ assertThat(underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_CANCEL))).isFalse()
+ }
+
+ @Test
+ fun tap_doesNotSendProxiedInput() =
+ testScope.runTest {
+ val leftShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.LEFT))
+ val rightShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.RIGHT))
+ val singleShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.SINGLE))
+
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_UP))
+
+ assertThat(leftShadeProxiedInput).isNull()
+ assertThat(rightShadeProxiedInput).isNull()
+ assertThat(singleShadeProxiedInput).isNull()
+ }
+
+ @Test
+ fun dragBelowTouchSlop_doesNotSendProxiedInput() =
+ testScope.runTest {
+ val leftShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.LEFT))
+ val rightShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.RIGHT))
+ val singleShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.SINGLE))
+
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_DOWN))
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_MOVE, y = touchSlop - 1f))
+ underTest.shouldIntercept(motionEvent(MotionEvent.ACTION_UP))
+
+ assertThat(leftShadeProxiedInput).isNull()
+ assertThat(rightShadeProxiedInput).isNull()
+ assertThat(singleShadeProxiedInput).isNull()
+ }
+
+ @Test
+ fun dragAboveTouchSlopAndUp() =
+ testScope.runTest {
+ val leftShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.LEFT))
+ val rightShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.RIGHT))
+ val singleShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.SINGLE))
+
+ underTest.shouldIntercept(
+ motionEvent(
+ MotionEvent.ACTION_DOWN,
+ x = 100f, // left shade
+ )
+ )
+ assertThat(leftShadeProxiedInput).isNull()
+ assertThat(rightShadeProxiedInput).isNull()
+ assertThat(singleShadeProxiedInput).isNull()
+
+ val yDragAmountPx = touchSlop + 1f
+ val moveEvent =
+ motionEvent(
+ MotionEvent.ACTION_MOVE,
+ x = 100f, // left shade
+ y = yDragAmountPx,
+ )
+ assertThat(underTest.shouldIntercept(moveEvent)).isTrue()
+ underTest.onTouchEvent(moveEvent, viewWidthPx = 1000)
+ assertThat(leftShadeProxiedInput)
+ .isEqualTo(
+ ProxiedInputModel.OnDrag(
+ xFraction = 0.1f,
+ yDragAmountPx = yDragAmountPx,
+ )
+ )
+ assertThat(rightShadeProxiedInput).isNull()
+ assertThat(singleShadeProxiedInput).isNull()
+
+ val upEvent = motionEvent(MotionEvent.ACTION_UP)
+ assertThat(underTest.shouldIntercept(upEvent)).isTrue()
+ underTest.onTouchEvent(upEvent, viewWidthPx = 1000)
+ assertThat(leftShadeProxiedInput).isNull()
+ assertThat(rightShadeProxiedInput).isNull()
+ assertThat(singleShadeProxiedInput).isNull()
+ }
+
+ @Test
+ fun dragAboveTouchSlopAndCancel() =
+ testScope.runTest {
+ val leftShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.LEFT))
+ val rightShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.RIGHT))
+ val singleShadeProxiedInput by collectLastValue(interactor.proxiedInput(ShadeId.SINGLE))
+
+ underTest.shouldIntercept(
+ motionEvent(
+ MotionEvent.ACTION_DOWN,
+ x = 900f, // right shade
+ )
+ )
+ assertThat(leftShadeProxiedInput).isNull()
+ assertThat(rightShadeProxiedInput).isNull()
+ assertThat(singleShadeProxiedInput).isNull()
+
+ val yDragAmountPx = touchSlop + 1f
+ val moveEvent =
+ motionEvent(
+ MotionEvent.ACTION_MOVE,
+ x = 900f, // right shade
+ y = yDragAmountPx,
+ )
+ assertThat(underTest.shouldIntercept(moveEvent)).isTrue()
+ underTest.onTouchEvent(moveEvent, viewWidthPx = 1000)
+ assertThat(leftShadeProxiedInput).isNull()
+ assertThat(rightShadeProxiedInput)
+ .isEqualTo(
+ ProxiedInputModel.OnDrag(
+ xFraction = 0.9f,
+ yDragAmountPx = yDragAmountPx,
+ )
+ )
+ assertThat(singleShadeProxiedInput).isNull()
+
+ val cancelEvent = motionEvent(MotionEvent.ACTION_CANCEL)
+ assertThat(underTest.shouldIntercept(cancelEvent)).isTrue()
+ underTest.onTouchEvent(cancelEvent, viewWidthPx = 1000)
+ assertThat(leftShadeProxiedInput).isNull()
+ assertThat(rightShadeProxiedInput).isNull()
+ assertThat(singleShadeProxiedInput).isNull()
+ }
+
+ private fun TestScope.motionEvent(
+ action: Int,
+ downTime: Long = currentTime,
+ eventTime: Long = currentTime,
+ x: Float = 0f,
+ y: Float = 0f,
+ ): MotionEvent {
+ val motionEvent = MotionEvent.obtain(downTime, eventTime, action, x, y, 0)
+ motionEvents.add(motionEvent)
+ return motionEvent
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/multishade/shared/math/MathTest.kt b/packages/SystemUI/tests/src/com/android/systemui/multishade/shared/math/MathTest.kt
new file mode 100644
index 0000000..8935309
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/multishade/shared/math/MathTest.kt
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.systemui.multishade.shared.math
+
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.google.common.truth.Truth.assertThat
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+@SmallTest
+@RunWith(JUnit4::class)
+class MathTest : SysuiTestCase() {
+
+ @Test
+ fun isZero_zero_true() {
+ assertThat(0f.isZero(epsilon = EPSILON)).isTrue()
+ }
+
+ @Test
+ fun isZero_belowPositiveEpsilon_true() {
+ assertThat((EPSILON * 0.999999f).isZero(epsilon = EPSILON)).isTrue()
+ }
+
+ @Test
+ fun isZero_aboveNegativeEpsilon_true() {
+ assertThat((EPSILON * -0.999999f).isZero(epsilon = EPSILON)).isTrue()
+ }
+
+ @Test
+ fun isZero_positiveEpsilon_false() {
+ assertThat(EPSILON.isZero(epsilon = EPSILON)).isFalse()
+ }
+
+ @Test
+ fun isZero_negativeEpsilon_false() {
+ assertThat((-EPSILON).isZero(epsilon = EPSILON)).isFalse()
+ }
+
+ @Test
+ fun isZero_positive_false() {
+ assertThat(1f.isZero(epsilon = EPSILON)).isFalse()
+ }
+
+ @Test
+ fun isZero_negative_false() {
+ assertThat((-1f).isZero(epsilon = EPSILON)).isFalse()
+ }
+
+ companion object {
+ private const val EPSILON = 0.0001f
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt
index bc31a0e..8e32f81 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/navigationbar/gestural/BackPanelControllerTest.kt
@@ -127,7 +127,7 @@
mBackPanelController.params.deactivationSwipeTriggerThreshold
)
clearInvocations(backCallback)
- Thread.sleep(MIN_DURATION_ACTIVE_ANIMATION)
+ Thread.sleep(MIN_DURATION_ACTIVE_BEFORE_INACTIVE_ANIMATION)
// Move in the opposite direction to cross the deactivation threshold and cancel back
continueTouch(START_X)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
index 3f940d6..0ee52ea 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/notetask/NoteTaskControllerTest.kt
@@ -46,6 +46,7 @@
import org.junit.runner.RunWith
import org.mockito.ArgumentMatchers.anyInt
import org.mockito.Mock
+import org.mockito.Mockito.isNull
import org.mockito.Mockito.verify
import org.mockito.Mockito.verifyZeroInteractions
import org.mockito.MockitoAnnotations
@@ -216,6 +217,41 @@
}
@Test
+ fun showNoteTaskWithUser_keyguardIsLocked_shouldStartActivityWithExpectedUserAndLogUiEvent() {
+ val user10 = UserHandle.of(/* userId= */ 10)
+ val expectedInfo =
+ noteTaskInfo.copy(
+ entryPoint = NoteTaskEntryPoint.TAIL_BUTTON,
+ isKeyguardLocked = true,
+ )
+ whenever(keyguardManager.isKeyguardLocked).thenReturn(expectedInfo.isKeyguardLocked)
+ whenever(resolver.resolveInfo(any(), any())).thenReturn(expectedInfo)
+
+ createNoteTaskController()
+ .showNoteTaskAsUser(
+ entryPoint = expectedInfo.entryPoint!!,
+ user = user10,
+ )
+
+ val intentCaptor = argumentCaptor<Intent>()
+ val userCaptor = argumentCaptor<UserHandle>()
+ verify(context).startActivityAsUser(capture(intentCaptor), capture(userCaptor))
+ intentCaptor.value.let { intent ->
+ assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
+ assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
+ assertThat(intent.flags and FLAG_ACTIVITY_NEW_TASK).isEqualTo(FLAG_ACTIVITY_NEW_TASK)
+ assertThat(intent.flags and FLAG_ACTIVITY_MULTIPLE_TASK)
+ .isEqualTo(FLAG_ACTIVITY_MULTIPLE_TASK)
+ assertThat(intent.flags and FLAG_ACTIVITY_NEW_DOCUMENT)
+ .isEqualTo(FLAG_ACTIVITY_NEW_DOCUMENT)
+ assertThat(intent.getBooleanExtra(Intent.EXTRA_USE_STYLUS_MODE, false)).isTrue()
+ }
+ assertThat(userCaptor.value).isEqualTo(user10)
+ verify(eventLogger).logNoteTaskOpened(expectedInfo)
+ verifyZeroInteractions(bubbles)
+ }
+
+ @Test
fun showNoteTask_keyguardIsUnlocked_shouldStartBubblesWithoutLoggingUiEvent() {
val expectedInfo =
noteTaskInfo.copy(
@@ -232,7 +268,8 @@
verifyZeroInteractions(context)
val intentCaptor = argumentCaptor<Intent>()
- verify(bubbles).showOrHideAppBubble(capture(intentCaptor))
+ verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle),
+ isNull())
intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
@@ -366,7 +403,8 @@
createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
val intentCaptor = argumentCaptor<Intent>()
- verify(bubbles).showOrHideAppBubble(capture(intentCaptor))
+ verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle),
+ isNull())
intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
@@ -389,7 +427,8 @@
createNoteTaskController().showNoteTask(entryPoint = NoteTaskEntryPoint.QUICK_AFFORDANCE)
val intentCaptor = argumentCaptor<Intent>()
- verify(bubbles).showOrHideAppBubble(capture(intentCaptor))
+ verify(bubbles).showOrHideAppBubble(capture(intentCaptor), eq(userTracker.userHandle),
+ isNull())
intentCaptor.value.let { intent ->
assertThat(intent.action).isEqualTo(Intent.ACTION_CREATE_NOTE)
assertThat(intent.`package`).isEqualTo(NOTES_PACKAGE_NAME)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
index 64e9a3e..7e052bf 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/external/TileServicesTest.java
@@ -29,6 +29,7 @@
import android.app.PendingIntent;
import android.content.ComponentName;
import android.content.Intent;
+import android.os.Binder;
import android.os.Handler;
import android.os.RemoteException;
import android.os.UserHandle;
@@ -41,6 +42,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.broadcast.BroadcastDispatcher;
import com.android.systemui.qs.QSHost;
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.CommandQueue;
import com.android.systemui.statusbar.phone.StatusBarIconController;
@@ -91,6 +93,8 @@
private TileLifecycleManager mTileLifecycleManager;
@Mock
private QSHost mQSHost;
+ @Mock
+ private PanelInteractor mPanelInteractor;
@Before
public void setUp() throws Exception {
@@ -107,7 +111,8 @@
Provider<Handler> provider = () -> new Handler(mTestableLooper.getLooper());
mTileService = new TestTileServices(mQSHost, provider, mBroadcastDispatcher,
- mUserTracker, mKeyguardStateController, mCommandQueue, mStatusBarIconController);
+ mUserTracker, mKeyguardStateController, mCommandQueue, mStatusBarIconController,
+ mPanelInteractor);
}
@After
@@ -222,13 +227,37 @@
verify(tile, never()).startActivityAndCollapse(pi);
}
+ @Test
+ public void testOnStartActivityCollapsesPanel() {
+ CustomTile tile = mock(CustomTile.class);
+ ComponentName componentName = mock(ComponentName.class);
+ when(tile.getComponent()).thenReturn(componentName);
+ when(componentName.getPackageName()).thenReturn(this.getContext().getPackageName());
+ TileServiceManager manager = mTileService.getTileWrapper(tile);
+
+ mTileService.onStartActivity(manager.getToken());
+ verify(mPanelInteractor).forceCollapsePanels();
+ }
+
+ @Test
+ public void testOnShowDialogCollapsesPanel() {
+ CustomTile tile = mock(CustomTile.class);
+ ComponentName componentName = mock(ComponentName.class);
+ when(tile.getComponent()).thenReturn(componentName);
+ when(componentName.getPackageName()).thenReturn(this.getContext().getPackageName());
+ TileServiceManager manager = mTileService.getTileWrapper(tile);
+
+ mTileService.onShowDialog(manager.getToken());
+ verify(mPanelInteractor).forceCollapsePanels();
+ }
+
private class TestTileServices extends TileServices {
TestTileServices(QSHost host, Provider<Handler> handlerProvider,
BroadcastDispatcher broadcastDispatcher, UserTracker userTracker,
KeyguardStateController keyguardStateController, CommandQueue commandQueue,
- StatusBarIconController statusBarIconController) {
+ StatusBarIconController statusBarIconController, PanelInteractor panelInteractor) {
super(host, handlerProvider, broadcastDispatcher, userTracker, keyguardStateController,
- commandQueue, statusBarIconController);
+ commandQueue, statusBarIconController, panelInteractor);
}
@Override
@@ -237,6 +266,8 @@
TileServiceManager manager = mock(TileServiceManager.class);
mManagers.add(manager);
when(manager.isLifecycleStarted()).thenReturn(true);
+ Binder b = new Binder();
+ when(manager.getToken()).thenReturn(b);
return manager;
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
new file mode 100644
index 0000000..45783ab
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/pipeline/domain/interactor/PanelInteractorImplTest.kt
@@ -0,0 +1,76 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+package com.android.systemui.qs.pipeline.domain.interactor
+
+import android.testing.AndroidTestingRunner
+import androidx.test.filters.SmallTest
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import java.util.Optional
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@RunWith(AndroidTestingRunner::class)
+@SmallTest
+class PanelInteractorImplTest : SysuiTestCase() {
+
+ @Mock private lateinit var centralSurfaces: CentralSurfaces
+
+ @Before
+ fun setup() {
+ MockitoAnnotations.initMocks(this)
+ }
+
+ @Test
+ fun openPanels_callsCentralSurfaces() {
+ val underTest = PanelInteractorImpl(Optional.of(centralSurfaces))
+
+ underTest.openPanels()
+
+ verify(centralSurfaces).postAnimateOpenPanels()
+ }
+
+ @Test
+ fun collapsePanels_callsCentralSurfaces() {
+ val underTest = PanelInteractorImpl(Optional.of(centralSurfaces))
+
+ underTest.collapsePanels()
+
+ verify(centralSurfaces).postAnimateCollapsePanels()
+ }
+
+ @Test
+ fun forceCollapsePanels_callsCentralSurfaces() {
+ val underTest = PanelInteractorImpl(Optional.of(centralSurfaces))
+
+ underTest.forceCollapsePanels()
+
+ verify(centralSurfaces).postAnimateForceCollapsePanels()
+ }
+
+ @Test
+ fun whenOptionalEmpty_doesnThrow() {
+ val underTest = PanelInteractorImpl(Optional.empty())
+
+ underTest.openPanels()
+ underTest.collapsePanels()
+ underTest.forceCollapsePanels()
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt
index bd99cd4..eeebd4f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/FontScalingTileTest.kt
@@ -84,6 +84,7 @@
qsLogger,
dialogLaunchAnimator,
FakeSettings(),
+ FakeSettings(),
featureFlags
)
fontScalingTile.initialize()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
index 33921c7..3642e87 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/LocationTileTest.kt
@@ -31,9 +31,12 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController
import com.android.systemui.qs.QSHost
import com.android.systemui.qs.logging.QSLogger
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor
import com.android.systemui.qs.tileimpl.QSTileImpl
import com.android.systemui.statusbar.policy.KeyguardStateController
import com.android.systemui.statusbar.policy.LocationController
+import com.android.systemui.util.mockito.argumentCaptor
+import com.android.systemui.util.mockito.capture
import com.google.common.truth.Truth.assertThat
import org.junit.After
import org.junit.Before
@@ -41,6 +44,7 @@
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.`when`
+import org.mockito.Mockito.verify
import org.mockito.MockitoAnnotations
@RunWith(AndroidTestingRunner::class)
@@ -65,6 +69,8 @@
private lateinit var locationController: LocationController
@Mock
private lateinit var keyguardStateController: KeyguardStateController
+ @Mock
+ private lateinit var panelInteractor: PanelInteractor
private val uiEventLogger = UiEventLoggerFake()
private lateinit var testableLooper: TestableLooper
@@ -86,7 +92,9 @@
activityStarter,
qsLogger,
locationController,
- keyguardStateController)
+ keyguardStateController,
+ panelInteractor,
+ )
}
@After
@@ -116,4 +124,18 @@
assertThat(state.icon)
.isEqualTo(QSTileImpl.ResourceIcon.get(R.drawable.qs_location_icon_on))
}
+
+ @Test
+ fun testClickWhenLockedWillCallOpenPanels() {
+ `when`(keyguardStateController.isMethodSecure).thenReturn(true)
+ `when`(keyguardStateController.isShowing).thenReturn(true)
+
+ tile.handleClick(null)
+
+ val captor = argumentCaptor<Runnable>()
+ verify(activityStarter).postQSRunnableDismissingKeyguard(capture(captor))
+ captor.value.run()
+
+ verify(panelInteractor).openPanels()
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
index 5aef758..d9ed1a2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/qs/tiles/ScreenRecordTileTest.java
@@ -45,6 +45,7 @@
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.qs.QSHost;
import com.android.systemui.qs.logging.QSLogger;
+import com.android.systemui.qs.pipeline.domain.interactor.PanelInteractor;
import com.android.systemui.qs.tileimpl.QSTileImpl;
import com.android.systemui.screenrecord.RecordingController;
import com.android.systemui.statusbar.phone.KeyguardDismissUtil;
@@ -83,6 +84,8 @@
private KeyguardStateController mKeyguardStateController;
@Mock
private DialogLaunchAnimator mDialogLaunchAnimator;
+ @Mock
+ private PanelInteractor mPanelInteractor;
private TestableLooper mTestableLooper;
private ScreenRecordTile mTile;
@@ -108,7 +111,8 @@
mController,
mKeyguardDismissUtil,
mKeyguardStateController,
- mDialogLaunchAnimator
+ mDialogLaunchAnimator,
+ mPanelInteractor
);
mTile.initialize();
@@ -146,7 +150,7 @@
assertNotNull(onStartRecordingClicked.getValue());
onStartRecordingClicked.getValue().run();
verify(mDialogLaunchAnimator).disableAllCurrentDialogsExitAnimations();
- verify(mHost).collapsePanels();
+ verify(mPanelInteractor).collapsePanels();
}
// Test that the tile is active and labeled correctly when the controller is starting
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt
index 1f18d91..08b5d2b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/ScreenshotDetectionControllerTest.kt
@@ -19,12 +19,14 @@
import android.content.ComponentName
import android.content.pm.ActivityInfo
import android.content.pm.PackageManager
+import android.content.pm.PackageManager.MATCH_DISABLED_COMPONENTS
import android.testing.AndroidTestingRunner
import android.view.Display
import android.view.IWindowManager
import android.view.WindowManager
import androidx.test.filters.SmallTest
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.argThat
import com.android.systemui.util.mockito.eq
import com.android.systemui.util.mockito.whenever
import junit.framework.Assert.assertEquals
@@ -32,6 +34,7 @@
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
+import org.mockito.ArgumentMatcher
import org.mockito.Mock
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
@@ -158,4 +161,56 @@
assertEquals(appName2, list[1])
assertEquals(appName3, list[2])
}
+
+ private fun includesFlagBits(@PackageManager.ComponentInfoFlagsBits mask: Int) =
+ ComponentInfoFlagMatcher(mask, mask)
+ private fun excludesFlagBits(@PackageManager.ComponentInfoFlagsBits mask: Int) =
+ ComponentInfoFlagMatcher(mask, 0)
+
+ private class ComponentInfoFlagMatcher(
+ @PackageManager.ComponentInfoFlagsBits val mask: Int, val value: Int
+ ): ArgumentMatcher<PackageManager.ComponentInfoFlags> {
+ override fun matches(flags: PackageManager.ComponentInfoFlags): Boolean {
+ return (mask.toLong() and flags.value) == value.toLong()
+ }
+
+ override fun toString(): String{
+ return "mask 0x%08x == 0x%08x".format(mask, value)
+ }
+ }
+
+ @Test
+ fun testMaybeNotifyOfScreenshot_disabledApp() {
+ val data = ScreenshotData.forTesting()
+ data.source = WindowManager.ScreenshotSource.SCREENSHOT_KEY_CHORD
+
+ val component = ComponentName("package1", "class1")
+ val appName = "app name"
+ val activityInfo = mock(ActivityInfo::class.java)
+
+ whenever(
+ packageManager.getActivityInfo(
+ eq(component),
+ argThat(includesFlagBits(MATCH_DISABLED_COMPONENTS))
+ )
+ ).thenReturn(activityInfo);
+
+ whenever(
+ packageManager.getActivityInfo(
+ eq(component),
+ argThat(excludesFlagBits(MATCH_DISABLED_COMPONENTS))
+ )
+ ).thenThrow(PackageManager.NameNotFoundException::class.java);
+
+ whenever(windowManager.notifyScreenshotListeners(eq(Display.DEFAULT_DISPLAY)))
+ .thenReturn(listOf(component))
+
+ whenever(activityInfo.loadLabel(eq(packageManager))).thenReturn(appName)
+
+ val list = controller.maybeNotifyOfScreenshot(data)
+
+ assertEquals(1, list.size)
+ assertEquals(appName, list[0])
+ }
+
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
index 3440f91..31f7771 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/screenshot/WorkProfileMessageControllerTest.java
@@ -45,7 +45,6 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.ArgumentMatchers;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -58,8 +57,9 @@
@SmallTest
@RunWith(AndroidTestingRunner.class)
public class WorkProfileMessageControllerTest extends SysuiTestCase {
- private static final String DEFAULT_LABEL = "default label";
- private static final String APP_LABEL = "app label";
+ private static final String FILES_APP_COMPONENT = "com.android.test/.FilesComponent";
+ private static final String FILES_APP_LABEL = "Custom Files App";
+ private static final String DEFAULT_FILES_APP_LABEL = "Files";
private static final UserHandle NON_WORK_USER = UserHandle.of(0);
private static final UserHandle WORK_USER = UserHandle.of(10);
@@ -88,14 +88,21 @@
when(mMockContext.getSharedPreferences(
eq(WorkProfileMessageController.SHARED_PREFERENCES_NAME),
eq(Context.MODE_PRIVATE))).thenReturn(mSharedPreferences);
- when(mMockContext.getString(ArgumentMatchers.anyInt())).thenReturn(DEFAULT_LABEL);
- when(mPackageManager.getActivityIcon(any(ComponentName.class)))
+ when(mMockContext.getString(R.string.config_sceenshotWorkProfileFilesApp))
+ .thenReturn(FILES_APP_COMPONENT);
+ when(mMockContext.getString(R.string.screenshot_default_files_app_name))
+ .thenReturn(DEFAULT_FILES_APP_LABEL);
+ when(mPackageManager.getActivityIcon(
+ eq(ComponentName.unflattenFromString(FILES_APP_COMPONENT))))
.thenReturn(mActivityIcon);
- when(mPackageManager.getUserBadgedIcon(
- any(), any())).thenReturn(mBadgedActivityIcon);
- when(mPackageManager.getActivityInfo(any(),
- any(PackageManager.ComponentInfoFlags.class))).thenReturn(mActivityInfo);
- when(mActivityInfo.loadLabel(eq(mPackageManager))).thenReturn(APP_LABEL);
+ when(mPackageManager.getUserBadgedIcon(any(), any()))
+ .thenReturn(mBadgedActivityIcon);
+ when(mPackageManager.getActivityInfo(
+ eq(ComponentName.unflattenFromString(FILES_APP_COMPONENT)),
+ any(PackageManager.ComponentInfoFlags.class)))
+ .thenReturn(mActivityInfo);
+ when(mActivityInfo.loadLabel(eq(mPackageManager)))
+ .thenReturn(FILES_APP_LABEL);
mSharedPreferences.edit().putBoolean(
WorkProfileMessageController.PREFERENCE_KEY, false).apply();
@@ -120,14 +127,15 @@
@Test
public void testOnScreenshotTaken_packageNotFound()
throws PackageManager.NameNotFoundException {
- when(mPackageManager.getActivityInfo(any(),
+ when(mPackageManager.getActivityInfo(
+ eq(ComponentName.unflattenFromString(FILES_APP_COMPONENT)),
any(PackageManager.ComponentInfoFlags.class))).thenThrow(
new PackageManager.NameNotFoundException());
WorkProfileMessageController.WorkProfileFirstRunData data =
mMessageController.onScreenshotTaken(WORK_USER);
- assertEquals(DEFAULT_LABEL, data.getAppName());
+ assertEquals(DEFAULT_FILES_APP_LABEL, data.getAppName());
assertNull(data.getIcon());
}
@@ -136,16 +144,28 @@
WorkProfileMessageController.WorkProfileFirstRunData data =
mMessageController.onScreenshotTaken(WORK_USER);
- assertEquals(APP_LABEL, data.getAppName());
+ assertEquals(FILES_APP_LABEL, data.getAppName());
assertEquals(mBadgedActivityIcon, data.getIcon());
}
@Test
+ public void testOnScreenshotTaken_noFilesAppComponentDefined() {
+ when(mMockContext.getString(R.string.config_sceenshotWorkProfileFilesApp))
+ .thenReturn("");
+
+ WorkProfileMessageController.WorkProfileFirstRunData data =
+ mMessageController.onScreenshotTaken(WORK_USER);
+
+ assertEquals(DEFAULT_FILES_APP_LABEL, data.getAppName());
+ assertNull(data.getIcon());
+ }
+
+ @Test
public void testPopulateView() throws InterruptedException {
ViewGroup layout = (ViewGroup) LayoutInflater.from(mContext).inflate(
R.layout.screenshot_work_profile_first_run, null);
WorkProfileMessageController.WorkProfileFirstRunData data =
- new WorkProfileMessageController.WorkProfileFirstRunData(APP_LABEL,
+ new WorkProfileMessageController.WorkProfileFirstRunData(FILES_APP_LABEL,
mBadgedActivityIcon);
final CountDownLatch countdown = new CountDownLatch(1);
mMessageController.populateView(layout, data, () -> {
@@ -157,7 +177,7 @@
assertEquals(mBadgedActivityIcon, image.getDrawable());
TextView text = layout.findViewById(R.id.screenshot_message_content);
// The app name is used in a template, but at least validate that it was inserted.
- assertTrue(text.getText().toString().contains(APP_LABEL));
+ assertTrue(text.getText().toString().contains(FILES_APP_LABEL));
// Validate that clicking the dismiss button calls back properly.
assertEquals(1, countdown.getCount());
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 526dc8d..dd79297 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowControllerImplTest.java
@@ -223,6 +223,16 @@
}
@Test
+ public void attach_fadingAway_wallpaperVisible() {
+ clearInvocations(mWindowManager);
+ mNotificationShadeWindowController.attach();
+ mNotificationShadeWindowController.setKeyguardFadingAway(true);
+
+ verify(mWindowManager).updateViewLayout(any(), mLayoutParameters.capture());
+ assertThat((mLayoutParameters.getValue().flags & FLAG_SHOW_WALLPAPER) != 0).isTrue();
+ }
+
+ @Test
public void setBackgroundBlurRadius_expandedWithBlurs() {
mNotificationShadeWindowController.setBackgroundBlurRadius(10);
verify(mNotificationShadeWindowView).setVisibility(eq(View.VISIBLE));
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
index 0dc2d17..5f34b2f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewControllerTest.kt
@@ -26,17 +26,19 @@
import com.android.keyguard.dagger.KeyguardBouncerComponent
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
-import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor
import com.android.systemui.classifier.FalsingCollectorFake
import com.android.systemui.dock.DockManager
import com.android.systemui.flags.FakeFeatureFlags
import com.android.systemui.flags.Flags
import com.android.systemui.keyguard.KeyguardUnlockAnimationController
-import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor
import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
import com.android.systemui.keyguard.shared.model.TransitionStep
import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
+import com.android.systemui.multishade.data.remoteproxy.MultiShadeInputProxy
+import com.android.systemui.multishade.data.repository.MultiShadeRepository
+import com.android.systemui.multishade.domain.interactor.MultiShadeInteractor
+import com.android.systemui.multishade.domain.interactor.MultiShadeMotionEventInteractor
import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
import com.android.systemui.statusbar.LockscreenShadeTransitionController
import com.android.systemui.statusbar.NotificationInsetsController
@@ -50,25 +52,30 @@
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
import com.android.systemui.statusbar.window.StatusBarWindowStateController
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.time.FakeSystemClock
import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.ArgumentCaptor
import org.mockito.Mock
-import org.mockito.Mockito
import org.mockito.Mockito.anyFloat
import org.mockito.Mockito.mock
import org.mockito.Mockito.never
import org.mockito.Mockito.verify
-import org.mockito.Mockito.`when` as whenever
import org.mockito.MockitoAnnotations
+import org.mockito.Mockito.`when` as whenever
+@OptIn(ExperimentalCoroutinesApi::class)
@SmallTest
@RunWith(AndroidTestingRunner::class)
@RunWithLooper(setAsMainLooper = true)
class NotificationShadeWindowViewControllerTest : SysuiTestCase() {
+
@Mock private lateinit var view: NotificationShadeWindowView
@Mock private lateinit var sysuiStatusBarStateController: SysuiStatusBarStateController
@Mock private lateinit var centralSurfaces: CentralSurfaces
@@ -88,8 +95,6 @@
@Mock private lateinit var phoneStatusBarViewController: PhoneStatusBarViewController
@Mock private lateinit var pulsingGestureListener: PulsingGestureListener
@Mock private lateinit var notificationInsetsController: NotificationInsetsController
- @Mock private lateinit var alternateBouncerInteractor: AlternateBouncerInteractor
- @Mock private lateinit var udfpsOverlayInteractor: UdfpsOverlayInteractor
@Mock lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
@Mock lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
@Mock lateinit var keyguardSecurityContainerController: KeyguardSecurityContainerController
@@ -102,6 +107,8 @@
private lateinit var underTest: NotificationShadeWindowViewController
+ private lateinit var testScope: TestScope
+
@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
@@ -115,8 +122,23 @@
whenever(keyguardTransitionInteractor.lockscreenToDreamingTransition)
.thenReturn(emptyFlow<TransitionStep>())
- val featureFlags = FakeFeatureFlags();
- featureFlags.set(Flags.TRACKPAD_GESTURE_BACK, false)
+ val featureFlags = FakeFeatureFlags()
+ featureFlags.set(Flags.TRACKPAD_GESTURE_COMMON, true)
+ featureFlags.set(Flags.TRACKPAD_GESTURE_FEATURES, false)
+ featureFlags.set(Flags.DUAL_SHADE, false)
+
+ val inputProxy = MultiShadeInputProxy()
+ testScope = TestScope()
+ val multiShadeInteractor =
+ MultiShadeInteractor(
+ applicationScope = testScope.backgroundScope,
+ repository =
+ MultiShadeRepository(
+ applicationContext = context,
+ inputProxy = inputProxy,
+ ),
+ inputProxy = inputProxy,
+ )
underTest =
NotificationShadeWindowViewController(
lockscreenShadeTransitionController,
@@ -139,11 +161,18 @@
pulsingGestureListener,
keyguardBouncerViewModel,
keyguardBouncerComponentFactory,
- alternateBouncerInteractor,
- udfpsOverlayInteractor,
keyguardTransitionInteractor,
primaryBouncerToGoneTransitionViewModel,
featureFlags,
+ { multiShadeInteractor },
+ FakeSystemClock(),
+ {
+ MultiShadeMotionEventInteractor(
+ applicationContext = context,
+ applicationScope = testScope.backgroundScope,
+ interactor = multiShadeInteractor,
+ )
+ },
)
underTest.setupExpandedStatusBar()
@@ -156,147 +185,152 @@
// tests need to be added to test the rest of handleDispatchTouchEvent.
@Test
- fun handleDispatchTouchEvent_nullStatusBarViewController_returnsFalse() {
- underTest.setStatusBarViewController(null)
+ fun handleDispatchTouchEvent_nullStatusBarViewController_returnsFalse() =
+ testScope.runTest {
+ underTest.setStatusBarViewController(null)
- val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
- assertThat(returnVal).isFalse()
- }
+ assertThat(returnVal).isFalse()
+ }
@Test
- fun handleDispatchTouchEvent_downTouchBelowView_sendsTouchToSb() {
- underTest.setStatusBarViewController(phoneStatusBarViewController)
- val ev = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
- whenever(phoneStatusBarViewController.sendTouchToView(ev)).thenReturn(true)
+ fun handleDispatchTouchEvent_downTouchBelowView_sendsTouchToSb() =
+ testScope.runTest {
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ val ev = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
+ whenever(phoneStatusBarViewController.sendTouchToView(ev)).thenReturn(true)
- val returnVal = interactionEventHandler.handleDispatchTouchEvent(ev)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(ev)
- verify(phoneStatusBarViewController).sendTouchToView(ev)
- assertThat(returnVal).isTrue()
- }
+ verify(phoneStatusBarViewController).sendTouchToView(ev)
+ assertThat(returnVal).isTrue()
+ }
@Test
- fun handleDispatchTouchEvent_downTouchBelowViewThenAnotherTouch_sendsTouchToSb() {
- underTest.setStatusBarViewController(phoneStatusBarViewController)
- val downEvBelow =
- MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
- interactionEventHandler.handleDispatchTouchEvent(downEvBelow)
+ fun handleDispatchTouchEvent_downTouchBelowViewThenAnotherTouch_sendsTouchToSb() =
+ testScope.runTest {
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ val downEvBelow =
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, VIEW_BOTTOM + 4f, 0)
+ interactionEventHandler.handleDispatchTouchEvent(downEvBelow)
- val nextEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, VIEW_BOTTOM + 5f, 0)
- whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+ val nextEvent =
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, VIEW_BOTTOM + 5f, 0)
+ whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
- val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
- verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
- assertThat(returnVal).isTrue()
- }
+ verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
+ assertThat(returnVal).isTrue()
+ }
@Test
- fun handleDispatchTouchEvent_downAndPanelCollapsedAndInSbBoundAndSbWindowShow_sendsTouchToSb() {
- underTest.setStatusBarViewController(phoneStatusBarViewController)
- whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
- whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
- whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ fun handleDispatchTouchEvent_downAndPanelCollapsedAndInSbBoundAndSbWindowShow_sendsTouchToSb() =
+ testScope.runTest {
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(true)
+ whenever(phoneStatusBarViewController.sendTouchToView(DOWN_EVENT)).thenReturn(true)
+
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
+
+ verify(phoneStatusBarViewController).sendTouchToView(DOWN_EVENT)
+ assertThat(returnVal).isTrue()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_panelNotCollapsed_returnsNull() =
+ testScope.runTest {
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(true)
+ // Item we're testing
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(false)
+
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
+
+ verify(phoneStatusBarViewController, never()).sendTouchToView(DOWN_EVENT)
+ assertThat(returnVal).isNull()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_touchNotInSbBounds_returnsNull() =
+ testScope.runTest {
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ // Item we're testing
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(false)
+
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
+
+ verify(phoneStatusBarViewController, never()).sendTouchToView(DOWN_EVENT)
+ assertThat(returnVal).isNull()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_sbWindowNotShowing_noSendTouchToSbAndReturnsTrue() =
+ testScope.runTest {
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(true)
+ // Item we're testing
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(false)
+
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
+
+ verify(phoneStatusBarViewController, never()).sendTouchToView(DOWN_EVENT)
+ assertThat(returnVal).isTrue()
+ }
+
+ @Test
+ fun handleDispatchTouchEvent_downEventSentToSbThenAnotherEvent_sendsTouchToSb() =
+ testScope.runTest {
+ underTest.setStatusBarViewController(phoneStatusBarViewController)
+ whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
+ whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
+ whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
+ .thenReturn(true)
+
+ // Down event first
+ interactionEventHandler.handleDispatchTouchEvent(DOWN_EVENT)
+
+ // Then another event
+ val nextEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
+ whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
+
+ val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
+
+ verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
+ assertThat(returnVal).isTrue()
+ }
+
+ @Test
+ fun shouldInterceptTouchEvent_statusBarKeyguardViewManagerShouldIntercept() {
+ // down event should be intercepted by keyguardViewManager
+ whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(DOWN_EVENT))
.thenReturn(true)
- whenever(phoneStatusBarViewController.sendTouchToView(downEv)).thenReturn(true)
-
- val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
-
- verify(phoneStatusBarViewController).sendTouchToView(downEv)
- assertThat(returnVal).isTrue()
- }
-
- @Test
- fun handleDispatchTouchEvent_panelNotCollapsed_returnsNull() {
- underTest.setStatusBarViewController(phoneStatusBarViewController)
- whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
- whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
- .thenReturn(true)
- // Item we're testing
- whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(false)
-
- val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
-
- verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
- assertThat(returnVal).isNull()
- }
-
- @Test
- fun handleDispatchTouchEvent_touchNotInSbBounds_returnsNull() {
- underTest.setStatusBarViewController(phoneStatusBarViewController)
- whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
- whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
- // Item we're testing
- whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
- .thenReturn(false)
-
- val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
-
- verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
- assertThat(returnVal).isNull()
- }
-
- @Test
- fun handleDispatchTouchEvent_sbWindowNotShowing_noSendTouchToSbAndReturnsTrue() {
- underTest.setStatusBarViewController(phoneStatusBarViewController)
- whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
- whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
- .thenReturn(true)
- // Item we're testing
- whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(false)
-
- val returnVal = interactionEventHandler.handleDispatchTouchEvent(downEv)
-
- verify(phoneStatusBarViewController, never()).sendTouchToView(downEv)
- assertThat(returnVal).isTrue()
- }
-
- @Test
- fun handleDispatchTouchEvent_downEventSentToSbThenAnotherEvent_sendsTouchToSb() {
- underTest.setStatusBarViewController(phoneStatusBarViewController)
- whenever(statusBarWindowStateController.windowIsShowing()).thenReturn(true)
- whenever(notificationPanelViewController.isFullyCollapsed).thenReturn(true)
- whenever(phoneStatusBarViewController.touchIsWithinView(anyFloat(), anyFloat()))
- .thenReturn(true)
-
- // Down event first
- interactionEventHandler.handleDispatchTouchEvent(downEv)
-
- // Then another event
- val nextEvent = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
- whenever(phoneStatusBarViewController.sendTouchToView(nextEvent)).thenReturn(true)
-
- val returnVal = interactionEventHandler.handleDispatchTouchEvent(nextEvent)
-
- verify(phoneStatusBarViewController).sendTouchToView(nextEvent)
- assertThat(returnVal).isTrue()
- }
-
- @Test
- fun shouldInterceptTouchEvent_downEventAlternateBouncer_ignoreIfInUdfpsOverlay() {
- // Down event within udfpsOverlay bounds while alternateBouncer is showing
- whenever(udfpsOverlayInteractor.canInterceptTouchInUdfpsBounds(downEv)).thenReturn(false)
- whenever(alternateBouncerInteractor.isVisibleState()).thenReturn(true)
// Then touch should not be intercepted
- val shouldIntercept = interactionEventHandler.shouldInterceptTouchEvent(downEv)
- assertThat(shouldIntercept).isFalse()
+ val shouldIntercept = interactionEventHandler.shouldInterceptTouchEvent(DOWN_EVENT)
+ assertThat(shouldIntercept).isTrue()
}
@Test
- fun testGetBouncerContainer() {
- Mockito.clearInvocations(view)
- underTest.bouncerContainer
- verify(view).findViewById<ViewGroup>(R.id.keyguard_bouncer_container)
- }
+ fun testGetKeyguardMessageArea() =
+ testScope.runTest {
+ underTest.keyguardMessageArea
+ verify(view).findViewById<ViewGroup>(R.id.keyguard_message_area)
+ }
- @Test
- fun testGetKeyguardMessageArea() {
- underTest.keyguardMessageArea
- verify(view).findViewById<ViewGroup>(R.id.keyguard_message_area)
+ companion object {
+ private val DOWN_EVENT = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ private const val VIEW_BOTTOM = 100
}
}
-
-private val downEv = MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
-private const val VIEW_BOTTOM = 100
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
deleted file mode 100644
index 2797440..0000000
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.java
+++ /dev/null
@@ -1,226 +0,0 @@
-/*
- * Copyright (C) 2017 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.android.systemui.shade;
-
-import static junit.framework.Assert.assertFalse;
-import static junit.framework.Assert.assertTrue;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.spy;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
-
-import static kotlinx.coroutines.flow.FlowKt.emptyFlow;
-
-import android.os.SystemClock;
-import android.testing.AndroidTestingRunner;
-import android.testing.TestableLooper;
-import android.view.MotionEvent;
-import android.view.ViewGroup;
-
-import androidx.test.filters.SmallTest;
-
-import com.android.keyguard.KeyguardSecurityContainerController;
-import com.android.keyguard.LockIconViewController;
-import com.android.keyguard.dagger.KeyguardBouncerComponent;
-import com.android.systemui.R;
-import com.android.systemui.SysuiTestCase;
-import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
-import com.android.systemui.classifier.FalsingCollectorFake;
-import com.android.systemui.dock.DockManager;
-import com.android.systemui.flags.FakeFeatureFlags;
-import com.android.systemui.flags.Flags;
-import com.android.systemui.keyguard.KeyguardUnlockAnimationController;
-import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
-import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor;
-import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel;
-import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel;
-import com.android.systemui.statusbar.DragDownHelper;
-import com.android.systemui.statusbar.LockscreenShadeTransitionController;
-import com.android.systemui.statusbar.NotificationInsetsController;
-import com.android.systemui.statusbar.NotificationShadeDepthController;
-import com.android.systemui.statusbar.NotificationShadeWindowController;
-import com.android.systemui.statusbar.SysuiStatusBarStateController;
-import com.android.systemui.statusbar.notification.stack.AmbientState;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout;
-import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController;
-import com.android.systemui.statusbar.phone.CentralSurfaces;
-import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
-import com.android.systemui.statusbar.window.StatusBarWindowStateController;
-import com.android.systemui.tuner.TunerService;
-
-import org.junit.Before;
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.mockito.ArgumentCaptor;
-import org.mockito.Captor;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
-
-@RunWith(AndroidTestingRunner.class)
-@TestableLooper.RunWithLooper(setAsMainLooper = true)
-@SmallTest
-public class NotificationShadeWindowViewTest extends SysuiTestCase {
-
- private NotificationShadeWindowView mView;
- private NotificationShadeWindowViewController mController;
-
- @Mock private TunerService mTunerService;
- @Mock private DragDownHelper mDragDownHelper;
- @Mock private SysuiStatusBarStateController mStatusBarStateController;
- @Mock private ShadeController mShadeController;
- @Mock private CentralSurfaces mCentralSurfaces;
- @Mock private DockManager mDockManager;
- @Mock private NotificationPanelViewController mNotificationPanelViewController;
- @Mock private NotificationStackScrollLayout mNotificationStackScrollLayout;
- @Mock private NotificationShadeDepthController mNotificationShadeDepthController;
- @Mock private NotificationShadeWindowController mNotificationShadeWindowController;
- @Mock private NotificationStackScrollLayoutController mNotificationStackScrollLayoutController;
- @Mock private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
- @Mock private StatusBarWindowStateController mStatusBarWindowStateController;
- @Mock private LockscreenShadeTransitionController mLockscreenShadeTransitionController;
- @Mock private LockIconViewController mLockIconViewController;
- @Mock private KeyguardUnlockAnimationController mKeyguardUnlockAnimationController;
- @Mock private AmbientState mAmbientState;
- @Mock private PulsingGestureListener mPulsingGestureListener;
- @Mock private KeyguardBouncerViewModel mKeyguardBouncerViewModel;
- @Mock private KeyguardBouncerComponent.Factory mKeyguardBouncerComponentFactory;
- @Mock private KeyguardBouncerComponent mKeyguardBouncerComponent;
- @Mock private KeyguardSecurityContainerController mKeyguardSecurityContainerController;
- @Mock private NotificationInsetsController mNotificationInsetsController;
- @Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
- @Mock private UdfpsOverlayInteractor mUdfpsOverlayInteractor;
- @Mock private KeyguardTransitionInteractor mKeyguardTransitionInteractor;
- @Mock private PrimaryBouncerToGoneTransitionViewModel mPrimaryBouncerToGoneTransitionViewModel;
-
- @Captor private ArgumentCaptor<NotificationShadeWindowView.InteractionEventHandler>
- mInteractionEventHandlerCaptor;
- private NotificationShadeWindowView.InteractionEventHandler mInteractionEventHandler;
-
- @Before
- public void setUp() {
- MockitoAnnotations.initMocks(this);
-
- mView = spy(new NotificationShadeWindowView(getContext(), null));
- when(mView.findViewById(R.id.notification_stack_scroller))
- .thenReturn(mNotificationStackScrollLayout);
-
- when(mView.findViewById(R.id.keyguard_bouncer_container)).thenReturn(mock(ViewGroup.class));
- when(mKeyguardBouncerComponentFactory.create(any(ViewGroup.class))).thenReturn(
- mKeyguardBouncerComponent);
- when(mKeyguardBouncerComponent.getSecurityContainerController()).thenReturn(
- mKeyguardSecurityContainerController);
-
- when(mStatusBarStateController.isDozing()).thenReturn(false);
- mDependency.injectTestDependency(ShadeController.class, mShadeController);
-
- when(mDockManager.isDocked()).thenReturn(false);
-
- when(mKeyguardTransitionInteractor.getLockscreenToDreamingTransition())
- .thenReturn(emptyFlow());
-
- FakeFeatureFlags featureFlags = new FakeFeatureFlags();
- featureFlags.set(Flags.TRACKPAD_GESTURE_BACK, false);
- mController = new NotificationShadeWindowViewController(
- mLockscreenShadeTransitionController,
- new FalsingCollectorFake(),
- mStatusBarStateController,
- mDockManager,
- mNotificationShadeDepthController,
- mView,
- mNotificationPanelViewController,
- new ShadeExpansionStateManager(),
- mNotificationStackScrollLayoutController,
- mStatusBarKeyguardViewManager,
- mStatusBarWindowStateController,
- mLockIconViewController,
- mCentralSurfaces,
- mNotificationShadeWindowController,
- mKeyguardUnlockAnimationController,
- mNotificationInsetsController,
- mAmbientState,
- mPulsingGestureListener,
- mKeyguardBouncerViewModel,
- mKeyguardBouncerComponentFactory,
- mAlternateBouncerInteractor,
- mUdfpsOverlayInteractor,
- mKeyguardTransitionInteractor,
- mPrimaryBouncerToGoneTransitionViewModel,
- featureFlags
- );
- mController.setupExpandedStatusBar();
- mController.setDragDownHelper(mDragDownHelper);
- }
-
- @Test
- public void testDragDownHelperCalledWhenDraggingDown() {
- when(mDragDownHelper.isDraggingDown()).thenReturn(true);
- long now = SystemClock.elapsedRealtime();
- MotionEvent ev = MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, 0 /* x */, 0 /* y */,
- 0 /* meta */);
- mView.onTouchEvent(ev);
- verify(mDragDownHelper).onTouchEvent(ev);
- ev.recycle();
- }
-
- @Test
- public void testInterceptTouchWhenShowingAltAuth() {
- captureInteractionEventHandler();
-
- // WHEN showing alt auth, not dozing, drag down helper doesn't want to intercept
- when(mStatusBarStateController.isDozing()).thenReturn(false);
- when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
- when(mUdfpsOverlayInteractor.canInterceptTouchInUdfpsBounds(any())).thenReturn(true);
- when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
-
- // THEN we should intercept touch
- assertTrue(mInteractionEventHandler.shouldInterceptTouchEvent(mock(MotionEvent.class)));
- }
-
- @Test
- public void testNoInterceptTouch() {
- captureInteractionEventHandler();
-
- // WHEN not showing alt auth, not dozing, drag down helper doesn't want to intercept
- when(mStatusBarStateController.isDozing()).thenReturn(false);
- when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
- when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
-
- // THEN we shouldn't intercept touch
- assertFalse(mInteractionEventHandler.shouldInterceptTouchEvent(mock(MotionEvent.class)));
- }
-
- @Test
- public void testHandleTouchEventWhenShowingAltAuth() {
- captureInteractionEventHandler();
-
- // WHEN showing alt auth, not dozing, drag down helper doesn't want to intercept
- when(mStatusBarStateController.isDozing()).thenReturn(false);
- when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
- when(mDragDownHelper.onInterceptTouchEvent(any())).thenReturn(false);
-
- // THEN we should handle the touch
- assertTrue(mInteractionEventHandler.handleTouchEvent(mock(MotionEvent.class)));
- }
-
- private void captureInteractionEventHandler() {
- verify(mView).setInteractionEventHandler(mInteractionEventHandlerCaptor.capture());
- mInteractionEventHandler = mInteractionEventHandlerCaptor.getValue();
-
- }
-}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
new file mode 100644
index 0000000..b40181e
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/NotificationShadeWindowViewTest.kt
@@ -0,0 +1,252 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.shade
+
+import android.os.SystemClock
+import android.testing.AndroidTestingRunner
+import android.testing.TestableLooper.RunWithLooper
+import android.view.MotionEvent
+import android.widget.FrameLayout
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardSecurityContainerController
+import com.android.keyguard.LockIconViewController
+import com.android.keyguard.dagger.KeyguardBouncerComponent
+import com.android.systemui.R
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.classifier.FalsingCollectorFake
+import com.android.systemui.dock.DockManager
+import com.android.systemui.flags.FakeFeatureFlags
+import com.android.systemui.flags.Flags
+import com.android.systemui.keyguard.KeyguardUnlockAnimationController
+import com.android.systemui.keyguard.domain.interactor.KeyguardTransitionInteractor
+import com.android.systemui.keyguard.ui.viewmodel.KeyguardBouncerViewModel
+import com.android.systemui.keyguard.ui.viewmodel.PrimaryBouncerToGoneTransitionViewModel
+import com.android.systemui.multishade.data.remoteproxy.MultiShadeInputProxy
+import com.android.systemui.multishade.data.repository.MultiShadeRepository
+import com.android.systemui.multishade.domain.interactor.MultiShadeInteractor
+import com.android.systemui.multishade.domain.interactor.MultiShadeMotionEventInteractor
+import com.android.systemui.shade.NotificationShadeWindowView.InteractionEventHandler
+import com.android.systemui.statusbar.DragDownHelper
+import com.android.systemui.statusbar.LockscreenShadeTransitionController
+import com.android.systemui.statusbar.NotificationInsetsController
+import com.android.systemui.statusbar.NotificationShadeDepthController
+import com.android.systemui.statusbar.NotificationShadeWindowController
+import com.android.systemui.statusbar.SysuiStatusBarStateController
+import com.android.systemui.statusbar.notification.stack.AmbientState
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayout
+import com.android.systemui.statusbar.notification.stack.NotificationStackScrollLayoutController
+import com.android.systemui.statusbar.phone.CentralSurfaces
+import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager
+import com.android.systemui.statusbar.window.StatusBarWindowStateController
+import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.mock
+import com.android.systemui.util.mockito.whenever
+import com.android.systemui.util.time.FakeSystemClock
+import com.google.common.truth.Truth.assertThat
+import kotlinx.coroutines.ExperimentalCoroutinesApi
+import kotlinx.coroutines.flow.emptyFlow
+import kotlinx.coroutines.test.TestScope
+import kotlinx.coroutines.test.runTest
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.ArgumentCaptor
+import org.mockito.Captor
+import org.mockito.Mock
+import org.mockito.Mockito.spy
+import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
+
+@OptIn(ExperimentalCoroutinesApi::class)
+@RunWith(AndroidTestingRunner::class)
+@RunWithLooper(setAsMainLooper = true)
+@SmallTest
+class NotificationShadeWindowViewTest : SysuiTestCase() {
+
+ @Mock private lateinit var dragDownHelper: DragDownHelper
+ @Mock private lateinit var statusBarStateController: SysuiStatusBarStateController
+ @Mock private lateinit var shadeController: ShadeController
+ @Mock private lateinit var centralSurfaces: CentralSurfaces
+ @Mock private lateinit var dockManager: DockManager
+ @Mock private lateinit var notificationPanelViewController: NotificationPanelViewController
+ @Mock private lateinit var notificationStackScrollLayout: NotificationStackScrollLayout
+ @Mock private lateinit var notificationShadeDepthController: NotificationShadeDepthController
+ @Mock private lateinit var notificationShadeWindowController: NotificationShadeWindowController
+ @Mock
+ private lateinit var notificationStackScrollLayoutController:
+ NotificationStackScrollLayoutController
+ @Mock private lateinit var statusBarKeyguardViewManager: StatusBarKeyguardViewManager
+ @Mock private lateinit var statusBarWindowStateController: StatusBarWindowStateController
+ @Mock
+ private lateinit var lockscreenShadeTransitionController: LockscreenShadeTransitionController
+ @Mock private lateinit var lockIconViewController: LockIconViewController
+ @Mock private lateinit var keyguardUnlockAnimationController: KeyguardUnlockAnimationController
+ @Mock private lateinit var ambientState: AmbientState
+ @Mock private lateinit var pulsingGestureListener: PulsingGestureListener
+ @Mock private lateinit var keyguardBouncerViewModel: KeyguardBouncerViewModel
+ @Mock private lateinit var keyguardBouncerComponentFactory: KeyguardBouncerComponent.Factory
+ @Mock private lateinit var keyguardBouncerComponent: KeyguardBouncerComponent
+ @Mock
+ private lateinit var keyguardSecurityContainerController: KeyguardSecurityContainerController
+ @Mock private lateinit var notificationInsetsController: NotificationInsetsController
+ @Mock private lateinit var keyguardTransitionInteractor: KeyguardTransitionInteractor
+ @Mock
+ private lateinit var primaryBouncerToGoneTransitionViewModel:
+ PrimaryBouncerToGoneTransitionViewModel
+ @Captor
+ private lateinit var interactionEventHandlerCaptor: ArgumentCaptor<InteractionEventHandler>
+
+ private lateinit var underTest: NotificationShadeWindowView
+ private lateinit var controller: NotificationShadeWindowViewController
+ private lateinit var interactionEventHandler: InteractionEventHandler
+ private lateinit var testScope: TestScope
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ underTest = spy(NotificationShadeWindowView(context, null))
+ whenever(
+ underTest.findViewById<NotificationStackScrollLayout>(
+ R.id.notification_stack_scroller
+ )
+ )
+ .thenReturn(notificationStackScrollLayout)
+ whenever(underTest.findViewById<FrameLayout>(R.id.keyguard_bouncer_container))
+ .thenReturn(mock())
+ whenever(keyguardBouncerComponentFactory.create(any())).thenReturn(keyguardBouncerComponent)
+ whenever(keyguardBouncerComponent.securityContainerController)
+ .thenReturn(keyguardSecurityContainerController)
+ whenever(statusBarStateController.isDozing).thenReturn(false)
+ mDependency.injectTestDependency(ShadeController::class.java, shadeController)
+ whenever(dockManager.isDocked).thenReturn(false)
+ whenever(keyguardTransitionInteractor.lockscreenToDreamingTransition)
+ .thenReturn(emptyFlow())
+
+ val featureFlags = FakeFeatureFlags()
+ featureFlags.set(Flags.TRACKPAD_GESTURE_COMMON, true)
+ featureFlags.set(Flags.TRACKPAD_GESTURE_FEATURES, false)
+ featureFlags.set(Flags.DUAL_SHADE, false)
+ val inputProxy = MultiShadeInputProxy()
+ testScope = TestScope()
+ val multiShadeInteractor =
+ MultiShadeInteractor(
+ applicationScope = testScope.backgroundScope,
+ repository =
+ MultiShadeRepository(
+ applicationContext = context,
+ inputProxy = inputProxy,
+ ),
+ inputProxy = inputProxy,
+ )
+ controller =
+ NotificationShadeWindowViewController(
+ lockscreenShadeTransitionController,
+ FalsingCollectorFake(),
+ statusBarStateController,
+ dockManager,
+ notificationShadeDepthController,
+ underTest,
+ notificationPanelViewController,
+ ShadeExpansionStateManager(),
+ notificationStackScrollLayoutController,
+ statusBarKeyguardViewManager,
+ statusBarWindowStateController,
+ lockIconViewController,
+ centralSurfaces,
+ notificationShadeWindowController,
+ keyguardUnlockAnimationController,
+ notificationInsetsController,
+ ambientState,
+ pulsingGestureListener,
+ keyguardBouncerViewModel,
+ keyguardBouncerComponentFactory,
+ keyguardTransitionInteractor,
+ primaryBouncerToGoneTransitionViewModel,
+ featureFlags,
+ { multiShadeInteractor },
+ FakeSystemClock(),
+ {
+ MultiShadeMotionEventInteractor(
+ applicationContext = context,
+ applicationScope = testScope.backgroundScope,
+ interactor = multiShadeInteractor,
+ )
+ },
+ )
+
+ controller.setupExpandedStatusBar()
+ controller.setDragDownHelper(dragDownHelper)
+ }
+
+ @Test
+ fun testDragDownHelperCalledWhenDraggingDown() =
+ testScope.runTest {
+ whenever(dragDownHelper.isDraggingDown).thenReturn(true)
+ val now = SystemClock.elapsedRealtime()
+ val ev = MotionEvent.obtain(now, now, MotionEvent.ACTION_UP, 0f, 0f, 0 /* meta */)
+ underTest.onTouchEvent(ev)
+ verify(dragDownHelper).onTouchEvent(ev)
+ ev.recycle()
+ }
+
+ @Test
+ fun testInterceptTouchWhenShowingAltAuth() =
+ testScope.runTest {
+ captureInteractionEventHandler()
+
+ // WHEN showing alt auth, not dozing, drag down helper doesn't want to intercept
+ whenever(statusBarStateController.isDozing).thenReturn(false)
+ whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(any())).thenReturn(true)
+ whenever(dragDownHelper.onInterceptTouchEvent(any())).thenReturn(false)
+
+ // THEN we should intercept touch
+ assertThat(interactionEventHandler.shouldInterceptTouchEvent(mock())).isTrue()
+ }
+
+ @Test
+ fun testNoInterceptTouch() =
+ testScope.runTest {
+ captureInteractionEventHandler()
+
+ // WHEN not showing alt auth, not dozing, drag down helper doesn't want to intercept
+ whenever(statusBarStateController.isDozing).thenReturn(false)
+ whenever(statusBarKeyguardViewManager.shouldInterceptTouchEvent(any()))
+ .thenReturn(false)
+ whenever(dragDownHelper.onInterceptTouchEvent(any())).thenReturn(false)
+
+ // THEN we shouldn't intercept touch
+ assertThat(interactionEventHandler.shouldInterceptTouchEvent(mock())).isFalse()
+ }
+
+ @Test
+ fun testHandleTouchEventWhenShowingAltAuth() =
+ testScope.runTest {
+ captureInteractionEventHandler()
+
+ // WHEN showing alt auth, not dozing, drag down helper doesn't want to intercept
+ whenever(statusBarStateController.isDozing).thenReturn(false)
+ whenever(statusBarKeyguardViewManager.onTouch(any())).thenReturn(true)
+ whenever(dragDownHelper.onInterceptTouchEvent(any())).thenReturn(false)
+
+ // THEN we should handle the touch
+ assertThat(interactionEventHandler.handleTouchEvent(mock())).isTrue()
+ }
+
+ private fun captureInteractionEventHandler() {
+ verify(underTest).setInteractionEventHandler(interactionEventHandlerCaptor.capture())
+ interactionEventHandler = interactionEventHandlerCaptor.value
+ }
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
index 15b8423..d8ffe39 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/QuickSettingsControllerTest.java
@@ -275,9 +275,7 @@
@Test
public void testPanelStaysOpenWhenClosingQs() {
- mShadeExpansionStateManager.onPanelExpansionChanged(/* fraction= */ 1,
- /* expanded= */ true, /* tracking= */ false, /* dragDownPxAmount= */ 0);
- mQsController.setShadeExpandedHeight(1);
+ mQsController.setShadeExpansion(/* shadeExpandedHeight= */ 1, /* expandedFraction=*/ 1);
float shadeExpandedHeight = mQsController.getShadeExpandedHeight();
mQsController.animateCloseQs(false);
@@ -289,7 +287,7 @@
public void interceptTouchEvent_withinQs_shadeExpanded_startsQsTracking() {
mQsController.setQs(mQs);
- mQsController.setShadeExpandedHeight(1f);
+ mQsController.setShadeExpansion(/* shadeExpandedHeight= */ 1, /* expandedFraction=*/ 1);
mQsController.onIntercept(
createMotionEvent(0, 0, ACTION_DOWN));
mQsController.onIntercept(
@@ -303,7 +301,7 @@
enableSplitShade(true);
mQsController.setQs(mQs);
- mQsController.setShadeExpandedHeight(1f);
+ mQsController.setShadeExpansion(/* shadeExpandedHeight= */ 1, /* expandedFraction=*/ 1);
mQsController.onIntercept(
createMotionEvent(0, 0, ACTION_DOWN));
mQsController.onIntercept(
@@ -342,13 +340,8 @@
public void handleTouch_downActionInQsArea() {
mQsController.setQs(mQs);
mQsController.setBarState(SHADE);
- mQsController.onPanelExpansionChanged(
- new ShadeExpansionChangeEvent(
- 0.5f,
- true,
- true,
- 0
- ));
+ mQsController.setShadeExpansion(/* shadeExpandedHeight= */ 1, /* expandedFraction=*/ 0.5f);
+
MotionEvent event =
createMotionEvent(QS_FRAME_WIDTH / 2, QS_FRAME_BOTTOM / 2, ACTION_DOWN);
mQsController.handleTouch(event, false, false);
@@ -385,7 +378,7 @@
@Test
public void handleTouch_isConflictingExpansionGestureSet() {
assertThat(mQsController.isConflictingExpansionGesture()).isFalse();
- mShadeExpansionStateManager.onPanelExpansionChanged(1f, true, false, 0f);
+ mQsController.setShadeExpansion(/* shadeExpandedHeight= */ 1, /* expandedFraction=*/ 1);
mQsController.handleTouch(MotionEvent.obtain(0L /* downTime */,
0L /* eventTime */, ACTION_DOWN, 0f /* x */, 0f /* y */,
0 /* metaState */), false, false);
@@ -394,7 +387,7 @@
@Test
public void handleTouch_isConflictingExpansionGestureSet_cancel() {
- mShadeExpansionStateManager.onPanelExpansionChanged(1f, true, false, 0f);
+ mQsController.setShadeExpansion(/* shadeExpandedHeight= */ 1, /* expandedFraction=*/ 1);
mQsController.handleTouch(createMotionEvent(0, 0, ACTION_DOWN), false, false);
assertThat(mQsController.isConflictingExpansionGesture()).isTrue();
mQsController.handleTouch(createMotionEvent(0, 0, ACTION_UP), true, true);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shade/SplitShadeTransitionAdapterTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shade/SplitShadeTransitionAdapterTest.kt
new file mode 100644
index 0000000..64fec5b
--- /dev/null
+++ b/packages/SystemUI/tests/src/com/android/systemui/shade/SplitShadeTransitionAdapterTest.kt
@@ -0,0 +1,74 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.systemui.shade
+
+import android.animation.Animator
+import android.testing.AndroidTestingRunner
+import android.transition.TransitionValues
+import androidx.test.filters.SmallTest
+import com.android.keyguard.KeyguardStatusViewController
+import com.android.systemui.SysuiTestCase
+import com.android.systemui.shade.NotificationPanelViewController.SplitShadeTransitionAdapter
+import com.google.common.truth.Truth.assertThat
+import org.junit.Before
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.mockito.Mock
+import org.mockito.MockitoAnnotations
+
+@SmallTest
+@RunWith(AndroidTestingRunner::class)
+class SplitShadeTransitionAdapterTest : SysuiTestCase() {
+
+ @Mock private lateinit var keyguardStatusViewController: KeyguardStatusViewController
+
+ private lateinit var adapter: SplitShadeTransitionAdapter
+
+ @Before
+ fun setUp() {
+ MockitoAnnotations.initMocks(this)
+ adapter = SplitShadeTransitionAdapter(keyguardStatusViewController)
+ }
+
+ @Test
+ fun createAnimator_nullStartValues_returnsNull() {
+ val animator = adapter.createAnimator(startValues = null, endValues = TransitionValues())
+
+ assertThat(animator).isNull()
+ }
+
+ @Test
+ fun createAnimator_nullEndValues_returnsNull() {
+ val animator = adapter.createAnimator(startValues = TransitionValues(), endValues = null)
+
+ assertThat(animator).isNull()
+ }
+
+ @Test
+ fun createAnimator_nonNullStartAndEndValues_returnsAnimator() {
+ val animator =
+ adapter.createAnimator(startValues = TransitionValues(), endValues = TransitionValues())
+
+ assertThat(animator).isNotNull()
+ }
+}
+
+private fun SplitShadeTransitionAdapter.createAnimator(
+ startValues: TransitionValues?,
+ endValues: TransitionValues?
+): Animator? {
+ return createAnimator(/* sceneRoot= */ null, startValues, endValues)
+}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
index 6a68b71..8841f48 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/animation/UnfoldMoveFromCenterAnimatorTest.kt
@@ -65,8 +65,8 @@
// Positive translationX -> translated to the right
// 10x10 view center is 25px from the center,
// When progress is 0.5 it should be translated at:
- // 25 * 0.3 * (1 - 0.5) = 3.75px
- assertThat(view.translationX).isWithin(0.01f).of(3.75f)
+ // 25 * 0.08 * (1 - 0.5) = 1px
+ assertThat(view.translationX).isWithin(0.01f).of(1.0f)
}
@Test
@@ -81,8 +81,8 @@
// Positive translationX -> translated to the right
// 10x10 view center is 25px from the center,
// When progress is 0 it should be translated at:
- // 25 * 0.3 * (1 - 0) = 7.5px
- assertThat(view.translationX).isWithin(0.01f).of(7.5f)
+ // 25 * 0.08 * (1 - 0) = 7.5px
+ assertThat(view.translationX).isWithin(0.01f).of(2f)
}
@Test
@@ -97,7 +97,7 @@
// Positive translationX -> translated to the right
// 10x10 view center is 25px from the center,
// When progress is 1 it should be translated at:
- // 25 * 0.3 * 0 = 0px
+ // 25 * 0.08 * 0 = 0px
assertThat(view.translationX).isEqualTo(0f)
}
@@ -113,8 +113,8 @@
// Positive translationX -> translated to the right, original translation is ignored
// 10x10 view center is 25px from the center,
// When progress is 0.5 it should be translated at:
- // 25 * 0.3 * (1 - 0.5) = 3.75px
- assertThat(view.translationX).isWithin(0.01f).of(3.75f)
+ // 25 * 0.08 * (1 - 0.5) = 1px
+ assertThat(view.translationX).isWithin(0.01f).of(1.0f)
}
@Test
@@ -154,7 +154,7 @@
animator.onTransitionProgress(0.5f)
// Positive translationY -> translated to the bottom
- assertThat(view.translationY).isWithin(0.01f).of(3.75f)
+ assertThat(view.translationY).isWithin(0.01f).of(1f)
}
@Test
@@ -169,7 +169,7 @@
animator.updateViewPositions()
// Negative translationX -> translated to the left
- assertThat(view.translationX).isWithin(0.1f).of(-5.25f)
+ assertThat(view.translationX).isWithin(0.1f).of(-1.4f)
}
private fun createView(
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
index 1fdb364..374aae1 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/clocks/ClockRegistryTest.kt
@@ -27,13 +27,16 @@
import com.android.systemui.plugins.ClockProviderPlugin
import com.android.systemui.plugins.ClockSettings
import com.android.systemui.plugins.PluginListener
+import com.android.systemui.plugins.PluginLifecycleManager
import com.android.systemui.plugins.PluginManager
import com.android.systemui.util.mockito.argumentCaptor
import com.android.systemui.util.mockito.eq
+import com.android.systemui.util.mockito.mock
import junit.framework.Assert.assertEquals
import junit.framework.Assert.fail
import kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.test.StandardTestDispatcher
+import kotlinx.coroutines.test.TestCoroutineScheduler
import kotlinx.coroutines.test.TestScope
import org.junit.Before
import org.junit.Rule
@@ -49,6 +52,7 @@
class ClockRegistryTest : SysuiTestCase() {
@JvmField @Rule val mockito = MockitoJUnit.rule()
+ private lateinit var scheduler: TestCoroutineScheduler
private lateinit var dispatcher: CoroutineDispatcher
private lateinit var scope: TestScope
@@ -58,37 +62,38 @@
@Mock private lateinit var mockDefaultClock: ClockController
@Mock private lateinit var mockThumbnail: Drawable
@Mock private lateinit var mockContentResolver: ContentResolver
+ @Mock private lateinit var mockPluginLifecycle: PluginLifecycleManager<ClockProviderPlugin>
private lateinit var fakeDefaultProvider: FakeClockPlugin
private lateinit var pluginListener: PluginListener<ClockProviderPlugin>
private lateinit var registry: ClockRegistry
companion object {
- private fun failFactory(): ClockController {
- fail("Unexpected call to createClock")
+ private fun failFactory(clockId: ClockId): ClockController {
+ fail("Unexpected call to createClock: $clockId")
return null!!
}
- private fun failThumbnail(): Drawable? {
- fail("Unexpected call to getThumbnail")
+ private fun failThumbnail(clockId: ClockId): Drawable? {
+ fail("Unexpected call to getThumbnail: $clockId")
return null
}
}
private class FakeClockPlugin : ClockProviderPlugin {
private val metadata = mutableListOf<ClockMetadata>()
- private val createCallbacks = mutableMapOf<ClockId, () -> ClockController>()
- private val thumbnailCallbacks = mutableMapOf<ClockId, () -> Drawable?>()
+ private val createCallbacks = mutableMapOf<ClockId, (ClockId) -> ClockController>()
+ private val thumbnailCallbacks = mutableMapOf<ClockId, (ClockId) -> Drawable?>()
override fun getClocks() = metadata
override fun createClock(settings: ClockSettings): ClockController =
- createCallbacks[settings.clockId!!]!!()
- override fun getClockThumbnail(id: ClockId): Drawable? = thumbnailCallbacks[id]!!()
+ createCallbacks[settings.clockId!!]!!(settings.clockId!!)
+ override fun getClockThumbnail(id: ClockId): Drawable? = thumbnailCallbacks[id]!!(id)
fun addClock(
id: ClockId,
name: String,
- create: () -> ClockController = ::failFactory,
- getThumbnail: () -> Drawable? = ::failThumbnail
+ create: (ClockId) -> ClockController = ::failFactory,
+ getThumbnail: (ClockId) -> Drawable? = ::failThumbnail
): FakeClockPlugin {
metadata.add(ClockMetadata(id, name))
createCallbacks[id] = create
@@ -99,7 +104,8 @@
@Before
fun setUp() {
- dispatcher = StandardTestDispatcher()
+ scheduler = TestCoroutineScheduler()
+ dispatcher = StandardTestDispatcher(scheduler)
scope = TestScope(dispatcher)
fakeDefaultProvider = FakeClockPlugin()
@@ -116,6 +122,8 @@
isEnabled = true,
handleAllUsers = true,
defaultClockProvider = fakeDefaultProvider,
+ keepAllLoaded = true,
+ subTag = "Test",
) {
override fun querySettings() { }
override fun applySettings(value: ClockSettings?) {
@@ -142,8 +150,8 @@
.addClock("clock_3", "clock 3")
.addClock("clock_4", "clock 4")
- pluginListener.onPluginConnected(plugin1, mockContext)
- pluginListener.onPluginConnected(plugin2, mockContext)
+ pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle)
+ pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle)
val list = registry.getClocks()
assertEquals(
list,
@@ -165,16 +173,18 @@
@Test
fun clockIdConflict_ErrorWithoutCrash() {
+ val mockPluginLifecycle1 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1", { mockClock }, { mockThumbnail })
.addClock("clock_2", "clock 2", { mockClock }, { mockThumbnail })
+ val mockPluginLifecycle2 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin2 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
- pluginListener.onPluginConnected(plugin1, mockContext)
- pluginListener.onPluginConnected(plugin2, mockContext)
+ pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle1)
+ pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle2)
val list = registry.getClocks()
assertEquals(
list,
@@ -202,8 +212,8 @@
.addClock("clock_4", "clock 4")
registry.applySettings(ClockSettings("clock_3", null))
- pluginListener.onPluginConnected(plugin1, mockContext)
- pluginListener.onPluginConnected(plugin2, mockContext)
+ pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle)
+ pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle)
val clock = registry.createCurrentClock()
assertEquals(mockClock, clock)
@@ -220,9 +230,9 @@
.addClock("clock_4", "clock 4")
registry.applySettings(ClockSettings("clock_3", null))
- pluginListener.onPluginConnected(plugin1, mockContext)
- pluginListener.onPluginConnected(plugin2, mockContext)
- pluginListener.onPluginDisconnected(plugin2)
+ pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle)
+ pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle)
+ pluginListener.onPluginUnloaded(plugin2, mockPluginLifecycle)
val clock = registry.createCurrentClock()
assertEquals(clock, mockDefaultClock)
@@ -230,15 +240,16 @@
@Test
fun pluginRemoved_clockAndListChanged() {
+ val mockPluginLifecycle1 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin1 = FakeClockPlugin()
.addClock("clock_1", "clock 1")
.addClock("clock_2", "clock 2")
+ val mockPluginLifecycle2 = mock<PluginLifecycleManager<ClockProviderPlugin>>()
val plugin2 = FakeClockPlugin()
.addClock("clock_3", "clock 3", { mockClock })
.addClock("clock_4", "clock 4")
-
var changeCallCount = 0
var listChangeCallCount = 0
registry.registerClockChangeListener(object : ClockRegistry.ClockChangeListener {
@@ -247,23 +258,38 @@
})
registry.applySettings(ClockSettings("clock_3", null))
- assertEquals(0, changeCallCount)
+ scheduler.runCurrent()
+ assertEquals(1, changeCallCount)
assertEquals(0, listChangeCallCount)
- pluginListener.onPluginConnected(plugin1, mockContext)
- assertEquals(0, changeCallCount)
+ pluginListener.onPluginLoaded(plugin1, mockContext, mockPluginLifecycle1)
+ scheduler.runCurrent()
+ assertEquals(1, changeCallCount)
assertEquals(1, listChangeCallCount)
- pluginListener.onPluginConnected(plugin2, mockContext)
- assertEquals(1, changeCallCount)
+ pluginListener.onPluginLoaded(plugin2, mockContext, mockPluginLifecycle2)
+ scheduler.runCurrent()
+ assertEquals(2, changeCallCount)
assertEquals(2, listChangeCallCount)
- pluginListener.onPluginDisconnected(plugin1)
- assertEquals(1, changeCallCount)
+ pluginListener.onPluginUnloaded(plugin1, mockPluginLifecycle1)
+ scheduler.runCurrent()
+ assertEquals(2, changeCallCount)
+ assertEquals(2, listChangeCallCount)
+
+ pluginListener.onPluginUnloaded(plugin2, mockPluginLifecycle2)
+ scheduler.runCurrent()
+ assertEquals(3, changeCallCount)
+ assertEquals(2, listChangeCallCount)
+
+ pluginListener.onPluginDetached(mockPluginLifecycle1)
+ scheduler.runCurrent()
+ assertEquals(3, changeCallCount)
assertEquals(3, listChangeCallCount)
- pluginListener.onPluginDisconnected(plugin2)
- assertEquals(2, changeCallCount)
+ pluginListener.onPluginDetached(mockPluginLifecycle2)
+ scheduler.runCurrent()
+ assertEquals(3, changeCallCount)
assertEquals(4, listChangeCallCount)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginActionManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginActionManagerTest.java
index 05280fa..c39b29f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginActionManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginActionManagerTest.java
@@ -79,11 +79,11 @@
private PluginInstance<TestPlugin> mPluginInstance;
private PluginInstance.Factory mPluginInstanceFactory = new PluginInstance.Factory(
this.getClass().getClassLoader(),
- new PluginInstance.InstanceFactory<>(), new PluginInstance.VersionChecker(),
+ new PluginInstance.InstanceFactory<>(), new PluginInstance.VersionCheckerImpl(),
Collections.emptyList(), false) {
@Override
public <T extends Plugin> PluginInstance<T> create(Context context, ApplicationInfo appInfo,
- ComponentName componentName, Class<T> pluginClass) {
+ ComponentName componentName, Class<T> pluginClass, PluginListener<T> listener) {
return (PluginInstance<T>) mPluginInstance;
}
};
@@ -128,7 +128,7 @@
createPlugin();
// Verify startup lifecycle
- verify(mPluginInstance).onCreate(mContext, mMockListener);
+ verify(mPluginInstance).onCreate();
}
@Test
@@ -140,7 +140,7 @@
mFakeExecutor.runAllReady();
// Verify shutdown lifecycle
- verify(mPluginInstance).onDestroy(mMockListener);
+ verify(mPluginInstance).onDestroy();
}
@Test
@@ -152,9 +152,9 @@
mFakeExecutor.runAllReady();
// Verify the old one was destroyed.
- verify(mPluginInstance).onDestroy(mMockListener);
+ verify(mPluginInstance).onDestroy();
verify(mPluginInstance, Mockito.times(2))
- .onCreate(mContext, mMockListener);
+ .onCreate();
}
@Test
@@ -188,7 +188,7 @@
mFakeExecutor.runAllReady();
// Verify startup lifecycle
- verify(mPluginInstance).onCreate(mContext, mMockListener);
+ verify(mPluginInstance).onCreate();
}
@Test
diff --git a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceTest.java b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceTest.java
index bb9a1e9..d5e904c 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/shared/plugins/PluginInstanceTest.java
@@ -16,11 +16,9 @@
package com.android.systemui.shared.plugins;
+import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.assertNotNull;
-
-import static org.mockito.Matchers.any;
-import static org.mockito.Mockito.verify;
-import static org.mockito.Mockito.when;
+import static junit.framework.Assert.assertNull;
import android.content.ComponentName;
import android.content.Context;
@@ -31,6 +29,7 @@
import com.android.systemui.SysuiTestCase;
import com.android.systemui.plugins.Plugin;
+import com.android.systemui.plugins.PluginLifecycleManager;
import com.android.systemui.plugins.PluginListener;
import com.android.systemui.plugins.annotations.ProvidesInterface;
import com.android.systemui.plugins.annotations.Requires;
@@ -38,46 +37,64 @@
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
-import org.mockito.Mock;
-import org.mockito.MockitoAnnotations;
+import java.lang.ref.WeakReference;
import java.util.Collections;
+import java.util.concurrent.atomic.AtomicInteger;
@SmallTest
@RunWith(AndroidJUnit4.class)
public class PluginInstanceTest extends SysuiTestCase {
private static final String PRIVILEGED_PACKAGE = "com.android.systemui.plugins";
-
- @Mock
- private TestPluginImpl mMockPlugin;
- @Mock
- private PluginListener<TestPlugin> mMockListener;
- @Mock
- private VersionInfo mVersionInfo;
- ComponentName mTestPluginComponentName =
+ private static final ComponentName TEST_PLUGIN_COMPONENT_NAME =
new ComponentName(PRIVILEGED_PACKAGE, TestPluginImpl.class.getName());
+
+ private FakeListener mPluginListener;
+ private VersionInfo mVersionInfo;
+ private VersionInfo.InvalidVersionException mVersionException;
+ private PluginInstance.VersionChecker mVersionChecker;
+
+ private RefCounter mCounter;
private PluginInstance<TestPlugin> mPluginInstance;
private PluginInstance.Factory mPluginInstanceFactory;
-
private ApplicationInfo mAppInfo;
- private Context mPluginContext;
- @Mock
- private PluginInstance.VersionChecker mVersionChecker;
+
+ // Because we're testing memory in this file, we must be careful not to assert the target
+ // objects, or capture them via mockito if we expect the garbage collector to later free them.
+ // Both JUnit and Mockito will save references and prevent these objects from being cleaned up.
+ private WeakReference<TestPluginImpl> mPlugin;
+ private WeakReference<Context> mPluginContext;
@Before
public void setup() throws Exception {
- MockitoAnnotations.initMocks(this);
+ mCounter = new RefCounter();
mAppInfo = mContext.getApplicationInfo();
- mAppInfo.packageName = mTestPluginComponentName.getPackageName();
- when(mVersionChecker.checkVersion(any(), any(), any())).thenReturn(mVersionInfo);
+ mAppInfo.packageName = TEST_PLUGIN_COMPONENT_NAME.getPackageName();
+ mPluginListener = new FakeListener();
+ mVersionInfo = new VersionInfo();
+ mVersionChecker = new PluginInstance.VersionChecker() {
+ @Override
+ public <T extends Plugin> VersionInfo checkVersion(
+ Class<T> instanceClass,
+ Class<T> pluginClass,
+ Plugin plugin
+ ) {
+ if (mVersionException != null) {
+ throw mVersionException;
+ }
+ return mVersionInfo;
+ }
+ };
mPluginInstanceFactory = new PluginInstance.Factory(
this.getClass().getClassLoader(),
new PluginInstance.InstanceFactory<TestPlugin>() {
@Override
TestPlugin create(Class cls) {
- return mMockPlugin;
+ TestPluginImpl plugin = new TestPluginImpl(mCounter);
+ mPlugin = new WeakReference<>(plugin);
+ return plugin;
}
},
mVersionChecker,
@@ -85,8 +102,9 @@
false);
mPluginInstance = mPluginInstanceFactory.create(
- mContext, mAppInfo, mTestPluginComponentName, TestPlugin.class);
- mPluginContext = mPluginInstance.getPluginContext();
+ mContext, mAppInfo, TEST_PLUGIN_COMPONENT_NAME,
+ TestPlugin.class, mPluginListener);
+ mPluginContext = new WeakReference<>(mPluginInstance.getPluginContext());
}
@Test
@@ -96,29 +114,51 @@
@Test(expected = VersionInfo.InvalidVersionException.class)
public void testIncorrectVersion() throws Exception {
-
ComponentName wrongVersionTestPluginComponentName =
new ComponentName(PRIVILEGED_PACKAGE, TestPlugin.class.getName());
- when(mVersionChecker.checkVersion(any(), any(), any())).thenThrow(
- new VersionInfo.InvalidVersionException("test", true));
+ mVersionException = new VersionInfo.InvalidVersionException("test", true);
mPluginInstanceFactory.create(
- mContext, mAppInfo, wrongVersionTestPluginComponentName, TestPlugin.class);
+ mContext, mAppInfo, wrongVersionTestPluginComponentName,
+ TestPlugin.class, mPluginListener);
}
@Test
public void testOnCreate() {
- mPluginInstance.onCreate(mContext, mMockListener);
- verify(mMockPlugin).onCreate(mContext, mPluginContext);
- verify(mMockListener).onPluginConnected(mMockPlugin, mPluginContext);
+ mPluginInstance.onCreate();
+ assertEquals(1, mPluginListener.mAttachedCount);
+ assertEquals(1, mPluginListener.mLoadCount);
+ assertEquals(mPlugin.get(), mPluginInstance.getPlugin());
+ assertInstances(1, 1);
}
@Test
public void testOnDestroy() {
- mPluginInstance.onDestroy(mMockListener);
- verify(mMockListener).onPluginDisconnected(mMockPlugin);
- verify(mMockPlugin).onDestroy();
+ mPluginInstance.onDestroy();
+ assertEquals(1, mPluginListener.mDetachedCount);
+ assertEquals(1, mPluginListener.mUnloadCount);
+ assertNull(mPluginInstance.getPlugin());
+ assertInstances(0, -1); // Destroyed but never created
+ }
+
+ @Test
+ public void testOnRepeatedlyLoadUnload_PluginFreed() {
+ mPluginInstance.onCreate();
+ mPluginInstance.loadPlugin();
+ assertInstances(1, 1);
+
+ mPluginInstance.unloadPlugin();
+ assertNull(mPluginInstance.getPlugin());
+ assertInstances(0, 0);
+
+ mPluginInstance.loadPlugin();
+ assertInstances(1, 1);
+
+ mPluginInstance.unloadPlugin();
+ mPluginInstance.onDestroy();
+ assertNull(mPluginInstance.getPlugin());
+ assertInstances(0, 0);
}
// This target class doesn't matter, it just needs to have a Requires to hit the flow where
@@ -129,10 +169,103 @@
String ACTION = "testAction";
}
+ public void assertInstances(Integer allocated, Integer created) {
+ // Run the garbage collector to finalize and deallocate outstanding
+ // instances. Since the GC doesn't always appear to want to run
+ // completely when we ask, we ask it 10 times in a short loop.
+ for (int i = 0; i < 10; i++) {
+ System.runFinalization();
+ System.gc();
+ }
+
+ mCounter.assertInstances(allocated, created);
+ }
+
+ public static class RefCounter {
+ public final AtomicInteger mAllocatedInstances = new AtomicInteger();
+ public final AtomicInteger mCreatedInstances = new AtomicInteger();
+
+ public void assertInstances(Integer allocated, Integer created) {
+ if (allocated != null) {
+ assertEquals(allocated.intValue(), mAllocatedInstances.get());
+ }
+ if (created != null) {
+ assertEquals(created.intValue(), mCreatedInstances.get());
+ }
+ }
+ }
+
@Requires(target = TestPlugin.class, version = TestPlugin.VERSION)
public static class TestPluginImpl implements TestPlugin {
+ public final RefCounter mCounter;
+ public TestPluginImpl(RefCounter counter) {
+ mCounter = counter;
+ mCounter.mAllocatedInstances.getAndIncrement();
+ }
+
+ @Override
+ public void finalize() {
+ mCounter.mAllocatedInstances.getAndDecrement();
+ }
+
@Override
public void onCreate(Context sysuiContext, Context pluginContext) {
+ mCounter.mCreatedInstances.getAndIncrement();
+ }
+
+ @Override
+ public void onDestroy() {
+ mCounter.mCreatedInstances.getAndDecrement();
+ }
+ }
+
+ public class FakeListener implements PluginListener<TestPlugin> {
+ public int mAttachedCount = 0;
+ public int mDetachedCount = 0;
+ public int mLoadCount = 0;
+ public int mUnloadCount = 0;
+
+ @Override
+ public void onPluginAttached(PluginLifecycleManager<TestPlugin> manager) {
+ mAttachedCount++;
+ assertEquals(PluginInstanceTest.this.mPluginInstance, manager);
+ }
+
+ @Override
+ public void onPluginDetached(PluginLifecycleManager<TestPlugin> manager) {
+ mDetachedCount++;
+ assertEquals(PluginInstanceTest.this.mPluginInstance, manager);
+ }
+
+ @Override
+ public void onPluginLoaded(
+ TestPlugin plugin,
+ Context pluginContext,
+ PluginLifecycleManager<TestPlugin> manager
+ ) {
+ mLoadCount++;
+ TestPlugin expectedPlugin = PluginInstanceTest.this.mPlugin.get();
+ if (expectedPlugin != null) {
+ assertEquals(expectedPlugin, plugin);
+ }
+ Context expectedContext = PluginInstanceTest.this.mPluginContext.get();
+ if (expectedContext != null) {
+ assertEquals(expectedContext, pluginContext);
+ }
+ assertEquals(PluginInstanceTest.this.mPluginInstance, manager);
+ }
+
+ @Override
+ public void onPluginUnloaded(
+ TestPlugin plugin,
+ PluginLifecycleManager<TestPlugin> manager
+ ) {
+ mUnloadCount++;
+ TestPlugin expectedPlugin = PluginInstanceTest.this.mPlugin.get();
+ if (expectedPlugin != null) {
+ assertEquals(expectedPlugin, plugin);
+ }
+ assertEquals(PluginInstanceTest.this.mPluginInstance, manager);
}
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
index 251aced..569f90b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/KeyguardIndicationControllerTest.java
@@ -105,6 +105,7 @@
import com.android.systemui.keyguard.domain.interactor.AlternateBouncerInteractor;
import com.android.systemui.plugins.FalsingManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
+import com.android.systemui.settings.UserTracker;
import com.android.systemui.statusbar.phone.KeyguardBypassController;
import com.android.systemui.statusbar.phone.KeyguardIndicationTextView;
import com.android.systemui.statusbar.phone.StatusBarKeyguardViewManager;
@@ -188,6 +189,8 @@
private AuthController mAuthController;
@Mock
private AlarmManager mAlarmManager;
+ @Mock
+ private UserTracker mUserTracker;
@Captor
private ArgumentCaptor<DockManager.AlignmentStateListener> mAlignmentListener;
@Captor
@@ -209,6 +212,7 @@
private BroadcastReceiver mBroadcastReceiver;
private FakeExecutor mExecutor = new FakeExecutor(new FakeSystemClock());
private TestableLooper mTestableLooper;
+ private final int mCurrentUserId = 1;
private KeyguardIndicationTextView mTextView; // AOD text
@@ -260,6 +264,7 @@
.thenReturn(mDisclosureGeneric);
when(mDevicePolicyResourcesManager.getString(anyString(), any(), anyString()))
.thenReturn(mDisclosureWithOrganization);
+ when(mUserTracker.getUserId()).thenReturn(mCurrentUserId);
mWakeLock = new WakeLockFake();
mWakeLockBuilder = new WakeLockFake.Builder(mContext);
@@ -291,7 +296,8 @@
mKeyguardBypassController, mAccessibilityManager,
mFaceHelpMessageDeferral, mock(KeyguardLogger.class),
mAlternateBouncerInteractor,
- mAlarmManager
+ mAlarmManager,
+ mUserTracker
);
mController.init();
mController.setIndicationArea(mIndicationArea);
@@ -813,7 +819,7 @@
public void faceErrorTimeout_whenFingerprintEnrolled_doesNotShowMessage() {
createController();
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(true);
+ getCurrentUser())).thenReturn(true);
String message = "A message";
mController.setVisible(true);
@@ -828,7 +834,7 @@
// GIVEN fingerprint enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(true);
+ getCurrentUser())).thenReturn(true);
// WHEN help messages received that are allowed to show
final String helpString = "helpString";
@@ -855,7 +861,7 @@
// GIVEN fingerprint enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(true);
+ getCurrentUser())).thenReturn(true);
// WHEN help messages received that aren't supposed to show
final String helpString = "helpString";
@@ -882,7 +888,7 @@
// GIVEN fingerprint NOT enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(false);
+ getCurrentUser())).thenReturn(false);
// WHEN help messages received
final Set<CharSequence> helpStrings = new HashSet<>();
@@ -913,7 +919,7 @@
// GIVEN fingerprint NOT enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(false);
+ getCurrentUser())).thenReturn(false);
// WHEN help message received and deferred message is valid
final String helpString = "helpMsg";
@@ -944,7 +950,7 @@
// GIVEN fingerprint enrolled
when(mKeyguardUpdateMonitor.getCachedIsUnlockWithFingerprintPossible(
- 0)).thenReturn(true);
+ getCurrentUser())).thenReturn(true);
// WHEN help message received and deferredMessage is valid
final String helpString = "helpMsg";
@@ -1173,7 +1179,7 @@
// WHEN trust is granted
when(mKeyguardUpdateMonitor.getUserHasTrust(anyInt())).thenReturn(true);
- mKeyguardUpdateMonitorCallback.onTrustChanged(KeyguardUpdateMonitor.getCurrentUser());
+ mKeyguardUpdateMonitorCallback.onTrustChanged(getCurrentUser());
// THEN verify the trust granted message shows
verifyIndicationMessage(
@@ -1238,7 +1244,7 @@
public void coEx_faceSuccess_showsPressToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, no a11y enabled
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(false);
@@ -1262,7 +1268,7 @@
public void coEx_faceSuccess_touchExplorationEnabled_showsFaceUnlockedSwipeToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y enabled
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(true);
@@ -1286,7 +1292,7 @@
public void coEx_faceSuccess_a11yEnabled_showsFaceUnlockedSwipeToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(true);
@@ -1309,7 +1315,7 @@
public void faceOnly_faceSuccess_showsFaceUnlockedSwipeToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, no udfps supported
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false);
createController();
@@ -1331,7 +1337,7 @@
public void udfpsOnly_a11yEnabled_showsSwipeToOpen() {
// GIVEN bouncer isn't showing, can skip bouncer, udfps is supported, a11y is enabled
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(true);
@@ -1351,7 +1357,7 @@
public void udfpsOnly_showsPressToOpen() {
// GIVEN bouncer isn't showing, udfps is supported, a11y is NOT enabled, can skip bouncer
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(true);
when(mAccessibilityManager.isEnabled()).thenReturn(false);
@@ -1372,7 +1378,7 @@
// GIVEN bouncer isn't showing, can skip bouncer, no security (udfps isn't supported,
// face wasn't authenticated)
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(true);
when(mKeyguardUpdateMonitor.isUdfpsSupported()).thenReturn(false);
createController();
@@ -1390,7 +1396,7 @@
public void cannotSkipBouncer_showSwipeToUnlockHint() {
// GIVEN bouncer isn't showing and cannot skip bouncer
when(mStatusBarKeyguardViewManager.isBouncerShowing()).thenReturn(false);
- when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(KeyguardUpdateMonitor.getCurrentUser()))
+ when(mKeyguardUpdateMonitor.getUserCanSkipBouncer(getCurrentUser()))
.thenReturn(false);
createController();
mController.setVisible(true);
@@ -1746,10 +1752,14 @@
private void setupFingerprintUnlockPossible(boolean possible) {
when(mKeyguardUpdateMonitor
- .getCachedIsUnlockWithFingerprintPossible(KeyguardUpdateMonitor.getCurrentUser()))
+ .getCachedIsUnlockWithFingerprintPossible(getCurrentUser()))
.thenReturn(possible);
}
+ private int getCurrentUser() {
+ return mCurrentUserId;
+ }
+
private void onFaceLockoutError(String errMsg) {
mKeyguardUpdateMonitorCallback.onBiometricError(FACE_ERROR_LOCKOUT_PERMANENT,
errMsg,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
index 5170678..ced0734 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/NotificationRemoteInputManagerTest.java
@@ -34,6 +34,7 @@
import com.android.systemui.dump.DumpManager;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
import com.android.systemui.statusbar.notification.NotifPipelineFlags;
+import com.android.systemui.statusbar.notification.RemoteInputControllerLogger;
import com.android.systemui.statusbar.notification.collection.NotificationEntry;
import com.android.systemui.statusbar.notification.collection.NotificationEntryBuilder;
import com.android.systemui.statusbar.notification.collection.render.NotificationVisibilityProvider;
@@ -41,6 +42,8 @@
import com.android.systemui.statusbar.phone.CentralSurfaces;
import com.android.systemui.statusbar.policy.RemoteInputUriController;
+import dagger.Lazy;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -49,8 +52,6 @@
import java.util.Optional;
-import dagger.Lazy;
-
@SmallTest
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -84,6 +85,7 @@
() -> Optional.of(mock(CentralSurfaces.class)),
mStateController,
mRemoteInputUriController,
+ mock(RemoteInputControllerLogger.class),
mClickNotifier,
mock(ActionClickLogger.class),
mock(DumpManager.class));
@@ -141,6 +143,7 @@
Lazy<Optional<CentralSurfaces>> centralSurfacesOptionalLazy,
StatusBarStateController statusBarStateController,
RemoteInputUriController remoteInputUriController,
+ RemoteInputControllerLogger remoteInputControllerLogger,
NotificationClickNotifier clickNotifier,
ActionClickLogger actionClickLogger,
DumpManager dumpManager) {
@@ -153,6 +156,7 @@
centralSurfacesOptionalLazy,
statusBarStateController,
remoteInputUriController,
+ remoteInputControllerLogger,
clickNotifier,
actionClickLogger,
dumpManager);
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 e6f272b..3327e42 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/StatusBarStateControllerImplTest.kt
@@ -167,4 +167,13 @@
controller.setIsDreaming(false)
verify(listener).onDreamingChanged(false)
}
+
+ @Test
+ fun testSetDreamState_getterReturnsCurrentState() {
+ controller.setIsDreaming(true)
+ assertTrue(controller.isDreaming())
+
+ controller.setIsDreaming(false)
+ assertFalse(controller.isDreaming())
+ }
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
index 8acf507..09b00e2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/notification/interruption/NotificationInterruptStateProviderImplTest.java
@@ -54,7 +54,6 @@
import android.os.Handler;
import android.os.PowerManager;
import android.os.RemoteException;
-import android.service.dreams.IDreamManager;
import android.testing.AndroidTestingRunner;
import androidx.test.filters.SmallTest;
@@ -94,8 +93,6 @@
@Mock
PowerManager mPowerManager;
@Mock
- IDreamManager mDreamManager;
- @Mock
AmbientDisplayConfiguration mAmbientDisplayConfiguration;
@Mock
StatusBarStateController mStatusBarStateController;
@@ -133,7 +130,6 @@
new NotificationInterruptStateProviderImpl(
mContext.getContentResolver(),
mPowerManager,
- mDreamManager,
mAmbientDisplayConfiguration,
mBatteryController,
mStatusBarStateController,
@@ -157,7 +153,7 @@
when(mHeadsUpManager.isSnoozed(any())).thenReturn(false);
when(mStatusBarStateController.isDozing()).thenReturn(false);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mPowerManager.isScreenOn()).thenReturn(true);
}
@@ -359,7 +355,7 @@
// Also not in use if screen is on but we're showing screen saver / "dreaming"
when(mPowerManager.isDeviceIdleMode()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(true);
+ when(mStatusBarStateController.isDreaming()).thenReturn(true);
assertThat(mNotifInterruptionStateProvider.shouldHeadsUp(entry)).isFalse();
}
@@ -539,7 +535,7 @@
public void testShouldNotFullScreen_notPendingIntent() throws RemoteException {
NotificationEntry entry = createNotification(IMPORTANCE_HIGH);
when(mPowerManager.isInteractive()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
@@ -558,7 +554,7 @@
.setSuppressedVisualEffects(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT)
.build();
when(mPowerManager.isInteractive()).thenReturn(false);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
@@ -577,7 +573,7 @@
.setSuppressedVisualEffects(SUPPRESSED_EFFECT_FULL_SCREEN_INTENT)
.build();
when(mPowerManager.isInteractive()).thenReturn(false);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
@@ -599,7 +595,7 @@
public void testShouldNotFullScreen_notHighImportance() throws RemoteException {
NotificationEntry entry = createFsiNotification(IMPORTANCE_DEFAULT, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
@@ -621,7 +617,7 @@
public void testShouldNotFullScreen_isGroupAlertSilenced() throws RemoteException {
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ true);
when(mPowerManager.isInteractive()).thenReturn(false);
- when(mDreamManager.isDreaming()).thenReturn(true);
+ when(mStatusBarStateController.isDreaming()).thenReturn(true);
when(mStatusBarStateController.getState()).thenReturn(KEYGUARD);
assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
@@ -651,7 +647,7 @@
public void testShouldFullScreen_notInteractive() throws RemoteException {
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(false);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
@@ -673,7 +669,7 @@
public void testShouldFullScreen_isDreaming() throws RemoteException {
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(true);
+ when(mStatusBarStateController.isDreaming()).thenReturn(true);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
@@ -695,7 +691,7 @@
public void testShouldFullScreen_onKeyguard() throws RemoteException {
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(KEYGUARD);
assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
@@ -718,7 +714,7 @@
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
when(mPowerManager.isScreenOn()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
@@ -735,7 +731,7 @@
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
when(mPowerManager.isScreenOn()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
@@ -754,7 +750,7 @@
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
when(mPowerManager.isScreenOn()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
when(mKeyguardStateController.isShowing()).thenReturn(true);
@@ -775,7 +771,7 @@
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
when(mPowerManager.isScreenOn()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
when(mKeyguardStateController.isShowing()).thenReturn(true);
@@ -800,7 +796,7 @@
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
when(mPowerManager.isScreenOn()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE_LOCKED);
when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
when(mKeyguardStateController.isShowing()).thenReturn(true);
@@ -821,7 +817,7 @@
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
when(mPowerManager.isScreenOn()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE_LOCKED);
when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
when(mKeyguardStateController.isShowing()).thenReturn(true);
@@ -846,7 +842,7 @@
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
when(mPowerManager.isScreenOn()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
when(mKeyguardStateController.isShowing()).thenReturn(false);
@@ -862,6 +858,23 @@
}
@Test
+ public void testShouldNotScreen_appSuspended() throws RemoteException {
+ NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
+ when(mPowerManager.isInteractive()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.getState()).thenReturn(SHADE);
+ modifyRanking(entry).setSuspended(true).build();
+
+ assertThat(mNotifInterruptionStateProvider.getFullScreenIntentDecision(entry))
+ .isEqualTo(FullScreenIntentDecision.NO_FSI_SUSPENDED);
+ assertThat(mNotifInterruptionStateProvider.shouldLaunchFullScreenIntentWhenAdded(entry))
+ .isFalse();
+ verify(mLogger).logNoFullscreen(entry, "NO_FSI_SUSPENDED");
+ verify(mLogger, never()).logNoFullscreenWarning(any(), any());
+ verify(mLogger, never()).logFullscreen(any(), any());
+ }
+
+ @Test
public void logFullScreenIntentDecision_shouldAlmostAlwaysLogOneTime() {
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
Set<FullScreenIntentDecision> warnings = new HashSet<>(Arrays.asList(
@@ -892,7 +905,7 @@
NotificationEntry entry = createFsiNotification(IMPORTANCE_HIGH, /* silenced */ false);
when(mPowerManager.isInteractive()).thenReturn(true);
when(mPowerManager.isScreenOn()).thenReturn(true);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
when(mStatusBarStateController.getState()).thenReturn(SHADE);
when(mHeadsUpManager.isSnoozed("a")).thenReturn(true);
when(mKeyguardStateController.isShowing()).thenReturn(false);
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 031c17f..1aba1fc 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
@@ -347,7 +347,6 @@
mNotificationInterruptStateProvider =
new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
mPowerManager,
- mDreamManager,
mAmbientDisplayConfiguration,
mStatusBarStateController,
mKeyguardStateController,
@@ -730,7 +729,7 @@
public void testShouldHeadsUp_nonSuppressedGroupSummary() throws Exception {
when(mPowerManager.isScreenOn()).thenReturn(true);
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
Notification n = new Notification.Builder(getContext(), "a")
.setGroup("a")
@@ -753,7 +752,7 @@
public void testShouldHeadsUp_suppressedGroupSummary() throws Exception {
when(mPowerManager.isScreenOn()).thenReturn(true);
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
Notification n = new Notification.Builder(getContext(), "a")
.setGroup("a")
@@ -776,7 +775,7 @@
public void testShouldHeadsUp_suppressedHeadsUp() throws Exception {
when(mPowerManager.isScreenOn()).thenReturn(true);
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
Notification n = new Notification.Builder(getContext(), "a").build();
@@ -797,7 +796,7 @@
public void testShouldHeadsUp_noSuppressedHeadsUp() throws Exception {
when(mPowerManager.isScreenOn()).thenReturn(true);
when(mHeadsUpManager.isSnoozed(anyString())).thenReturn(false);
- when(mDreamManager.isDreaming()).thenReturn(false);
+ when(mStatusBarStateController.isDreaming()).thenReturn(false);
Notification n = new Notification.Builder(getContext(), "a").build();
@@ -1343,6 +1342,18 @@
}
@Test
+ public void keyguard_notHidden_ifGoingAwayAndOccluded() {
+ setKeyguardShowingAndOccluded(true /* showing */, false /* occluded */);
+
+ when(mKeyguardStateController.isKeyguardGoingAway()).thenReturn(true);
+ when(mKeyguardStateController.isOccluded()).thenReturn(true);
+
+ mCentralSurfaces.updateIsKeyguard(false);
+
+ verify(mStatusBarStateController, never()).setState(eq(SHADE), anyBoolean());
+ }
+
+ @Test
public void frpLockedDevice_shadeDisabled() {
when(mDeviceProvisionedController.isFrpActive()).thenReturn(true);
when(mDozeServiceHost.isPulsing()).thenReturn(true);
@@ -1400,7 +1411,6 @@
TestableNotificationInterruptStateProviderImpl(
ContentResolver contentResolver,
PowerManager powerManager,
- IDreamManager dreamManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
StatusBarStateController controller,
KeyguardStateController keyguardStateController,
@@ -1415,7 +1425,6 @@
super(
contentResolver,
powerManager,
- dreamManager,
ambientDisplayConfiguration,
batteryController,
controller,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
index 3108ed9..fe12051 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/KeyguardStatusBarViewTest.java
@@ -21,6 +21,7 @@
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
import android.view.LayoutInflater;
+import android.view.View;
import androidx.test.filters.SmallTest;
@@ -49,6 +50,13 @@
}
@Test
+ public void userSwitcherChip_defaultVisibilityIsGone() {
+ assertThat(mKeyguardStatusBarView.findViewById(
+ R.id.user_switcher_container).getVisibility()).isEqualTo(
+ View.GONE);
+ }
+
+ @Test
public void setTopClipping_clippingUpdated() {
int topClipping = 40;
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
index cdc9898..3edf33b 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/PhoneStatusBarViewControllerTest.kt
@@ -25,6 +25,8 @@
import androidx.test.platform.app.InstrumentationRegistry
import com.android.systemui.R
import com.android.systemui.SysuiTestCase
+import com.android.systemui.flags.FeatureFlags
+import com.android.systemui.flags.Flags
import com.android.systemui.shade.NotificationPanelViewController
import com.android.systemui.shade.ShadeControllerImpl
import com.android.systemui.shade.ShadeLogger
@@ -34,6 +36,7 @@
import com.android.systemui.unfold.util.ScopedUnfoldTransitionProgressProvider
import com.android.systemui.user.ui.viewmodel.StatusBarUserChipViewModel
import com.android.systemui.util.mockito.any
+import com.android.systemui.util.mockito.whenever
import com.android.systemui.util.view.ViewUtil
import com.google.common.truth.Truth.assertThat
import org.junit.Before
@@ -54,6 +57,8 @@
@Mock
private lateinit var notificationPanelViewController: NotificationPanelViewController
@Mock
+ private lateinit var featureFlags: FeatureFlags
+ @Mock
private lateinit var moveFromCenterAnimation: StatusBarMoveFromCenterAnimationController
@Mock
private lateinit var sysuiUnfoldComponent: SysUIUnfoldComponent
@@ -93,6 +98,8 @@
@Test
fun onViewAttachedAndDrawn_moveFromCenterAnimationEnabled_moveFromCenterAnimationInitialized() {
+ whenever(featureFlags.isEnabled(Flags.ENABLE_UNFOLD_STATUS_BAR_ANIMATIONS))
+ .thenReturn(true)
val view = createViewMock()
val argumentCaptor = ArgumentCaptor.forClass(OnPreDrawListener::class.java)
unfoldConfig.isEnabled = true
@@ -108,6 +115,20 @@
}
@Test
+ fun onViewAttachedAndDrawn_statusBarAnimationDisabled_animationNotInitialized() {
+ whenever(featureFlags.isEnabled(Flags.ENABLE_UNFOLD_STATUS_BAR_ANIMATIONS))
+ .thenReturn(false)
+ val view = createViewMock()
+ unfoldConfig.isEnabled = true
+ // create the controller on main thread as it requires main looper
+ InstrumentationRegistry.getInstrumentation().runOnMainSync {
+ controller = createAndInitController(view)
+ }
+
+ verify(moveFromCenterAnimation, never()).onViewsReady(any())
+ }
+
+ @Test
fun handleTouchEventFromStatusBar_panelsNotEnabled_returnsFalseAndNoViewEvent() {
`when`(centralSurfacesImpl.commandQueuePanelsEnabled).thenReturn(false)
val returnVal = view.onTouchEvent(
@@ -179,6 +200,7 @@
return PhoneStatusBarViewController.Factory(
Optional.of(sysuiUnfoldComponent),
Optional.of(progressProvider),
+ featureFlags,
userChipViewModel,
centralSurfacesImpl,
shadeControllerImpl,
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 7a1270f..a9ed175 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
@@ -25,6 +25,7 @@
import static com.google.common.truth.Truth.assertThat;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyFloat;
import static org.mockito.ArgumentMatchers.anyInt;
@@ -1163,8 +1164,8 @@
@Test
public void testScrimFocus() {
mScrimController.transitionTo(ScrimState.AOD);
- Assert.assertFalse("Should not be focusable on AOD", mScrimBehind.isFocusable());
- Assert.assertFalse("Should not be focusable on AOD", mScrimInFront.isFocusable());
+ assertFalse("Should not be focusable on AOD", mScrimBehind.isFocusable());
+ assertFalse("Should not be focusable on AOD", mScrimInFront.isFocusable());
mScrimController.transitionTo(ScrimState.KEYGUARD);
Assert.assertTrue("Should be focusable on keyguard", mScrimBehind.isFocusable());
@@ -1224,7 +1225,7 @@
public void testAnimatesTransitionToAod() {
when(mDozeParameters.shouldControlScreenOff()).thenReturn(false);
ScrimState.AOD.prepare(ScrimState.KEYGUARD);
- Assert.assertFalse("No animation when ColorFade kicks in",
+ assertFalse("No animation when ColorFade kicks in",
ScrimState.AOD.getAnimateChange());
reset(mDozeParameters);
@@ -1236,9 +1237,9 @@
@Test
public void testViewsDontHaveFocusHighlight() {
- Assert.assertFalse("Scrim shouldn't have focus highlight",
+ assertFalse("Scrim shouldn't have focus highlight",
mScrimInFront.getDefaultFocusHighlightEnabled());
- Assert.assertFalse("Scrim shouldn't have focus highlight",
+ assertFalse("Scrim shouldn't have focus highlight",
mScrimBehind.getDefaultFocusHighlightEnabled());
}
@@ -1738,7 +1739,7 @@
@Test
public void aodStateSetsFrontScrimToNotBlend() {
mScrimController.transitionTo(ScrimState.AOD);
- Assert.assertFalse("Front scrim should not blend with main color",
+ assertFalse("Front scrim should not blend with main color",
mScrimInFront.shouldBlendWithMainColor());
}
@@ -1773,6 +1774,14 @@
verify(mStatusBarKeyguardViewManager).onKeyguardFadedAway();
}
+ @Test
+ public void testDoNotAnimateChangeIfOccludeAnimationPlaying() {
+ mScrimController.setOccludeAnimationPlaying(true);
+ mScrimController.transitionTo(ScrimState.UNLOCKED);
+
+ assertFalse(ScrimState.UNLOCKED.mAnimateChange);
+ }
+
private void assertAlphaAfterExpansion(ScrimView scrim, float expectedAlpha, float expansion) {
mScrimController.setRawPanelExpansionFraction(expansion);
finishAnimationsImmediately();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImplTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImplTest.kt
index 3bc288a2..08e89fb 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImplTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarIconControllerImplTest.kt
@@ -20,13 +20,17 @@
import androidx.test.filters.SmallTest
import com.android.internal.statusbar.StatusBarIcon
import com.android.systemui.SysuiTestCase
+import com.android.systemui.statusbar.CommandQueue
import com.android.systemui.statusbar.phone.StatusBarIconController.TAG_PRIMARY
import com.android.systemui.statusbar.phone.StatusBarIconControllerImpl.EXTERNAL_SLOT_SUFFIX
+import com.android.systemui.util.mockito.kotlinArgumentCaptor
import com.android.systemui.util.mockito.mock
import com.google.common.truth.Truth.assertThat
import org.junit.Before
import org.junit.Test
+import org.mockito.Mock
import org.mockito.Mockito.verify
+import org.mockito.MockitoAnnotations
@SmallTest
class StatusBarIconControllerImplTest : SysuiTestCase() {
@@ -34,15 +38,19 @@
private lateinit var underTest: StatusBarIconControllerImpl
private lateinit var iconList: StatusBarIconList
+ private lateinit var commandQueueCallbacks: CommandQueue.Callbacks
private val iconGroup: StatusBarIconController.IconManager = mock()
+ @Mock private lateinit var commandQueue: CommandQueue
+
@Before
fun setUp() {
+ MockitoAnnotations.initMocks(this)
iconList = StatusBarIconList(arrayOf())
underTest =
StatusBarIconControllerImpl(
context,
- mock(),
+ commandQueue,
mock(),
mock(),
mock(),
@@ -51,11 +59,14 @@
mock(),
)
underTest.addIconGroup(iconGroup)
+ val commandQueueCallbacksCaptor = kotlinArgumentCaptor<CommandQueue.Callbacks>()
+ verify(commandQueue).addCallback(commandQueueCallbacksCaptor.capture())
+ commandQueueCallbacks = commandQueueCallbacksCaptor.value
}
/** Regression test for b/255428281. */
@Test
- fun internalAndExternalIconWithSameName_bothDisplayed() {
+ fun internalAndExternalIconWithSameName_externalFromTile_bothDisplayed() {
val slotName = "mute"
// Internal
@@ -71,7 +82,7 @@
/* number= */ 0,
"contentDescription",
)
- underTest.setIcon(slotName, externalIcon)
+ underTest.setIconFromTile(slotName, externalIcon)
assertThat(iconList.slots).hasSize(2)
// Whichever was added last comes first
@@ -83,17 +94,45 @@
/** Regression test for b/255428281. */
@Test
- fun internalAndExternalIconWithSameName_externalRemoved_viaRemoveIcon_internalStays() {
+ fun internalAndExternalIconWithSameName_externalFromCommandQueue_bothDisplayed() {
val slotName = "mute"
// Internal
underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
// External
- underTest.setIcon(slotName, createExternalIcon())
+ val externalIcon =
+ StatusBarIcon(
+ "external.package",
+ UserHandle.ALL,
+ /* iconId= */ 2,
+ /* iconLevel= */ 0,
+ /* number= */ 0,
+ "contentDescription",
+ )
+ commandQueueCallbacks.setIcon(slotName, externalIcon)
- // WHEN the external icon is removed via #removeIcon
- underTest.removeIcon(slotName)
+ assertThat(iconList.slots).hasSize(2)
+ // Whichever was added last comes first
+ assertThat(iconList.slots[0].name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+ assertThat(iconList.slots[1].name).isEqualTo(slotName)
+ assertThat(iconList.slots[0].hasIconsInSlot()).isTrue()
+ assertThat(iconList.slots[1].hasIconsInSlot()).isTrue()
+ }
+
+ /** Regression test for b/255428281. */
+ @Test
+ fun internalAndExternalIconWithSameName_externalRemoved_fromCommandQueue_internalStays() {
+ val slotName = "mute"
+
+ // Internal
+ underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+ // External
+ commandQueueCallbacks.setIcon(slotName, createExternalIcon())
+
+ // WHEN the external icon is removed via CommandQueue.Callbacks#removeIcon
+ commandQueueCallbacks.removeIcon(slotName)
// THEN the external icon is removed but the internal icon remains
// Note: [StatusBarIconList] never removes slots from its list, it just sets the holder for
@@ -109,17 +148,17 @@
/** Regression test for b/255428281. */
@Test
- fun internalAndExternalIconWithSameName_externalRemoved_viaRemoveAll_internalStays() {
+ fun internalAndExternalIconWithSameName_externalRemoved_fromTileRemove_internalStays() {
val slotName = "mute"
// Internal
underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
// External
- underTest.setIcon(slotName, createExternalIcon())
+ underTest.setIconFromTile(slotName, createExternalIcon())
- // WHEN the external icon is removed via #removeAllIconsForExternalSlot
- underTest.removeAllIconsForExternalSlot(slotName)
+ // WHEN the external icon is removed via #removeIconForTile
+ underTest.removeIconForTile(slotName)
// THEN the external icon is removed but the internal icon remains
assertThat(iconList.slots).hasSize(2)
@@ -133,17 +172,17 @@
/** Regression test for b/255428281. */
@Test
- fun internalAndExternalIconWithSameName_externalRemoved_viaSetNull_internalStays() {
+ fun internalAndExternalIconWithSameName_externalRemoved_fromTileSetNull_internalStays() {
val slotName = "mute"
// Internal
underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
// External
- underTest.setIcon(slotName, createExternalIcon())
+ underTest.setIconFromTile(slotName, createExternalIcon())
- // WHEN the external icon is removed via a #setIcon(null)
- underTest.setIcon(slotName, /* icon= */ null)
+ // WHEN the external icon is removed via a #setIconFromTile(null)
+ underTest.setIconFromTile(slotName, /* icon= */ null)
// THEN the external icon is removed but the internal icon remains
assertThat(iconList.slots).hasSize(2)
@@ -164,12 +203,12 @@
underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
// External
- underTest.setIcon(slotName, createExternalIcon())
+ underTest.setIconFromTile(slotName, createExternalIcon())
// WHEN the internal icon is removed via #removeIcon
underTest.removeIcon(slotName, /* tag= */ 0)
- // THEN the external icon is removed but the internal icon remains
+ // THEN the internal icon is removed but the external icon remains
assertThat(iconList.slots).hasSize(2)
assertThat(iconList.slots[0].name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
assertThat(iconList.slots[1].name).isEqualTo(slotName)
@@ -188,12 +227,12 @@
underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
// External
- underTest.setIcon(slotName, createExternalIcon())
+ underTest.setIconFromTile(slotName, createExternalIcon())
// WHEN the internal icon is removed via #removeAllIconsForSlot
underTest.removeAllIconsForSlot(slotName)
- // THEN the external icon is removed but the internal icon remains
+ // THEN the internal icon is removed but the external icon remains
assertThat(iconList.slots).hasSize(2)
assertThat(iconList.slots[0].name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
assertThat(iconList.slots[1].name).isEqualTo(slotName)
@@ -221,7 +260,7 @@
/* number= */ 0,
"externalDescription",
)
- underTest.setIcon(slotName, startingExternalIcon)
+ underTest.setIconFromTile(slotName, startingExternalIcon)
// WHEN the internal icon is updated
underTest.setIcon(slotName, /* resourceId= */ 11, "newContentDescription")
@@ -243,7 +282,7 @@
/** Regression test for b/255428281. */
@Test
- fun internalAndExternalIconWithSameName_externalUpdatedIndependently() {
+ fun internalAndExternalIconWithSameName_fromTile_externalUpdatedIndependently() {
val slotName = "mute"
// Internal
@@ -259,7 +298,7 @@
/* number= */ 0,
"externalDescription",
)
- underTest.setIcon(slotName, startingExternalIcon)
+ underTest.setIconFromTile(slotName, startingExternalIcon)
// WHEN the external icon is updated
val newExternalIcon =
@@ -271,7 +310,54 @@
/* number= */ 0,
"newExternalDescription",
)
- underTest.setIcon(slotName, newExternalIcon)
+ underTest.setIconFromTile(slotName, newExternalIcon)
+
+ // THEN only the external slot gets the updates
+ val externalSlot = iconList.slots[0]
+ val externalHolder = externalSlot.getHolderForTag(TAG_PRIMARY)!!
+ assertThat(externalSlot.name).isEqualTo(slotName + EXTERNAL_SLOT_SUFFIX)
+ assertThat(externalHolder.icon!!.contentDescription).isEqualTo("newExternalDescription")
+ assertThat(externalHolder.icon!!.icon.resId).isEqualTo(21)
+
+ // And the internal slot has its own values
+ val internalSlot = iconList.slots[1]
+ val internalHolder = internalSlot.getHolderForTag(TAG_PRIMARY)!!
+ assertThat(internalSlot.name).isEqualTo(slotName)
+ assertThat(internalHolder.icon!!.contentDescription).isEqualTo("contentDescription")
+ assertThat(internalHolder.icon!!.icon.resId).isEqualTo(10)
+ }
+
+ /** Regression test for b/255428281. */
+ @Test
+ fun internalAndExternalIconWithSameName_fromCommandQueue_externalUpdatedIndependently() {
+ val slotName = "mute"
+
+ // Internal
+ underTest.setIcon(slotName, /* resourceId= */ 10, "contentDescription")
+
+ // External
+ val startingExternalIcon =
+ StatusBarIcon(
+ "external.package",
+ UserHandle.ALL,
+ /* iconId= */ 20,
+ /* iconLevel= */ 0,
+ /* number= */ 0,
+ "externalDescription",
+ )
+ commandQueueCallbacks.setIcon(slotName, startingExternalIcon)
+
+ // WHEN the external icon is updated
+ val newExternalIcon =
+ StatusBarIcon(
+ "external.package",
+ UserHandle.ALL,
+ /* iconId= */ 21,
+ /* iconLevel= */ 0,
+ /* number= */ 0,
+ "newExternalDescription",
+ )
+ commandQueueCallbacks.setIcon(slotName, newExternalIcon)
// THEN only the external slot gets the updates
val externalSlot = iconList.slots[0]
@@ -289,8 +375,16 @@
}
@Test
- fun externalSlot_alreadyEndsWithSuffix_suffixNotAddedTwice() {
- underTest.setIcon("myslot$EXTERNAL_SLOT_SUFFIX", createExternalIcon())
+ fun externalSlot_fromTile_alreadyEndsWithSuffix_suffixNotAddedTwice() {
+ underTest.setIconFromTile("myslot$EXTERNAL_SLOT_SUFFIX", createExternalIcon())
+
+ assertThat(iconList.slots).hasSize(1)
+ assertThat(iconList.slots[0].name).isEqualTo("myslot$EXTERNAL_SLOT_SUFFIX")
+ }
+
+ @Test
+ fun externalSlot_fromCommandQueue_alreadyEndsWithSuffix_suffixNotAddedTwice() {
+ commandQueueCallbacks.setIcon("myslot$EXTERNAL_SLOT_SUFFIX", createExternalIcon())
assertThat(iconList.slots).hasSize(1)
assertThat(iconList.slots[0].name).isEqualTo("myslot$EXTERNAL_SLOT_SUFFIX")
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
index 3146262..14aee4e 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/StatusBarKeyguardViewManagerTest.java
@@ -31,6 +31,7 @@
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.reset;
import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -58,6 +59,7 @@
import com.android.keyguard.KeyguardUpdateMonitor;
import com.android.keyguard.ViewMediatorCallback;
import com.android.systemui.SysuiTestCase;
+import com.android.systemui.biometrics.domain.interactor.UdfpsOverlayInteractor;
import com.android.systemui.dock.DockManager;
import com.android.systemui.dreams.DreamOverlayStateController;
import com.android.systemui.flags.FeatureFlags;
@@ -126,12 +128,14 @@
@Mock private PrimaryBouncerCallbackInteractor mPrimaryBouncerCallbackInteractor;
@Mock private PrimaryBouncerInteractor mPrimaryBouncerInteractor;
@Mock private AlternateBouncerInteractor mAlternateBouncerInteractor;
+ @Mock private UdfpsOverlayInteractor mUdfpsOverlayInteractor;
@Mock private BouncerView mBouncerView;
@Mock private BouncerViewDelegate mBouncerViewDelegate;
@Mock private OnBackAnimationCallback mBouncerViewDelegateBackCallback;
@Mock private NotificationShadeWindowView mNotificationShadeWindowView;
@Mock private WindowInsetsController mWindowInsetsController;
@Mock private TaskbarDelegate mTaskbarDelegate;
+ @Mock private StatusBarKeyguardViewManager.KeyguardViewManagerCallback mCallback;
private StatusBarKeyguardViewManager mStatusBarKeyguardViewManager;
private PrimaryBouncerCallbackInteractor.PrimaryBouncerExpansionCallback
@@ -150,7 +154,6 @@
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
- when(mCentralSurfaces.getBouncerContainer()).thenReturn(mContainer);
when(mContainer.findViewById(anyInt())).thenReturn(mKeyguardMessageArea);
when(mKeyguardMessageAreaFactory.create(any(KeyguardMessageArea.class)))
.thenReturn(mKeyguardMessageAreaController);
@@ -188,7 +191,8 @@
mPrimaryBouncerCallbackInteractor,
mPrimaryBouncerInteractor,
mBouncerView,
- mAlternateBouncerInteractor) {
+ mAlternateBouncerInteractor,
+ mUdfpsOverlayInteractor) {
@Override
public ViewRootImpl getViewRootImpl() {
return mViewRootImpl;
@@ -675,7 +679,8 @@
mPrimaryBouncerCallbackInteractor,
mPrimaryBouncerInteractor,
mBouncerView,
- mAlternateBouncerInteractor) {
+ mAlternateBouncerInteractor,
+ mUdfpsOverlayInteractor) {
@Override
public ViewRootImpl getViewRootImpl() {
return mViewRootImpl;
@@ -713,7 +718,115 @@
}
@Test
- public void testAlternateBouncerToShowPrimaryBouncer_updatesScrimControllerOnce() {
+ public void handleDispatchTouchEvent_alternateBouncerNotVisible() {
+ mStatusBarKeyguardViewManager.addCallback(mCallback);
+
+ // GIVEN the alternate bouncer is visible
+ when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
+
+ // THEN handleDispatchTouchEvent doesn't use the touches
+ assertFalse(mStatusBarKeyguardViewManager.dispatchTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ ));
+ assertFalse(mStatusBarKeyguardViewManager.dispatchTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
+ ));
+ assertFalse(mStatusBarKeyguardViewManager.dispatchTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
+ ));
+
+ // THEN the touch is not acted upon
+ verify(mCallback, never()).onTouch(any());
+ }
+
+ @Test
+ public void handleDispatchTouchEvent_shouldInterceptTouchAndHandleTouch() {
+ mStatusBarKeyguardViewManager.addCallback(mCallback);
+
+ // GIVEN the alternate bouncer is visible
+ when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
+
+ // GIVEN all touches are NOT the udfps overlay
+ when(mUdfpsOverlayInteractor.isTouchWithinUdfpsArea(any())).thenReturn(false);
+
+ // THEN handleDispatchTouchEvent eats/intercepts the touches so motion events aren't sent
+ // to its child views (handleDispatchTouchEvent returns true)
+ assertTrue(mStatusBarKeyguardViewManager.dispatchTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ ));
+ assertTrue(mStatusBarKeyguardViewManager.dispatchTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
+ ));
+ assertTrue(mStatusBarKeyguardViewManager.dispatchTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
+ ));
+
+ // THEN the touch is acted upon once for each dispatchTOuchEvent call
+ verify(mCallback, times(3)).onTouch(any());
+ }
+
+ @Test
+ public void handleDispatchTouchEvent_shouldInterceptTouchButNotHandleTouch() {
+ mStatusBarKeyguardViewManager.addCallback(mCallback);
+
+ // GIVEN the alternate bouncer is visible
+ when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
+
+ // GIVEN all touches are within the udfps overlay
+ when(mUdfpsOverlayInteractor.isTouchWithinUdfpsArea(any())).thenReturn(true);
+
+ // THEN handleDispatchTouchEvent eats/intercepts the touches so motion events aren't sent
+ // to its child views (handleDispatchTouchEvent returns true)
+ assertTrue(mStatusBarKeyguardViewManager.dispatchTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ ));
+ assertTrue(mStatusBarKeyguardViewManager.dispatchTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
+ ));
+ assertTrue(mStatusBarKeyguardViewManager.dispatchTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
+ ));
+
+ // THEN the touch is NOT acted upon at the moment
+ verify(mCallback, never()).onTouch(any());
+ }
+
+ @Test
+ public void shouldInterceptTouch_alternateBouncerNotVisible() {
+ // GIVEN the alternate bouncer is not visible
+ when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(false);
+
+ // THEN no motion events are intercepted
+ assertFalse(mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ ));
+ assertFalse(mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
+ ));
+ assertFalse(mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
+ ));
+ }
+
+ @Test
+ public void shouldInterceptTouch_alternateBouncerVisible() {
+ // GIVEN the alternate bouncer is visible
+ when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
+
+ // THEN all motion events are intercepted
+ assertTrue(mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0)
+ ));
+ assertTrue(mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0)
+ ));
+ assertTrue(mStatusBarKeyguardViewManager.shouldInterceptTouchEvent(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_MOVE, 0f, 0f, 0)
+ ));
+ }
+
+ @Test
+ public void alternateBouncerToShowPrimaryBouncer_updatesScrimControllerOnce() {
// GIVEN the alternate bouncer has shown and calls to hide() will result in successfully
// hiding it
when(mAlternateBouncerInteractor.hide()).thenReturn(true);
@@ -729,30 +842,67 @@
}
@Test
- public void testAlternateBouncerOnTouch_actionDown_doesNotHandleTouch() {
+ public void alternateBouncerOnTouch_actionDownThenUp_noMinTimeShown_noHideAltBouncer() {
+ reset(mAlternateBouncerInteractor);
+
// GIVEN the alternate bouncer has shown for a minimum amount of time
- when(mAlternateBouncerInteractor.hasAlternateBouncerShownWithMinTime()).thenReturn(true);
+ when(mAlternateBouncerInteractor.hasAlternateBouncerShownWithMinTime()).thenReturn(false);
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
+ when(mUdfpsOverlayInteractor.isTouchWithinUdfpsArea(any())).thenReturn(false);
- // WHEN ACTION_DOWN touch event comes
- boolean touchHandled = mStatusBarKeyguardViewManager.onTouch(
+ // WHEN ACTION_DOWN and ACTION_UP touch event comes
+ boolean touchHandledDown = mStatusBarKeyguardViewManager.onTouch(
MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0));
+ when(mAlternateBouncerInteractor.getReceivedDownTouch()).thenReturn(true);
+ boolean touchHandledUp = mStatusBarKeyguardViewManager.onTouch(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0));
- // THEN the touch is not handled
- assertFalse(touchHandled);
+ // THEN the touches are handled (doesn't let touches through to underlying views)
+ assertTrue(touchHandledDown);
+ assertTrue(touchHandledUp);
+
+ // THEN alternate bouncer does NOT attempt to hide since min showing time wasn't met
+ verify(mAlternateBouncerInteractor, never()).hide();
}
@Test
- public void testAlternateBouncerOnTouch_actionUp_handlesTouch() {
+ public void alternateBouncerOnTouch_actionDownThenUp_handlesTouch_hidesAltBouncer() {
+ reset(mAlternateBouncerInteractor);
+
// GIVEN the alternate bouncer has shown for a minimum amount of time
when(mAlternateBouncerInteractor.hasAlternateBouncerShownWithMinTime()).thenReturn(true);
when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
+ when(mUdfpsOverlayInteractor.isTouchWithinUdfpsArea(any())).thenReturn(false);
- // WHEN ACTION_UP touch event comes
- boolean touchHandled = mStatusBarKeyguardViewManager.onTouch(
+ // WHEN ACTION_DOWN and ACTION_UP touch event comes
+ boolean touchHandledDown = mStatusBarKeyguardViewManager.onTouch(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_DOWN, 0f, 0f, 0));
+ when(mAlternateBouncerInteractor.getReceivedDownTouch()).thenReturn(true);
+ boolean touchHandledUp = mStatusBarKeyguardViewManager.onTouch(
MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0));
- // THEN the touch is handled
- assertTrue(touchHandled);
+ // THEN the touches are handled
+ assertTrue(touchHandledDown);
+ assertTrue(touchHandledUp);
+
+ // THEN alternate bouncer attempts to hide
+ verify(mAlternateBouncerInteractor).hide();
+ }
+
+ @Test
+ public void alternateBouncerOnTouch_actionUp_doesNotHideAlternateBouncer() {
+ reset(mAlternateBouncerInteractor);
+
+ // GIVEN the alternate bouncer has shown for a minimum amount of time
+ when(mAlternateBouncerInteractor.hasAlternateBouncerShownWithMinTime()).thenReturn(true);
+ when(mAlternateBouncerInteractor.isVisibleState()).thenReturn(true);
+ when(mUdfpsOverlayInteractor.isTouchWithinUdfpsArea(any())).thenReturn(false);
+
+ // WHEN only ACTION_UP touch event comes
+ mStatusBarKeyguardViewManager.onTouch(
+ MotionEvent.obtain(0L, 0L, MotionEvent.ACTION_UP, 0f, 0f, 0));
+
+ // THEN the alternateBouncer doesn't hide
+ verify(mAlternateBouncerInteractor, never()).hide();
}
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
index 64545b1..be0c83f 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/phone/fragment/CollapsedStatusBarFragmentTest.java
@@ -294,6 +294,13 @@
}
@Test
+ public void userChip_defaultVisibilityIsGone() {
+ CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+
+ assertEquals(View.GONE, getUserChipView().getVisibility());
+ }
+
+ @Test
public void disable_noOngoingCall_chipHidden() {
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
@@ -333,6 +340,19 @@
}
@Test
+ public void disable_hasOngoingCallButAlsoHun_chipHidden() {
+ CollapsedStatusBarFragment fragment = resumeAndGetFragment();
+
+ when(mOngoingCallController.hasOngoingCall()).thenReturn(true);
+ when(mHeadsUpAppearanceController.shouldBeVisible()).thenReturn(true);
+
+ fragment.disable(DEFAULT_DISPLAY, 0, 0, false);
+
+ assertEquals(View.GONE,
+ mFragment.getView().findViewById(R.id.ongoing_call_chip).getVisibility());
+ }
+
+ @Test
public void disable_ongoingCallEnded_chipHidden() {
CollapsedStatusBarFragment fragment = resumeAndGetFragment();
@@ -558,6 +578,10 @@
return (CollapsedStatusBarFragment) mFragment;
}
+ private View getUserChipView() {
+ return mFragment.getView().findViewById(R.id.user_switcher_container);
+ }
+
private View getClockView() {
return mFragment.getView().findViewById(R.id.clock);
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
index 542b688..934e1c6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionRepositoryTest.kt
@@ -25,7 +25,6 @@
import android.telephony.TelephonyCallback
import android.telephony.TelephonyCallback.DataActivityListener
import android.telephony.TelephonyCallback.ServiceStateListener
-import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_LTE_CA
import android.telephony.TelephonyDisplayInfo.OVERRIDE_NETWORK_TYPE_NONE
import android.telephony.TelephonyManager
@@ -68,6 +67,7 @@
import com.android.systemui.statusbar.pipeline.mobile.data.repository.FakeMobileConnectionsRepository
import com.android.systemui.statusbar.pipeline.mobile.data.repository.MobileConnectionRepository.Companion.DEFAULT_NUM_LEVELS
import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.signalStrength
+import com.android.systemui.statusbar.pipeline.mobile.data.repository.prod.MobileTelephonyHelpers.telephonyDisplayInfo
import com.android.systemui.statusbar.pipeline.mobile.util.FakeMobileMappingsProxy
import com.android.systemui.statusbar.pipeline.shared.data.model.DataActivityModel
import com.android.systemui.statusbar.pipeline.shared.data.model.toMobileDataActivityModel
@@ -392,13 +392,17 @@
val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this)
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
- val type = NETWORK_TYPE_UNKNOWN
- val expected = UnknownNetworkType
- val ti = mock<TelephonyDisplayInfo>().also { whenever(it.networkType).thenReturn(type) }
+ val ti =
+ telephonyDisplayInfo(
+ networkType = NETWORK_TYPE_UNKNOWN,
+ overrideNetworkType = NETWORK_TYPE_UNKNOWN,
+ )
+
callback.onDisplayInfoChanged(ti)
+ val expected = UnknownNetworkType
assertThat(latest).isEqualTo(expected)
- assertThat(latest!!.lookupKey).isEqualTo(MobileMappings.toIconKey(type))
+ assertThat(latest!!.lookupKey).isEqualTo(MobileMappings.toIconKey(NETWORK_TYPE_UNKNOWN))
job.cancel()
}
@@ -412,14 +416,10 @@
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
val overrideType = OVERRIDE_NETWORK_TYPE_NONE
val type = NETWORK_TYPE_LTE
- val expected = DefaultNetworkType(mobileMappings.toIconKey(type))
- val ti =
- mock<TelephonyDisplayInfo>().also {
- whenever(it.overrideNetworkType).thenReturn(overrideType)
- whenever(it.networkType).thenReturn(type)
- }
+ val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = overrideType)
callback.onDisplayInfoChanged(ti)
+ val expected = DefaultNetworkType(mobileMappings.toIconKey(type))
assertThat(latest).isEqualTo(expected)
job.cancel()
@@ -433,14 +433,10 @@
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
val type = OVERRIDE_NETWORK_TYPE_LTE_CA
- val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
- val ti =
- mock<TelephonyDisplayInfo>().also {
- whenever(it.networkType).thenReturn(type)
- whenever(it.overrideNetworkType).thenReturn(type)
- }
+ val ti = telephonyDisplayInfo(networkType = type, overrideNetworkType = type)
callback.onDisplayInfoChanged(ti)
+ val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
assertThat(latest).isEqualTo(expected)
job.cancel()
@@ -455,14 +451,10 @@
val callback = getTelephonyCallbackForType<TelephonyCallback.DisplayInfoListener>()
val unknown = NETWORK_TYPE_UNKNOWN
val type = OVERRIDE_NETWORK_TYPE_LTE_CA
- val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
- val ti =
- mock<TelephonyDisplayInfo>().also {
- whenever(it.networkType).thenReturn(unknown)
- whenever(it.overrideNetworkType).thenReturn(type)
- }
+ val ti = telephonyDisplayInfo(unknown, type)
callback.onDisplayInfoChanged(ti)
+ val expected = OverrideNetworkType(mobileMappings.toIconKeyOverride(type))
assertThat(latest).isEqualTo(expected)
job.cancel()
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
index bbf04ed2..9da9ff7 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileConnectionTelephonySmokeTests.kt
@@ -64,10 +64,14 @@
*
* Kind of like an interaction test case build just for [TelephonyCallback]
*
- * The list of telephony callbacks we use is: [TelephonyCallback.CarrierNetworkListener]
- * [TelephonyCallback.DataActivityListener] [TelephonyCallback.DataConnectionStateListener]
- * [TelephonyCallback.DataEnabledListener] [TelephonyCallback.DisplayInfoListener]
- * [TelephonyCallback.ServiceStateListener] [TelephonyCallback.SignalStrengthsListener]
+ * The list of telephony callbacks we use is:
+ * - [TelephonyCallback.CarrierNetworkListener]
+ * - [TelephonyCallback.DataActivityListener]
+ * - [TelephonyCallback.DataConnectionStateListener]
+ * - [TelephonyCallback.DataEnabledListener]
+ * - [TelephonyCallback.DisplayInfoListener]
+ * - [TelephonyCallback.ServiceStateListener]
+ * - [TelephonyCallback.SignalStrengthsListener]
*
* Because each of these callbacks comes in on the same callbackFlow, collecting on a field backed
* by only a single callback can immediately create backpressure on the other fields related to a
@@ -201,7 +205,6 @@
200 /* unused */
)
- // Send a bunch of events that we don't care about, to overrun the replay buffer
flipActivity(100, activityCallback)
val connectionJob = underTest.dataConnectionState.onEach { latest = it }.launchIn(this)
@@ -225,7 +228,6 @@
enabledCallback.onDataEnabledChanged(true, 1 /* unused */)
- // Send a bunch of events that we don't care about, to overrun the replay buffer
flipActivity(100, activityCallback)
val job = underTest.dataEnabled.onEach { latest = it }.launchIn(this)
@@ -252,7 +254,6 @@
val ti = mock<TelephonyDisplayInfo>().also { whenever(it.networkType).thenReturn(type) }
displayInfoCallback.onDisplayInfoChanged(ti)
- // Send a bunch of events that we don't care about, to overrun the replay buffer
flipActivity(100, activityCallback)
val job = underTest.resolvedNetworkType.onEach { latest = it }.launchIn(this)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
index d07b96f..cf815c2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/pipeline/mobile/data/repository/prod/MobileTelephonyHelpers.kt
@@ -19,6 +19,7 @@
import android.telephony.CellSignalStrengthCdma
import android.telephony.SignalStrength
import android.telephony.TelephonyCallback
+import android.telephony.TelephonyDisplayInfo
import android.telephony.TelephonyManager
import com.android.systemui.util.mockito.any
import com.android.systemui.util.mockito.argumentCaptor
@@ -48,6 +49,12 @@
return signalStrength
}
+ fun telephonyDisplayInfo(networkType: Int, overrideNetworkType: Int) =
+ mock<TelephonyDisplayInfo>().also {
+ whenever(it.networkType).thenReturn(networkType)
+ whenever(it.overrideNetworkType).thenReturn(overrideNetworkType)
+ }
+
inline fun <reified T> getTelephonyCallbackForType(mockTelephonyManager: TelephonyManager): T {
val cbs = getTelephonyCallbacks(mockTelephonyManager).filterIsInstance<T>()
assertThat(cbs.size).isEqualTo(1)
diff --git a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java
index 481d453..c8f28bc 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/statusbar/policy/DeviceStateRotationLockSettingControllerTest.java
@@ -55,6 +55,9 @@
public class DeviceStateRotationLockSettingControllerTest extends SysuiTestCase {
private static final String[] DEFAULT_SETTINGS = new String[]{"0:1", "2:0:1", "1:2"};
+ private static final int[] DEFAULT_FOLDED_STATES = new int[]{0};
+ private static final int[] DEFAULT_HALF_FOLDED_STATES = new int[]{2};
+ private static final int[] DEFAULT_UNFOLDED_STATES = new int[]{1};
@Mock private DeviceStateManager mDeviceStateManager;
@Mock private DeviceStateRotationLockSettingControllerLogger mLogger;
@@ -73,6 +76,9 @@
MockitoAnnotations.initMocks(/* testClass= */ this);
TestableResources resources = mContext.getOrCreateTestableResources();
resources.addOverride(R.array.config_perDeviceStateRotationLockDefaults, DEFAULT_SETTINGS);
+ resources.addOverride(R.array.config_foldedDeviceStates, DEFAULT_FOLDED_STATES);
+ resources.addOverride(R.array.config_halfFoldedDeviceStates, DEFAULT_HALF_FOLDED_STATES);
+ resources.addOverride(R.array.config_openDeviceStates, DEFAULT_UNFOLDED_STATES);
ArgumentCaptor<DeviceStateManager.DeviceStateCallback> deviceStateCallbackArgumentCaptor =
ArgumentCaptor.forClass(DeviceStateManager.DeviceStateCallback.class);
diff --git a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
index 4525ad2..17f8ec2 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/stylus/StylusManagerTest.kt
@@ -507,11 +507,29 @@
stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
verify(uiEventLogger, times(1))
- .logWithInstanceId(
+ .logWithInstanceIdAndPosition(
StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_FIRST_DETECTED,
0,
null,
- InstanceId.fakeInstanceId(instanceIdSequenceFake.lastInstanceId)
+ InstanceId.fakeInstanceId(instanceIdSequenceFake.lastInstanceId),
+ 0,
+ )
+ }
+
+ @Test
+ fun onBatteryStateChanged_batteryPresent_btStylusPresent_logsSessionStart() {
+ whenever(batteryState.isPresent).thenReturn(true)
+ stylusManager.onInputDeviceAdded(BT_STYLUS_DEVICE_ID)
+
+ stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
+
+ verify(uiEventLogger, times(1))
+ .logWithInstanceIdAndPosition(
+ StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_FIRST_DETECTED,
+ 0,
+ null,
+ InstanceId.fakeInstanceId(instanceIdSequenceFake.lastInstanceId),
+ 1,
)
}
@@ -545,19 +563,21 @@
stylusManager.onBatteryStateChanged(STYLUS_DEVICE_ID, 1, batteryState)
verify(uiEventLogger, times(1))
- .logWithInstanceId(
+ .logWithInstanceIdAndPosition(
StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_FIRST_DETECTED,
0,
null,
- instanceId
+ instanceId,
+ 0
)
verify(uiEventLogger, times(1))
- .logWithInstanceId(
+ .logWithInstanceIdAndPosition(
StylusUiEvent.USI_STYLUS_BATTERY_PRESENCE_REMOVED,
0,
null,
- instanceId
+ instanceId,
+ 0
)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
index 586bdc6..6e24941 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/temporarydisplay/chipbar/ChipbarCoordinatorTest.kt
@@ -685,7 +685,7 @@
allowSwipeToDismiss: Boolean = false,
): ChipbarInfo {
return ChipbarInfo(
- TintedIcon(startIcon, tintAttr = null),
+ TintedIcon(startIcon, tint = null),
text,
endItem,
vibrationEffect,
diff --git a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
index 0413d92..9fe2f56 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
+++ b/packages/SystemUI/tests/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProviderTest.kt
@@ -40,7 +40,7 @@
@Before
fun setUp() {
- progressProvider = PhysicsBasedUnfoldTransitionProgressProvider(foldStateProvider)
+ progressProvider = PhysicsBasedUnfoldTransitionProgressProvider(context, foldStateProvider)
progressProvider.addCallback(listener)
}
diff --git a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/PostureDependentProximitySensorTest.java b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/PostureDependentProximitySensorTest.java
index 075f393..84129be 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/util/sensors/PostureDependentProximitySensorTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/util/sensors/PostureDependentProximitySensorTest.java
@@ -16,10 +16,16 @@
package com.android.systemui.util.sensors;
+import static com.android.systemui.statusbar.policy.DevicePostureController.DEVICE_POSTURE_CLOSED;
+
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import android.content.res.Resources;
+import android.hardware.Sensor;
import android.testing.AndroidTestingRunner;
import android.testing.TestableLooper;
@@ -46,28 +52,52 @@
@Mock private Resources mResources;
@Mock private DevicePostureController mDevicePostureController;
@Mock private AsyncSensorManager mSensorManager;
+ @Mock private Sensor mMockedPrimaryProxSensor;
@Captor private ArgumentCaptor<DevicePostureController.Callback> mPostureListenerCaptor =
ArgumentCaptor.forClass(DevicePostureController.Callback.class);
private DevicePostureController.Callback mPostureListener;
- private PostureDependentProximitySensor mProximitySensor;
- private FakeExecutor mFakeExecutor = new FakeExecutor(new FakeSystemClock());
+ private PostureDependentProximitySensor mPostureDependentProximitySensor;
+ private ThresholdSensor[] mPrimaryProxSensors;
+ private ThresholdSensor[] mSecondaryProxSensors;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
allowTestableLooperAsMainThread();
- mProximitySensor = new PostureDependentProximitySensor(
- new ThresholdSensor[DevicePostureController.SUPPORTED_POSTURES_SIZE],
- new ThresholdSensor[DevicePostureController.SUPPORTED_POSTURES_SIZE],
- mFakeExecutor,
+ setupProximitySensors(DEVICE_POSTURE_CLOSED);
+ mPostureDependentProximitySensor = new PostureDependentProximitySensor(
+ mPrimaryProxSensors,
+ mSecondaryProxSensors,
+ new FakeExecutor(new FakeSystemClock()),
new FakeExecution(),
mDevicePostureController
);
}
+ /**
+ * Support a proximity sensor only for the given devicePosture for the primary sensor.
+ * Otherwise, all other postures don't support prox.
+ */
+ private void setupProximitySensors(
+ @DevicePostureController.DevicePostureInt int proxExistsForPosture) {
+ final ThresholdSensorImpl.Builder sensorBuilder = new ThresholdSensorImpl.BuilderFactory(
+ mResources, mSensorManager, new FakeExecution()).createBuilder();
+
+ mPrimaryProxSensors = new ThresholdSensor[DevicePostureController.SUPPORTED_POSTURES_SIZE];
+ mSecondaryProxSensors =
+ new ThresholdSensor[DevicePostureController.SUPPORTED_POSTURES_SIZE];
+ for (int i = 0; i < DevicePostureController.SUPPORTED_POSTURES_SIZE; i++) {
+ mPrimaryProxSensors[i] = sensorBuilder.setSensor(null).setThresholdValue(0).build();
+ mSecondaryProxSensors[i] = sensorBuilder.setSensor(null).setThresholdValue(0).build();
+ }
+
+ mPrimaryProxSensors[proxExistsForPosture] = sensorBuilder
+ .setSensor(mMockedPrimaryProxSensor).setThresholdValue(5).build();
+ }
+
@Test
public void testPostureChangeListenerAdded() {
capturePostureListener();
@@ -83,30 +113,59 @@
// THEN device posture is updated to DEVICE_POSTURE_OPENED
assertEquals(DevicePostureController.DEVICE_POSTURE_OPENED,
- mProximitySensor.mDevicePosture);
+ mPostureDependentProximitySensor.mDevicePosture);
// WHEN the posture changes to DEVICE_POSTURE_CLOSED
- mPostureListener.onPostureChanged(DevicePostureController.DEVICE_POSTURE_CLOSED);
+ mPostureListener.onPostureChanged(DEVICE_POSTURE_CLOSED);
// THEN device posture is updated to DEVICE_POSTURE_CLOSED
- assertEquals(DevicePostureController.DEVICE_POSTURE_CLOSED,
- mProximitySensor.mDevicePosture);
+ assertEquals(DEVICE_POSTURE_CLOSED,
+ mPostureDependentProximitySensor.mDevicePosture);
// WHEN the posture changes to DEVICE_POSTURE_FLIPPED
mPostureListener.onPostureChanged(DevicePostureController.DEVICE_POSTURE_FLIPPED);
// THEN device posture is updated to DEVICE_POSTURE_FLIPPED
assertEquals(DevicePostureController.DEVICE_POSTURE_FLIPPED,
- mProximitySensor.mDevicePosture);
+ mPostureDependentProximitySensor.mDevicePosture);
// WHEN the posture changes to DEVICE_POSTURE_HALF_OPENED
mPostureListener.onPostureChanged(DevicePostureController.DEVICE_POSTURE_HALF_OPENED);
// THEN device posture is updated to DEVICE_POSTURE_HALF_OPENED
assertEquals(DevicePostureController.DEVICE_POSTURE_HALF_OPENED,
- mProximitySensor.mDevicePosture);
+ mPostureDependentProximitySensor.mDevicePosture);
}
+ @Test
+ public void proxSensorRegisters_proxSensorValid() {
+ // GIVEN posture that supports a valid posture with a prox sensor
+ capturePostureListener();
+ mPostureListener.onPostureChanged(DEVICE_POSTURE_CLOSED);
+
+ // WHEN a listener registers
+ mPostureDependentProximitySensor.register(mock(ThresholdSensor.Listener.class));
+
+ // THEN PostureDependentProximitySensor is registered
+ assertTrue(mPostureDependentProximitySensor.isRegistered());
+ }
+
+ @Test
+ public void proxSensorReregisters_postureChangesAndNewlySupportsProx() {
+ // GIVEN there's a registered listener but posture doesn't support prox
+ assertFalse(mPostureDependentProximitySensor.isRegistered());
+ mPostureDependentProximitySensor.register(mock(ThresholdSensor.Listener.class));
+ assertFalse(mPostureDependentProximitySensor.isRegistered());
+
+ // WHEN posture that supports a valid posture with a prox sensor
+ capturePostureListener();
+ mPostureListener.onPostureChanged(DEVICE_POSTURE_CLOSED);
+
+ // THEN PostureDependentProximitySensor is registered
+ assertTrue(mPostureDependentProximitySensor.isRegistered());
+ }
+
+
private void capturePostureListener() {
verify(mDevicePostureController).addCallback(mPostureListenerCaptor.capture());
mPostureListener = mPostureListenerCaptor.getValue();
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java b/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
index b1950ea..692af6a 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wallet/ui/WalletScreenControllerTest.java
@@ -22,6 +22,9 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyBoolean;
+import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@@ -63,6 +66,7 @@
import org.mockito.MockitoAnnotations;
import java.util.Collections;
+import java.util.List;
@RunWith(AndroidTestingRunner.class)
@TestableLooper.RunWithLooper
@@ -99,6 +103,8 @@
ArgumentCaptor<PendingIntent> mIntentCaptor;
@Captor
ArgumentCaptor<QuickAccessWalletClient.OnWalletCardsRetrievedCallback> mCallbackCaptor;
+ @Captor
+ ArgumentCaptor<List<WalletCardViewInfo>> mPaymentCardDataCaptor;
private WalletScreenController mController;
private TestableLooper mTestableLooper;
@@ -107,7 +113,7 @@
MockitoAnnotations.initMocks(this);
mTestableLooper = TestableLooper.get(this);
when(mUserTracker.getUserContext()).thenReturn(mContext);
- mWalletView = new WalletView(mContext);
+ mWalletView = spy(new WalletView(mContext));
mWalletView.getCardCarousel().setExpectedViewWidth(CARD_CAROUSEL_WIDTH);
when(mWalletClient.getLogo()).thenReturn(mWalletLogo);
when(mWalletClient.getShortcutLongLabel()).thenReturn(SHORTCUT_LONG_LABEL);
@@ -430,6 +436,41 @@
assertEquals(GONE, mWalletView.getVisibility());
}
+ @Test
+ public void onWalletCardsRetrieved_cardDataAllUnknown_showsAllCards() {
+ List<WalletCard> walletCardList = List.of(
+ createWalletCardWithType(mContext, WalletCard.CARD_TYPE_UNKNOWN),
+ createWalletCardWithType(mContext, WalletCard.CARD_TYPE_UNKNOWN),
+ createWalletCardWithType(mContext, WalletCard.CARD_TYPE_UNKNOWN));
+ GetWalletCardsResponse response = new GetWalletCardsResponse(walletCardList, 0);
+ mController.onWalletCardsRetrieved(response);
+ mTestableLooper.processAllMessages();
+
+ verify(mWalletView).showCardCarousel(mPaymentCardDataCaptor.capture(), anyInt(),
+ anyBoolean(),
+ anyBoolean());
+ List<WalletCardViewInfo> paymentCardData = mPaymentCardDataCaptor.getValue();
+ assertEquals(paymentCardData.size(), walletCardList.size());
+ }
+
+ @Test
+ public void onWalletCardsRetrieved_cardDataDifferentTypes_onlyShowsPayment() {
+ List<WalletCard> walletCardList = List.of(createWalletCardWithType(mContext,
+ WalletCard.CARD_TYPE_UNKNOWN),
+ createWalletCardWithType(mContext, WalletCard.CARD_TYPE_PAYMENT),
+ createWalletCardWithType(mContext, WalletCard.CARD_TYPE_NON_PAYMENT)
+ );
+ GetWalletCardsResponse response = new GetWalletCardsResponse(walletCardList, 0);
+ mController.onWalletCardsRetrieved(response);
+ mTestableLooper.processAllMessages();
+
+ verify(mWalletView).showCardCarousel(mPaymentCardDataCaptor.capture(), anyInt(),
+ anyBoolean(),
+ anyBoolean());
+ List<WalletCardViewInfo> paymentCardData = mPaymentCardDataCaptor.getValue();
+ assertEquals(paymentCardData.size(), 1);
+ }
+
private WalletCard createNonActiveWalletCard(Context context) {
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE);
@@ -457,6 +498,15 @@
.build();
}
+ private WalletCard createWalletCardWithType(Context context, int cardType) {
+ PendingIntent pendingIntent =
+ PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE);
+ return new WalletCard.Builder(CARD_ID_1, cardType, createIcon(), "•••• 1234", pendingIntent)
+ .setCardIcon(createIcon())
+ .setCardLabel("Hold to reader")
+ .build();
+ }
+
private WalletCard createCrazyWalletCard(Context context, boolean hasLabel) {
PendingIntent pendingIntent =
PendingIntent.getActivity(context, 0, mWalletIntent, PendingIntent.FLAG_IMMUTABLE);
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 e185922..cc3b4ab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/BubblesTest.java
@@ -284,6 +284,8 @@
private ShadeWindowLogger mShadeWindowLogger;
@Mock
private NotifPipelineFlags mNotifPipelineFlags;
+ @Mock
+ private Icon mAppBubbleIcon;
private TestableBubblePositioner mPositioner;
@@ -293,6 +295,8 @@
private FakeDisplayTracker mDisplayTracker = new FakeDisplayTracker(mContext);
+ private UserHandle mUser0;
+
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
@@ -301,6 +305,8 @@
// For the purposes of this test, just run everything synchronously
ShellExecutor syncExecutor = new SyncExecutor();
+ mUser0 = createUserHandle(/* userId= */ 0);
+
when(mColorExtractor.getNeutralColors()).thenReturn(mGradientColors);
when(mNotificationShadeWindowView.getViewTreeObserver())
.thenReturn(mock(ViewTreeObserver.class));
@@ -339,7 +345,6 @@
TestableNotificationInterruptStateProviderImpl interruptionStateProvider =
new TestableNotificationInterruptStateProviderImpl(mContext.getContentResolver(),
mock(PowerManager.class),
- mock(IDreamManager.class),
mock(AmbientDisplayConfiguration.class),
mock(StatusBarStateController.class),
mock(KeyguardStateController.class),
@@ -1242,6 +1247,24 @@
// Show the menu
stackView.showManageMenu(true);
assertSysuiStates(true /* stackExpanded */, true /* mangeMenuExpanded */);
+ assertTrue(stackView.isManageMenuSettingsVisible());
+ }
+
+ @Test
+ public void testShowManageMenuChangesSysuiState_appBubble() {
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
+ assertTrue(mBubbleController.hasBubbles());
+
+ // Expand the stack
+ BubbleStackView stackView = mBubbleController.getStackView();
+ mBubbleData.setExpanded(true);
+ assertStackExpanded();
+ assertSysuiStates(true /* stackExpanded */, false /* mangeMenuExpanded */);
+
+ // Show the menu
+ stackView.showManageMenu(true);
+ assertSysuiStates(true /* stackExpanded */, true /* mangeMenuExpanded */);
+ assertFalse(stackView.isManageMenuSettingsVisible());
}
@Test
@@ -1650,7 +1673,7 @@
assertThat(mBubbleController.isStackExpanded()).isFalse();
assertThat(mBubbleData.getBubbleInStackWithKey(KEY_APP_BUBBLE)).isNull();
- mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
verify(mBubbleController).inflateAndAdd(any(Bubble.class), /* suppressFlyout= */ eq(true),
/* showInShade= */ eq(false));
@@ -1660,13 +1683,13 @@
@Test
public void testShowOrHideAppBubble_expandIfCollapsed() {
- mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleController.collapseStack();
assertThat(mBubbleController.isStackExpanded()).isFalse();
// Calling this while collapsed will expand the app bubble
- mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
assertThat(mBubbleController.isStackExpanded()).isTrue();
@@ -1675,27 +1698,46 @@
@Test
public void testShowOrHideAppBubble_collapseIfSelected() {
- mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
assertThat(mBubbleController.isStackExpanded()).isTrue();
// Calling this while the app bubble is expanded should collapse the stack
- mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
assertThat(mBubbleController.isStackExpanded()).isFalse();
assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
+ assertThat(mBubbleData.getBubbles().get(0).getUser()).isEqualTo(mUser0);
+ }
+
+ @Test
+ public void testShowOrHideAppBubbleWithNonPrimaryUser_bubbleCollapsedWithExpectedUser() {
+ UserHandle user10 = createUserHandle(/* userId = */ 10);
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, user10, mAppBubbleIcon);
+ assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+ assertThat(mBubbleController.isStackExpanded()).isTrue();
+ assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
+ assertThat(mBubbleData.getBubbles().get(0).getUser()).isEqualTo(user10);
+
+ // Calling this while the app bubble is expanded should collapse the stack
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, user10, mAppBubbleIcon);
+
+ assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
+ assertThat(mBubbleController.isStackExpanded()).isFalse();
+ assertThat(mBubbleData.getBubbles().size()).isEqualTo(1);
+ assertThat(mBubbleData.getBubbles().get(0).getUser()).isEqualTo(user10);
}
@Test
public void testShowOrHideAppBubble_selectIfNotSelected() {
- mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
mBubbleController.updateBubble(mBubbleEntry);
mBubbleController.expandStackAndSelectBubble(mBubbleEntry);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(mBubbleEntry.getKey());
assertThat(mBubbleController.isStackExpanded()).isTrue();
- mBubbleController.showOrHideAppBubble(mAppBubbleIntent);
+ mBubbleController.showOrHideAppBubble(mAppBubbleIntent, mUser0, mAppBubbleIcon);
assertThat(mBubbleData.getSelectedBubble().getKey()).isEqualTo(KEY_APP_BUBBLE);
assertThat(mBubbleController.isStackExpanded()).isTrue();
assertThat(mBubbleData.getBubbles().size()).isEqualTo(2);
@@ -1830,6 +1872,12 @@
mBubbleController.onUserChanged(userId);
}
+ private UserHandle createUserHandle(int userId) {
+ UserHandle user = mock(UserHandle.class);
+ when(user.getIdentifier()).thenReturn(userId);
+ return user;
+ }
+
/**
* Asserts that the bubble stack is expanded and also validates the cached state is updated.
*/
diff --git a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
index ceee0bc..4e14bbf6 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/wmshell/TestableNotificationInterruptStateProviderImpl.java
@@ -20,7 +20,6 @@
import android.hardware.display.AmbientDisplayConfiguration;
import android.os.Handler;
import android.os.PowerManager;
-import android.service.dreams.IDreamManager;
import com.android.internal.logging.UiEventLogger;
import com.android.systemui.plugins.statusbar.StatusBarStateController;
@@ -39,7 +38,6 @@
TestableNotificationInterruptStateProviderImpl(
ContentResolver contentResolver,
PowerManager powerManager,
- IDreamManager dreamManager,
AmbientDisplayConfiguration ambientDisplayConfiguration,
StatusBarStateController statusBarStateController,
KeyguardStateController keyguardStateController,
@@ -53,7 +51,6 @@
UserTracker userTracker) {
super(contentResolver,
powerManager,
- dreamManager,
ambientDisplayConfiguration,
batteryController,
statusBarStateController,
diff --git a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
index 926c6c5..c664c99 100644
--- a/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
+++ b/packages/SystemUI/tests/utils/src/com/android/systemui/utils/leaks/FakeStatusBarIconController.java
@@ -47,7 +47,12 @@
}
@Override
- public void setExternalIcon(String slot) {
+ public void setIconFromTile(String slot, StatusBarIcon icon) {
+
+ }
+
+ @Override
+ public void removeIconForTile(String slot) {
}
@@ -57,11 +62,6 @@
}
@Override
- public void setIcon(String slot, StatusBarIcon icon) {
-
- }
-
- @Override
public void setWifiIcon(String slot, WifiIconState state) {
}
@@ -98,10 +98,6 @@
}
@Override
- public void removeAllIconsForExternalSlot(String slot) {
- }
-
- @Override
public void setIconAccessibilityLiveRegion(String slot, int mode) {
}
diff --git a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
index 28e4936..f8f168b 100644
--- a/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
+++ b/packages/SystemUI/unfold/src/com/android/systemui/unfold/progress/PhysicsBasedUnfoldTransitionProgressProvider.kt
@@ -15,8 +15,15 @@
*/
package com.android.systemui.unfold.progress
+import android.animation.Animator
+import android.animation.AnimatorListenerAdapter
+import android.animation.ObjectAnimator
+import android.animation.ValueAnimator
+import android.content.Context
import android.os.Trace
+import android.util.FloatProperty
import android.util.Log
+import android.view.animation.AnimationUtils.loadInterpolator
import androidx.dynamicanimation.animation.DynamicAnimation
import androidx.dynamicanimation.animation.FloatPropertyCompat
import androidx.dynamicanimation.animation.SpringAnimation
@@ -34,14 +41,22 @@
import javax.inject.Inject
/** Maps fold updates to unfold transition progress using DynamicAnimation. */
-class PhysicsBasedUnfoldTransitionProgressProvider @Inject constructor(
- private val foldStateProvider: FoldStateProvider
-) : UnfoldTransitionProgressProvider, FoldUpdatesListener, DynamicAnimation.OnAnimationEndListener {
+class PhysicsBasedUnfoldTransitionProgressProvider
+@Inject
+constructor(context: Context, private val foldStateProvider: FoldStateProvider) :
+ UnfoldTransitionProgressProvider, FoldUpdatesListener, DynamicAnimation.OnAnimationEndListener {
+
+ private val emphasizedInterpolator =
+ loadInterpolator(context, android.R.interpolator.fast_out_extra_slow_in)
+
+ private var cannedAnimator: ValueAnimator? = null
private val springAnimation =
- SpringAnimation(this, AnimationProgressProperty).apply {
- addEndListener(this@PhysicsBasedUnfoldTransitionProgressProvider)
- }
+ SpringAnimation(
+ this,
+ FloatPropertyCompat.createFloatPropertyCompat(AnimationProgressProperty)
+ )
+ .apply { addEndListener(this@PhysicsBasedUnfoldTransitionProgressProvider) }
private var isTransitionRunning = false
private var isAnimatedCancelRunning = false
@@ -76,7 +91,8 @@
override fun onFoldUpdate(@FoldUpdate update: Int) {
when (update) {
- FOLD_UPDATE_FINISH_FULL_OPEN, FOLD_UPDATE_FINISH_HALF_OPEN -> {
+ FOLD_UPDATE_FINISH_FULL_OPEN,
+ FOLD_UPDATE_FINISH_HALF_OPEN -> {
// Do not cancel if we haven't started the transition yet.
// This could happen when we fully unfolded the device before the screen
// became available. In this case we start and immediately cancel the animation
@@ -100,6 +116,14 @@
// the transition continues running.
if (isAnimatedCancelRunning) {
isAnimatedCancelRunning = false
+
+ // Switching to spring animation, start the animation if it
+ // is not running already
+ springAnimation.animateToFinalPosition(1.0f)
+
+ cannedAnimator?.removeAllListeners()
+ cannedAnimator?.cancel()
+ cannedAnimator = null
}
} else {
startTransition(startValue = 1f)
@@ -130,13 +154,22 @@
}
isAnimatedCancelRunning = true
- springAnimation.animateToFinalPosition(endValue)
+
+ if (USE_CANNED_ANIMATION) {
+ startCannedCancelAnimation()
+ } else {
+ springAnimation.animateToFinalPosition(endValue)
+ }
} else {
transitionProgress = endValue
isAnimatedCancelRunning = false
isTransitionRunning = false
springAnimation.cancel()
+ cannedAnimator?.removeAllListeners()
+ cannedAnimator?.cancel()
+ cannedAnimator = null
+
listeners.forEach { it.onTransitionFinished() }
if (DEBUG) {
@@ -157,7 +190,7 @@
}
private fun onStartTransition() {
- Trace.beginSection( "$TAG#onStartTransition")
+ Trace.beginSection("$TAG#onStartTransition")
listeners.forEach { it.onTransitionStarted() }
Trace.endSection()
@@ -195,8 +228,39 @@
listeners.remove(listener)
}
+ private fun startCannedCancelAnimation() {
+ cannedAnimator?.cancel()
+ cannedAnimator = null
+
+ // Temporary remove listener to cancel the spring animation without
+ // finishing the transition
+ springAnimation.removeEndListener(this)
+ springAnimation.cancel()
+ springAnimation.addEndListener(this)
+
+ cannedAnimator =
+ ObjectAnimator.ofFloat(this, AnimationProgressProperty, transitionProgress, 1f).apply {
+ addListener(CannedAnimationListener())
+ duration =
+ (CANNED_ANIMATION_DURATION_MS.toFloat() * (1f - transitionProgress)).toLong()
+ interpolator = emphasizedInterpolator
+ start()
+ }
+ }
+
+ private inner class CannedAnimationListener : AnimatorListenerAdapter() {
+ override fun onAnimationStart(animator: Animator) {
+ Trace.beginAsyncSection("$TAG#cannedAnimatorRunning", 0)
+ }
+
+ override fun onAnimationEnd(animator: Animator) {
+ cancelTransition(1f, animate = false)
+ Trace.endAsyncSection("$TAG#cannedAnimatorRunning", 0)
+ }
+ }
+
private object AnimationProgressProperty :
- FloatPropertyCompat<PhysicsBasedUnfoldTransitionProgressProvider>("animation_progress") {
+ FloatProperty<PhysicsBasedUnfoldTransitionProgressProvider>("animation_progress") {
override fun setValue(
provider: PhysicsBasedUnfoldTransitionProgressProvider,
@@ -205,7 +269,7 @@
provider.transitionProgress = value
}
- override fun getValue(provider: PhysicsBasedUnfoldTransitionProgressProvider): Float =
+ override fun get(provider: PhysicsBasedUnfoldTransitionProgressProvider): Float =
provider.transitionProgress
}
}
@@ -213,6 +277,8 @@
private const val TAG = "PhysicsBasedUnfoldTransitionProgressProvider"
private const val DEBUG = true
+private const val USE_CANNED_ANIMATION = true
+private const val CANNED_ANIMATION_DURATION_MS = 1000
private const val SPRING_STIFFNESS = 600.0f
private const val MINIMAL_VISIBLE_CHANGE = 0.001f
private const val FINAL_HINGE_ANGLE_POSITION = 165f
diff --git a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
index ee806a6..1298f63 100644
--- a/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
+++ b/packages/services/CameraExtensionsProxy/src/com/android/cameraextensions/CameraExtensionsProxyService.java
@@ -2076,6 +2076,7 @@
ret.outputId.id = output.getId();
ret.physicalCameraId = output.getPhysicalCameraId();
ret.surfaceGroupId = output.getSurfaceGroupId();
+ ret.isMultiResolutionOutput = false;
if (output instanceof SurfaceOutputConfigImpl) {
SurfaceOutputConfigImpl surfaceConfig = (SurfaceOutputConfigImpl) output;
ret.type = CameraOutputConfig.TYPE_SURFACE;
@@ -2095,6 +2096,7 @@
ret.type = CameraOutputConfig.TYPE_MULTIRES_IMAGEREADER;
ret.imageFormat = multiResReaderConfig.getImageFormat();
ret.capacity = multiResReaderConfig.getMaxImages();
+ ret.isMultiResolutionOutput = true;
} else {
throw new IllegalStateException("Unknown output config type!");
}
diff --git a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
index b0463db..d731fe2 100644
--- a/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
+++ b/services/accessibility/java/com/android/server/accessibility/AccessibilityManagerService.java
@@ -2277,6 +2277,15 @@
}
if (userState.mEnabledServices.contains(componentName)
&& !mUiAutomationManager.suppressingAccessibilityServicesLocked()) {
+ // Skip the enabling service disallowed by device admin policy.
+ if (!isAccessibilityTargetAllowed(componentName.getPackageName(),
+ installedService.getResolveInfo().serviceInfo.applicationInfo.uid,
+ userState.mUserId)) {
+ Slog.d(LOG_TAG, "Skipping enabling service disallowed by device admin policy: "
+ + componentName);
+ disableAccessibilityServiceLocked(componentName, userState.mUserId);
+ continue;
+ }
if (service == null) {
service = new AccessibilityServiceConnection(userState, mContext, componentName,
installedService, sIdCounter++, mMainHandler, mLock, mSecurityPolicy,
@@ -3890,31 +3899,30 @@
}
@Override
- @RequiresPermission(anyOf = {
- android.Manifest.permission.MANAGE_USERS,
- android.Manifest.permission.QUERY_ADMIN_POLICY})
public boolean isAccessibilityTargetAllowed(String packageName, int uid, int userId) {
- final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
- final List<String> permittedServices = dpm.getPermittedAccessibilityServices(userId);
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ final DevicePolicyManager dpm = mContext.getSystemService(DevicePolicyManager.class);
+ final List<String> permittedServices = dpm.getPermittedAccessibilityServices(userId);
- // permittedServices null means all accessibility services are allowed.
- boolean allowed = permittedServices == null || permittedServices.contains(packageName);
- if (allowed) {
- final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
- final int mode = appOps.noteOpNoThrow(
- AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
- uid, packageName, /* attributionTag= */ null, /* message= */ null);
- final boolean ecmEnabled = mContext.getResources().getBoolean(
- R.bool.config_enhancedConfirmationModeEnabled);
- return !ecmEnabled || mode == AppOpsManager.MODE_ALLOWED;
+ // permittedServices null means all accessibility services are allowed.
+ boolean allowed = permittedServices == null || permittedServices.contains(packageName);
+ if (allowed) {
+ final AppOpsManager appOps = mContext.getSystemService(AppOpsManager.class);
+ final int mode = appOps.noteOpNoThrow(
+ AppOpsManager.OP_ACCESS_RESTRICTED_SETTINGS,
+ uid, packageName, /* attributionTag= */ null, /* message= */ null);
+ final boolean ecmEnabled = mContext.getResources().getBoolean(
+ R.bool.config_enhancedConfirmationModeEnabled);
+ return !ecmEnabled || mode == AppOpsManager.MODE_ALLOWED;
+ }
+ return false;
+ } finally {
+ Binder.restoreCallingIdentity(identity);
}
- return false;
}
@Override
- @RequiresPermission(anyOf = {
- android.Manifest.permission.MANAGE_USERS,
- android.Manifest.permission.QUERY_ADMIN_POLICY})
public boolean sendRestrictedDialogIntent(String packageName, int uid, int userId) {
// The accessibility service is allowed. Don't show the restricted dialog.
if (isAccessibilityTargetAllowed(packageName, uid, userId)) {
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
index 01386da..af5b196 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerService.java
@@ -383,7 +383,7 @@
final AutofillManagerServiceImpl service = peekServiceForUserLocked(userId);
if (service == null) {
// If we cannot get the service from the services cache, it will call
- // updateRemoteAugmentedAutofillService() finally. Skip call this update again.
+ // updateRemoteFieldClassificationService() finally. Skip call this update again.
getServiceForUserLocked(userId);
} else {
service.updateRemoteFieldClassificationService();
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
index bea049c..d5dcdaf 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceImpl.java
@@ -1731,7 +1731,7 @@
}
/**
- * Called when the {@link AutofillManagerService#mAugmentedAutofillResolver}
+ * Called when the {@link AutofillManagerService#mFieldClassificationResolver}
* changed (among other places).
*/
void updateRemoteFieldClassificationService() {
@@ -1742,7 +1742,6 @@
+ "destroying old remote service");
}
mRemoteFieldClassificationService.unbind();
-
mRemoteFieldClassificationService = null;
mRemoteFieldClassificationServiceInfo = null;
}
diff --git a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
index b4e636e..62a2970 100644
--- a/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
+++ b/services/autofill/java/com/android/server/autofill/AutofillManagerServiceShellCommand.java
@@ -327,13 +327,11 @@
private int setTemporaryDetectionService(PrintWriter pw) {
final int userId = getNextIntArgRequired();
final String serviceName = getNextArg();
- final int duration = getNextIntArgRequired();
-
if (serviceName == null) {
mService.resetTemporaryDetectionService(userId);
return 0;
}
-
+ final int duration = getNextIntArgRequired();
if (duration <= 0) {
mService.resetTemporaryDetectionService(userId);
return 0;
diff --git a/services/autofill/java/com/android/server/autofill/FillRequestEventLogger.java b/services/autofill/java/com/android/server/autofill/FillRequestEventLogger.java
new file mode 100644
index 0000000..3b30af6
--- /dev/null
+++ b/services/autofill/java/com/android/server/autofill/FillRequestEventLogger.java
@@ -0,0 +1,268 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.autofill;
+
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_REQUEST_REPORTED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_EXPLICITLY_REQUESTED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_NORMAL_TRIGGER;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_PRE_TRIGGER;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_RETRIGGER;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_UNKNOWN;
+import static com.android.server.autofill.Helper.sVerbose;
+
+import android.annotation.IntDef;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.pm.PackageManager;
+import android.provider.Settings;
+import android.text.TextUtils;
+import android.util.Slog;
+
+import com.android.internal.util.FrameworkStatsLog;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.Optional;
+
+/**
+ * Helper class to log Autofill FillRequest filing stats.
+ */
+public final class FillRequestEventLogger {
+ private static final String TAG = "FillRequestEventLogger";
+
+ /**
+ * Reasons why presentation was not shown. These are wrappers around
+ * {@link com.android.os.AtomsProto.AutofillFillRequestReported.RequestTriggerReason}.
+ */
+ @IntDef(prefix = {"TRIGGER_REASON"}, value = {
+ TRIGGER_REASON_UNKNOWN,
+ TRIGGER_REASON_EXPLICITLY_REQUESTED,
+ TRIGGER_REASON_RETRIGGER,
+ TRIGGER_REASON_PRE_TRIGGER,
+ TRIGGER_REASON_NORMAL_TRIGGER,
+ TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ public @interface TriggerReason {
+ }
+
+ public static final int TRIGGER_REASON_UNKNOWN =
+ AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_UNKNOWN;
+ public static final int TRIGGER_REASON_EXPLICITLY_REQUESTED =
+ AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_EXPLICITLY_REQUESTED;
+ public static final int TRIGGER_REASON_RETRIGGER =
+ AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_RETRIGGER;
+ public static final int TRIGGER_REASON_PRE_TRIGGER =
+ AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_PRE_TRIGGER;
+ public static final int TRIGGER_REASON_NORMAL_TRIGGER =
+ AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_NORMAL_TRIGGER;
+ public static final int TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE =
+ AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE;
+
+ private final int mSessionId;
+ private Optional<FillRequestEventInternal> mEventInternal;
+
+ private FillRequestEventLogger(int sessionId) {
+ mSessionId = sessionId;
+ mEventInternal = Optional.empty();
+ }
+
+ /**
+ * A factory constructor to create FillRequestEventLogger.
+ */
+ public static FillRequestEventLogger forSessionId(int sessionId) {
+ return new FillRequestEventLogger(sessionId);
+ }
+ /**
+ * Reset mEventInternal before logging for a new request. It shall be called for each
+ * FillRequest.
+ */
+ public void startLogForNewRequest() {
+ if (!mEventInternal.isEmpty()) {
+ Slog.w(TAG, "FillRequestEventLogger is not empty before starting for a new " +
+ "request");
+ }
+ mEventInternal = Optional.of(new FillRequestEventInternal());
+ }
+
+ /**
+ * Set request_id as long as mEventInternal presents.
+ */
+ public void maybeSetRequestId(int requestId) {
+ mEventInternal.ifPresent(event -> event.mRequestId = requestId);
+ }
+
+ /**
+ * Set service_uid as long as mEventInternal presents.
+ */
+ public void maybeSetAutofillServiceUid(int uid) {
+ mEventInternal.ifPresent(event -> {
+ event.mAutofillServiceUid = uid;
+ });
+ }
+
+ /**
+ * Set inline_suggestion_host_uid as long as mEventInternal presents.
+ */
+ public void maybeSetInlineSuggestionHostUid(Context context, int userId) {
+ mEventInternal.ifPresent(event -> {
+ String imeString = Settings.Secure.getStringForUser(context.getContentResolver(),
+ Settings.Secure.DEFAULT_INPUT_METHOD, userId);
+ if (TextUtils.isEmpty(imeString)) {
+ Slog.w(TAG, "No default IME found");
+ return;
+ }
+ ComponentName imeComponent = ComponentName.unflattenFromString(imeString);
+ if (imeComponent == null) {
+ Slog.w(TAG, "No default IME found");
+ return;
+ }
+ int imeUid;
+ String packageName = imeComponent.getPackageName();
+ try {
+ imeUid = context.getPackageManager().getApplicationInfoAsUser(packageName,
+ PackageManager.ApplicationInfoFlags.of(0), userId).uid;
+ } catch (PackageManager.NameNotFoundException e) {
+ Slog.w(TAG, "Couldn't find packageName: " + packageName);
+ return;
+ }
+ event.mInlineSuggestionHostUid = imeUid;
+ });
+ }
+
+
+ /**
+ * Set flags as long as mEventInternal presents.
+ */
+ public void maybeSetFlags(int flags) {
+ mEventInternal.ifPresent(event -> {
+ event.mFlags = flags;
+ });
+ }
+
+ /**
+ * Set request_trigger_reason as long as mEventInternal presents.
+ */
+ public void maybeSetRequestTriggerReason(@TriggerReason int reason) {
+ mEventInternal.ifPresent(event -> {
+ event.mRequestTriggerReason = reason;
+ });
+ }
+
+ /**
+ * Set is_augmented as long as mEventInternal presents.
+ */
+ public void maybeSetIsAugmented(boolean val) {
+ mEventInternal.ifPresent(event -> {
+ event.mIsAugmented = val;
+ });
+ }
+
+ /**
+ * Set is_client_suggestion as long as mEventInternal presents.
+ */
+ public void maybeSetIsClientSuggestionFallback(boolean val) {
+ mEventInternal.ifPresent(event -> {
+ event.mIsClientSuggestionFallback = val;
+ });
+ }
+
+ /**
+ * Set is_fill_dialog_eligible as long as mEventInternal presents.
+ */
+ public void maybeSetIsFillDialogEligible(boolean val) {
+ mEventInternal.ifPresent(event -> {
+ event.mIsFillDialogEligible = val;
+ });
+ }
+
+ /**
+ * Set latency_fill_request_sent_millis as long as mEventInternal presents.
+ */
+ public void maybeSetLatencyFillRequestSentMillis(int timestamp) {
+ mEventInternal.ifPresent(event -> {
+ event.mLatencyFillRequestSentMillis = timestamp;
+ });
+ }
+
+ /**
+ * Set app_package_uid as long as mEventInternal presents.
+ */
+ public void maybeSetAppPackageUid(int uid) {
+ mEventInternal.ifPresent(event -> {
+ event.mAppPackageUid = uid;
+ });
+ }
+
+ /**
+ * Log an AUTOFILL_FILL_REQUEST_REPORTED event.
+ */
+ public void logAndEndEvent() {
+ if (!mEventInternal.isPresent()) {
+ Slog.w(TAG, "Shouldn't be logging AutofillFillRequestReported again for same "
+ + "event");
+ return;
+ }
+ FillRequestEventInternal event = mEventInternal.get();
+ if (sVerbose) {
+ Slog.v(TAG, "Log AutofillFillRequestReported:"
+ + " requestId=" + event.mRequestId
+ + " sessionId=" + mSessionId
+ + " mAutofillServiceUid=" + event.mAutofillServiceUid
+ + " mInlineSuggestionHostUid=" + event.mInlineSuggestionHostUid
+ + " mIsAugmented=" + event.mIsAugmented
+ + " mIsClientSuggestionFallback=" + event.mIsClientSuggestionFallback
+ + " mIsFillDialogEligible=" + event.mIsFillDialogEligible
+ + " mRequestTriggerReason=" + event.mRequestTriggerReason
+ + " mFlags=" + event.mFlags
+ + " mLatencyFillRequestSentMillis=" + event.mLatencyFillRequestSentMillis
+ + " mAppPackageUid=" + event.mAppPackageUid);
+ }
+ FrameworkStatsLog.write(
+ AUTOFILL_FILL_REQUEST_REPORTED,
+ event.mRequestId,
+ mSessionId,
+ event.mAutofillServiceUid,
+ event.mInlineSuggestionHostUid,
+ event.mIsAugmented,
+ event.mIsClientSuggestionFallback,
+ event.mIsFillDialogEligible,
+ event.mRequestTriggerReason,
+ event.mFlags,
+ event.mLatencyFillRequestSentMillis,
+ event.mAppPackageUid);
+ mEventInternal = Optional.empty();
+ }
+
+ private static final class FillRequestEventInternal {
+ int mRequestId;
+ int mAppPackageUid = -1;
+ int mAutofillServiceUid = -1;
+ int mInlineSuggestionHostUid = -1;
+ boolean mIsAugmented = false;
+ boolean mIsClientSuggestionFallback = false;
+ boolean mIsFillDialogEligible = false;
+ int mRequestTriggerReason =
+ AUTOFILL_FILL_REQUEST_REPORTED__REQUEST_TRIGGER_REASON__TRIGGER_REASON_UNKNOWN;
+ int mFlags = -1;
+ int mLatencyFillRequestSentMillis = -1;
+
+ FillRequestEventInternal() {
+ }
+ }
+}
diff --git a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
index 590f472..7d1de40 100644
--- a/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
+++ b/services/autofill/java/com/android/server/autofill/PresentationStatsEventLogger.java
@@ -38,6 +38,7 @@
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_SESSION_COMMITTED_PREMATURELY;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_UNKNOWN_REASON;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED;
+import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUSED_BEFORE_FILL_DIALOG_RESPONSE;
import static com.android.internal.util.FrameworkStatsLog.AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUS_CHANGED;
import static com.android.server.autofill.Helper.sVerbose;
@@ -71,6 +72,7 @@
@IntDef(prefix = {"NOT_SHOWN_REASON"}, value = {
NOT_SHOWN_REASON_ANY_SHOWN,
NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED,
+ NOT_SHOWN_REASON_VIEW_FOCUSED_BEFORE_FILL_DIALOG_RESPONSE,
NOT_SHOWN_REASON_VIEW_CHANGED,
NOT_SHOWN_REASON_ACTIVITY_FINISHED,
NOT_SHOWN_REASON_REQUEST_TIMEOUT,
@@ -86,6 +88,8 @@
AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__ANY_SHOWN;
public static final int NOT_SHOWN_REASON_VIEW_FOCUS_CHANGED =
AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUS_CHANGED;
+ public static final int NOT_SHOWN_REASON_VIEW_FOCUSED_BEFORE_FILL_DIALOG_RESPONSE =
+ AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_FOCUSED_BEFORE_FILL_DIALOG_RESPONSE;
public static final int NOT_SHOWN_REASON_VIEW_CHANGED =
AUTOFILL_PRESENTATION_EVENT_REPORTED__PRESENTATION_EVENT_RESULT__NONE_SHOWN_VIEW_CHANGED;
public static final int NOT_SHOWN_REASON_ACTIVITY_FINISHED =
@@ -142,7 +146,7 @@
}
public void maybeSetAvailableCount(@Nullable List<Dataset> datasetList,
- AutofillId currentViewId) {
+ AutofillId currentViewId) {
mEventInternal.ifPresent(event -> {
int availableCount = getDatasetCountForAutofillId(datasetList, currentViewId);
event.mAvailableCount = availableCount;
@@ -151,7 +155,7 @@
}
public void maybeSetCountShown(@Nullable List<Dataset> datasetList,
- AutofillId currentViewId) {
+ AutofillId currentViewId) {
mEventInternal.ifPresent(event -> {
int countShown = getDatasetCountForAutofillId(datasetList, currentViewId);
event.mCountShown = countShown;
@@ -162,7 +166,7 @@
}
private static int getDatasetCountForAutofillId(@Nullable List<Dataset> datasetList,
- AutofillId currentViewId) {
+ AutofillId currentViewId) {
int availableCount = 0;
if (datasetList != null) {
for (int i = 0; i < datasetList.size(); i++) {
@@ -225,10 +229,34 @@
});
}
+ public void maybeSetSelectedDatasetId(int selectedDatasetId) {
+ mEventInternal.ifPresent(event -> {
+ event.mSelectedDatasetId = selectedDatasetId;
+ });
+ }
+
+ public void maybeSetDialogDismissed(boolean dialogDismissed) {
+ mEventInternal.ifPresent(event -> {
+ event.mDialogDismissed = dialogDismissed;
+ });
+ }
+
+ public void maybeSetNegativeCtaButtonClicked(boolean negativeCtaButtonClicked) {
+ mEventInternal.ifPresent(event -> {
+ event.mNegativeCtaButtonClicked = negativeCtaButtonClicked;
+ });
+ }
+
+ public void maybeSetPositiveCtaButtonClicked(boolean positiveCtaButtonClicked) {
+ mEventInternal.ifPresent(event -> {
+ event.mPositiveCtaButtonClicked = positiveCtaButtonClicked;
+ });
+ }
+
public void maybeSetInlinePresentationAndSuggestionHostUid(Context context, int userId) {
mEventInternal.ifPresent(event -> {
event.mDisplayPresentationType =
- AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__INLINE;
+ AUTOFILL_PRESENTATION_EVENT_REPORTED__DISPLAY_PRESENTATION_TYPE__INLINE;
String imeString = Settings.Secure.getStringForUser(context.getContentResolver(),
Settings.Secure.DEFAULT_INPUT_METHOD, userId);
if (TextUtils.isEmpty(imeString)) {
@@ -290,7 +318,11 @@
+ " mFillRequestSentTimestampMs=" + event.mFillRequestSentTimestampMs
+ " mFillResponseReceivedTimestampMs=" + event.mFillResponseReceivedTimestampMs
+ " mSuggestionSentTimestampMs=" + event.mSuggestionSentTimestampMs
- + " mSuggestionPresentedTimestampMs=" + event.mSuggestionPresentedTimestampMs);
+ + " mSuggestionPresentedTimestampMs=" + event.mSuggestionPresentedTimestampMs
+ + " mSelectedDatasetId=" + event.mSelectedDatasetId
+ + " mDialogDismissed=" + event.mDialogDismissed
+ + " mNegativeCtaButtonClicked=" + event.mNegativeCtaButtonClicked
+ + " mPositiveCtaButtonClicked=" + event.mPositiveCtaButtonClicked);
}
// TODO(b/234185326): Distinguish empty responses from other no presentation reasons.
@@ -316,11 +348,10 @@
event.mFillResponseReceivedTimestampMs,
event.mSuggestionSentTimestampMs,
event.mSuggestionPresentedTimestampMs,
- //TODO(b/265051751): add new framework logging.
- /* selected_dataset_id= */ 0,
- /* dialog_dismissed= */ false,
- /* negative_cta_button_clicked= */ false,
- /* positive_cta_button_clicked= */ false);
+ event.mSelectedDatasetId,
+ event.mDialogDismissed,
+ event.mNegativeCtaButtonClicked,
+ event.mPositiveCtaButtonClicked);
mEventInternal = Optional.empty();
}
@@ -341,6 +372,10 @@
int mFillResponseReceivedTimestampMs;
int mSuggestionSentTimestampMs;
int mSuggestionPresentedTimestampMs;
+ int mSelectedDatasetId = -1;
+ boolean mDialogDismissed = false;
+ boolean mNegativeCtaButtonClicked = false;
+ boolean mPositiveCtaButtonClicked = false;
PresentationStatsEventInternal() {}
}
diff --git a/services/autofill/java/com/android/server/autofill/Session.java b/services/autofill/java/com/android/server/autofill/Session.java
index 7f6ad43..4acdabe 100644
--- a/services/autofill/java/com/android/server/autofill/Session.java
+++ b/services/autofill/java/com/android/server/autofill/Session.java
@@ -16,6 +16,7 @@
package com.android.server.autofill;
+import static android.Manifest.permission.PROVIDE_OWN_AUTOFILL_SUGGESTIONS;
import static android.service.autofill.AutofillFieldClassificationService.EXTRA_SCORES;
import static android.service.autofill.AutofillService.EXTRA_FILL_RESPONSE;
import static android.service.autofill.FillEventHistory.Event.UI_TYPE_DIALOG;
@@ -40,6 +41,9 @@
import static android.view.autofill.AutofillManager.getSmartSuggestionModeToString;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_NORMAL_TRIGGER;
+import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_PRE_TRIGGER;
+import static com.android.server.autofill.FillRequestEventLogger.TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE;
import static com.android.server.autofill.Helper.containsCharsInOrder;
import static com.android.server.autofill.Helper.createSanitizers;
import static com.android.server.autofill.Helper.getNumericValue;
@@ -72,6 +76,7 @@
import android.content.IntentFilter;
import android.content.IntentSender;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.graphics.Bitmap;
import android.graphics.Rect;
@@ -437,6 +442,10 @@
@GuardedBy("mLock")
private PresentationStatsEventLogger mPresentationStatsEventLogger;
+ @NonNull
+ @GuardedBy("mLock")
+ private FillRequestEventLogger mFillRequestEventLogger;
+
/**
* Fill dialog request would likely be sent slightly later.
*/
@@ -603,6 +612,14 @@
mPendingInlineSuggestionsRequest = null;
mWaitForInlineRequest = false;
mPendingFillRequest = null;
+
+ final long fillRequestSentRelativeTimestamp =
+ SystemClock.elapsedRealtime() - mLatencyBaseTime;
+ mPresentationStatsEventLogger.maybeSetFillRequestSentTimestampMs(
+ (int) (fillRequestSentRelativeTimestamp));
+ mFillRequestEventLogger.maybeSetLatencyFillRequestSentMillis(
+ (int) (fillRequestSentRelativeTimestamp));
+ mFillRequestEventLogger.logAndEndEvent();
}
@Override
@@ -1080,11 +1097,21 @@
private void requestNewFillResponseLocked(@NonNull ViewState viewState, int newState,
int flags) {
final FillResponse existingResponse = viewState.getResponse();
+ mFillRequestEventLogger.startLogForNewRequest();
+ mFillRequestEventLogger.maybeSetAppPackageUid(uid);
+ mFillRequestEventLogger.maybeSetFlags(mFlags);
+ if(mPreviouslyFillDialogPotentiallyStarted) {
+ mFillRequestEventLogger.maybeSetRequestTriggerReason(TRIGGER_REASON_PRE_TRIGGER);
+ } else {
+ mFillRequestEventLogger.maybeSetRequestTriggerReason(TRIGGER_REASON_NORMAL_TRIGGER);
+ }
if (existingResponse != null) {
setViewStatesLocked(
existingResponse,
ViewState.STATE_INITIAL,
/* clearResponse= */ true);
+ mFillRequestEventLogger.maybeSetRequestTriggerReason(
+ TRIGGER_REASON_SERVED_FROM_CACHED_RESPONSE);
}
mSessionFlags.mExpiredResponse = false;
mSessionState = STATE_ACTIVE;
@@ -1095,6 +1122,10 @@
+ ", flags=" + flags + ")");
}
mSessionFlags.mAugmentedAutofillOnly = true;
+ // Augmented autofill doesn't have request_id.
+ mFillRequestEventLogger.maybeSetRequestId(-1);
+ mFillRequestEventLogger.maybeSetIsAugmented(mSessionFlags.mAugmentedAutofillOnly);
+ mFillRequestEventLogger.logAndEndEvent();
triggerAugmentedAutofillLocked(flags);
return;
}
@@ -1121,6 +1152,12 @@
+ ", flags=" + flags);
}
mPresentationStatsEventLogger.maybeSetRequestId(requestId);
+ mFillRequestEventLogger.maybeSetRequestId(requestId);
+ mFillRequestEventLogger.maybeSetAutofillServiceUid(getAutofillServiceUid());
+ if (mSessionFlags.mInlineSupportedByService) {
+ mFillRequestEventLogger.maybeSetInlineSuggestionHostUid(mContext, userId);
+ }
+ mFillRequestEventLogger.maybeSetIsFillDialogEligible(!mSessionFlags.mFillDialogDisabled);
// If the focus changes very quickly before the first request is returned each focus change
// triggers a new partition and we end up with many duplicate partitions. This is
@@ -1187,11 +1224,6 @@
return;
}
- final long fillRequestSentRelativeTimestamp =
- SystemClock.elapsedRealtime() - mLatencyBaseTime;
- mPresentationStatsEventLogger.maybeSetFillRequestSentTimestampMs(
- (int) (fillRequestSentRelativeTimestamp));
-
// Now request the assist structure data.
requestAssistStructureLocked(requestId, flags);
}
@@ -1282,12 +1314,16 @@
mCompatMode = compatMode;
mSessionState = STATE_ACTIVE;
mPresentationStatsEventLogger = PresentationStatsEventLogger.forSessionId(sessionId);
+ mFillRequestEventLogger = FillRequestEventLogger.forSessionId(sessionId);
synchronized (mLock) {
mSessionFlags = new SessionFlags();
mSessionFlags.mAugmentedAutofillOnly = forAugmentedAutofillOnly;
mSessionFlags.mInlineSupportedByService = mService.isInlineSuggestionsEnabledLocked();
- mSessionFlags.mClientSuggestionsEnabled =
- (mFlags & FLAG_ENABLED_CLIENT_SUGGESTIONS) != 0;
+ if (mContext.checkCallingPermission(PROVIDE_OWN_AUTOFILL_SUGGESTIONS)
+ == PackageManager.PERMISSION_GRANTED) {
+ mSessionFlags.mClientSuggestionsEnabled =
+ (mFlags & FLAG_ENABLED_CLIENT_SUGGESTIONS) != 0;
+ }
setClientLocked(client);
}
@@ -4346,8 +4382,10 @@
for (int j = 0; j < fieldIds.size(); j++) {
final AutofillId id = fieldIds.get(j);
- if (trackedViews == null || !trackedViews.contains(id)) {
- fillableIds = ArrayUtils.add(fillableIds, id);
+ if (id != null) {
+ if (trackedViews == null || !trackedViews.contains(id)) {
+ fillableIds = ArrayUtils.add(fillableIds, id);
+ }
}
}
}
diff --git a/services/backup/java/com/android/server/backup/FullBackupJob.java b/services/backup/java/com/android/server/backup/FullBackupJob.java
index fe0e1c6..de33698 100644
--- a/services/backup/java/com/android/server/backup/FullBackupJob.java
+++ b/services/backup/java/com/android/server/backup/FullBackupJob.java
@@ -24,6 +24,7 @@
import android.app.job.JobService;
import android.content.ComponentName;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.SparseArray;
@@ -52,13 +53,15 @@
JobInfo.Builder builder = new JobInfo.Builder(getJobIdForUserId(userId), sIdleService);
final BackupManagerConstants constants = userBackupManagerService.getConstants();
synchronized (constants) {
- builder.setRequiresDeviceIdle(true)
- .setRequiredNetworkType(constants.getFullBackupRequiredNetworkType())
+ builder.setRequiredNetworkType(constants.getFullBackupRequiredNetworkType())
.setRequiresCharging(constants.getFullBackupRequireCharging());
}
if (minDelay > 0) {
builder.setMinimumLatency(minDelay);
}
+ if (!ctx.getPackageManager().hasSystemFeature(PackageManager.FEATURE_WATCH)) {
+ builder.setRequiresDeviceIdle(true);
+ }
Bundle extraInfo = new Bundle();
extraInfo.putInt(USER_ID_EXTRA_KEY, userId);
diff --git a/services/core/java/android/app/usage/UsageStatsManagerInternal.java b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
index 70eeb7f..fc56511 100644
--- a/services/core/java/android/app/usage/UsageStatsManagerInternal.java
+++ b/services/core/java/android/app/usage/UsageStatsManagerInternal.java
@@ -203,6 +203,16 @@
public abstract void setActiveAdminApps(Set<String> adminApps, int userId);
/**
+ * Called by DevicePolicyManagerService to inform about the protected packages for a user.
+ * User control will be disabled for protected packages.
+ *
+ * @param packageNames the set of protected packages for {@code userId}.
+ * @param userId the userId to which the protected packages belong.
+ */
+ public abstract void setAdminProtectedPackages(@Nullable Set<String> packageNames,
+ @UserIdInt int userId);
+
+ /**
* Called by DevicePolicyManagerService during boot to inform that admin data is loaded and
* pushed to UsageStatsService.
*/
diff --git a/services/core/java/android/content/pm/PackageManagerInternal.java b/services/core/java/android/content/pm/PackageManagerInternal.java
index b673fb6..97af17d 100644
--- a/services/core/java/android/content/pm/PackageManagerInternal.java
+++ b/services/core/java/android/content/pm/PackageManagerInternal.java
@@ -44,6 +44,7 @@
import android.util.SparseArray;
import com.android.internal.util.function.pooled.PooledLambda;
+import com.android.permission.persistence.RuntimePermissionsState;
import com.android.server.pm.Installer.LegacyDexoptDisabledException;
import com.android.server.pm.KnownPackages;
import com.android.server.pm.PackageList;
@@ -1077,10 +1078,17 @@
/**
* Read legacy permission definitions for permissions migration to new permission subsystem.
+ * Note that this api is supposed to be used for permissions migration only.
*/
public abstract LegacyPermissionSettings getLegacyPermissions();
/**
+ * Read legacy permission states for permissions migration to new permission subsystem.
+ * Note that this api is supposed to be used for permissions state migration only.
+ */
+ public abstract RuntimePermissionsState getLegacyPermissionsState(@UserIdInt int userId);
+
+ /**
* Returns {@code true} if the caller is the installer of record for the given package.
* Otherwise, {@code false}.
*/
diff --git a/services/core/java/com/android/server/DropBoxManagerService.java b/services/core/java/com/android/server/DropBoxManagerService.java
index a3dc21e..55069b7 100644
--- a/services/core/java/com/android/server/DropBoxManagerService.java
+++ b/services/core/java/com/android/server/DropBoxManagerService.java
@@ -311,14 +311,10 @@
extrasMerger.setMergeStrategy(DropBoxManager.EXTRA_DROPPED_COUNT,
BundleMerger.STRATEGY_NUMBER_INCREMENT_FIRST_AND_ADD);
- final String tag = intent.getStringExtra(DropBoxManager.EXTRA_TAG);
- final IntentFilter matchingFilter = new IntentFilter(
- DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED);
- matchingFilter.addExtra(DropBoxManager.EXTRA_TAG, tag);
-
return BroadcastOptions.makeBasic()
.setDeliveryGroupPolicy(BroadcastOptions.DELIVERY_GROUP_POLICY_MERGED)
- .setDeliveryGroupMatchingFilter(matchingFilter)
+ .setDeliveryGroupMatchingKey(DropBoxManager.ACTION_DROPBOX_ENTRY_ADDED,
+ intent.getStringExtra(DropBoxManager.EXTRA_TAG))
.setDeliveryGroupExtrasMerger(extrasMerger)
.setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE)
.toBundle();
diff --git a/services/core/java/com/android/server/MmsServiceBroker.java b/services/core/java/com/android/server/MmsServiceBroker.java
index 742c94a..d6f1348 100644
--- a/services/core/java/com/android/server/MmsServiceBroker.java
+++ b/services/core/java/com/android/server/MmsServiceBroker.java
@@ -343,10 +343,8 @@
// Check if user is associated with the subscription
if (!TelephonyPermissions.checkSubscriptionAssociatedWithUser(mContext, subId,
Binder.getCallingUserHandle())) {
- if (TelephonyUtils.isUidForeground(mContext, Binder.getCallingUid())) {
- TelephonyUtils.showErrorIfSubscriptionAssociatedWithManagedProfile(mContext,
- subId);
- }
+ TelephonyUtils.showSwitchToManagedProfileDialogIfAppropriate(mContext,
+ subId, Binder.getCallingUid(), callingPkg);
return;
}
diff --git a/services/core/java/com/android/server/SystemServerInitThreadPool.java b/services/core/java/com/android/server/SystemServerInitThreadPool.java
index 7f24c52..3d3535d 100644
--- a/services/core/java/com/android/server/SystemServerInitThreadPool.java
+++ b/services/core/java/com/android/server/SystemServerInitThreadPool.java
@@ -25,7 +25,7 @@
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.Preconditions;
-import com.android.server.am.ActivityManagerService;
+import com.android.server.am.StackTracesDumpHelper;
import com.android.server.utils.TimingsTraceAndSlog;
import java.io.PrintWriter;
@@ -188,12 +188,12 @@
}
/**
- * A helper function to call ActivityManagerService.dumpStackTraces().
+ * A helper function to call StackTracesDumpHelper.dumpStackTraces().
*/
private static void dumpStackTraces() {
final ArrayList<Integer> pids = new ArrayList<>();
pids.add(Process.myPid());
- ActivityManagerService.dumpStackTraces(pids,
+ StackTracesDumpHelper.dumpStackTraces(pids,
/* processCpuTracker= */null, /* lastPids= */null,
CompletableFuture.completedFuture(Watchdog.getInterestingNativePids()),
/* logExceptionCreatingFile= */null, /* subject= */null,
diff --git a/services/core/java/com/android/server/SystemUpdateManagerService.java b/services/core/java/com/android/server/SystemUpdateManagerService.java
index 811a780..d5e7be5 100644
--- a/services/core/java/com/android/server/SystemUpdateManagerService.java
+++ b/services/core/java/com/android/server/SystemUpdateManagerService.java
@@ -86,9 +86,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.RECOVERY)
@Override
public void updateSystemUpdateInfo(PersistableBundle infoBundle) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.RECOVERY, TAG);
+ updateSystemUpdateInfo_enforcePermission();
int status = infoBundle.getInt(KEY_STATUS, STATUS_UNKNOWN);
if (status == STATUS_UNKNOWN) {
diff --git a/services/core/java/com/android/server/Watchdog.java b/services/core/java/com/android/server/Watchdog.java
index e536076..62651dd 100644
--- a/services/core/java/com/android/server/Watchdog.java
+++ b/services/core/java/com/android/server/Watchdog.java
@@ -56,6 +56,7 @@
import com.android.internal.os.ZygoteConnectionConstants;
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.am.ActivityManagerService;
+import com.android.server.am.StackTracesDumpHelper;
import com.android.server.am.TraceErrorLogger;
import com.android.server.criticalevents.CriticalEventLog;
import com.android.server.wm.SurfaceAnimationThread;
@@ -880,7 +881,8 @@
CriticalEventLog.getInstance().logLinesForSystemServerTraceFile();
final UUID errorId = mTraceErrorLogger.generateErrorId();
if (mTraceErrorLogger.isAddErrorIdEnabled()) {
- mTraceErrorLogger.addErrorIdToTrace("system_server", errorId);
+ mTraceErrorLogger.addProcessInfoAndErrorIdToTrace("system_server", Process.myPid(),
+ errorId);
mTraceErrorLogger.addSubjectToTrace(subject, errorId);
}
@@ -904,7 +906,7 @@
report.append(ResourcePressureUtil.currentPsiState());
ProcessCpuTracker processCpuTracker = new ProcessCpuTracker(false);
StringWriter tracesFileException = new StringWriter();
- final File stack = ActivityManagerService.dumpStackTraces(
+ final File stack = StackTracesDumpHelper.dumpStackTraces(
pids, processCpuTracker, new SparseBooleanArray(),
CompletableFuture.completedFuture(getInterestingNativePids()), tracesFileException,
subject, criticalEvents, Runnable::run, /* latencyTracker= */null);
diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java
index 4a0a228..461103e 100644
--- a/services/core/java/com/android/server/am/ActiveServices.java
+++ b/services/core/java/com/android/server/am/ActiveServices.java
@@ -602,7 +602,7 @@
try {
final ServiceRecord.StartItem si = r.pendingStarts.get(0);
startServiceInnerLocked(this, si.intent, r, false, true, si.callingId,
- si.mCallingProcessName, r.startRequested);
+ si.mCallingProcessName, r.startRequested, si.mCallingPackageName);
} catch (TransactionTooLargeException e) {
// Ignore, nobody upstack cares.
}
@@ -969,7 +969,7 @@
startServiceInnerLocked(r, service, callingUid, callingPid,
getCallingProcessNameLocked(callingUid, callingPid, callingPackage),
fgRequired, callerFg,
- backgroundStartPrivileges);
+ backgroundStartPrivileges, callingPackage);
if (res.aliasComponent != null
&& !realResult.getPackageName().startsWith("!")
&& !realResult.getPackageName().startsWith("?")) {
@@ -990,7 +990,7 @@
private ComponentName startServiceInnerLocked(ServiceRecord r, Intent service,
int callingUid, int callingPid, String callingProcessName, boolean fgRequired,
boolean callerFg,
- BackgroundStartPrivileges backgroundStartPrivileges)
+ BackgroundStartPrivileges backgroundStartPrivileges, String callingPackage)
throws TransactionTooLargeException {
NeededUriGrants neededGrants = mAm.mUgmInternal.checkGrantUriPermissionFromIntent(
service, callingUid, r.packageName, r.userId);
@@ -1003,7 +1003,7 @@
r.delayedStop = false;
r.fgRequired = fgRequired;
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
- service, neededGrants, callingUid, callingProcessName));
+ service, neededGrants, callingUid, callingProcessName, callingPackage));
if (fgRequired) {
// We are now effectively running a foreground service.
@@ -1088,7 +1088,7 @@
r.allowBgActivityStartsOnServiceStart(backgroundStartPrivileges);
}
ComponentName cmp = startServiceInnerLocked(smap, service, r, callerFg, addToStarting,
- callingUid, callingProcessName, wasStartRequested);
+ callingUid, callingProcessName, wasStartRequested, callingPackage);
return cmp;
}
@@ -1241,7 +1241,7 @@
try {
startServiceInnerLocked(s, serviceIntent, callingUid, callingPid,
callingProcessName, fgRequired, callerFg,
- backgroundStartPrivileges);
+ backgroundStartPrivileges, callingPackage);
} catch (TransactionTooLargeException e) {
/* ignore - local call */
}
@@ -1287,7 +1287,7 @@
ComponentName startServiceInnerLocked(ServiceMap smap, Intent service, ServiceRecord r,
boolean callerFg, boolean addToStarting, int callingUid, String callingProcessName,
- boolean wasStartRequested) throws TransactionTooLargeException {
+ boolean wasStartRequested, String callingPackage) throws TransactionTooLargeException {
synchronized (mAm.mProcessStats.mLock) {
final ServiceState stracker = r.getTracker();
if (stracker != null) {
@@ -1328,7 +1328,9 @@
: SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM),
getShortProcessNameForStats(callingUid, callingProcessName),
getShortServiceNameForStats(r),
- packageState);
+ packageState,
+ packageName,
+ callingPackage);
if (r.startRequested && addToStarting) {
boolean first = smap.mStartingBackground.size() == 0;
@@ -3661,7 +3663,9 @@
: SERVICE_REQUEST_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM),
getShortProcessNameForStats(callingUid, callerApp.processName),
getShortServiceNameForStats(s),
- packageState);
+ packageState,
+ s.packageName,
+ callerApp.info.packageName);
if (DEBUG_SERVICE) Slog.v(TAG_SERVICE, "Bind " + s + " with " + b
+ ": received=" + b.intent.received
@@ -5253,7 +5257,7 @@
// be called.
if (r.startRequested && r.callStart && r.pendingStarts.size() == 0) {
r.pendingStarts.add(new ServiceRecord.StartItem(r, false, r.makeNextStartId(),
- null, null, 0, null));
+ null, null, 0, null, null));
}
sendServiceArgsLocked(r, execInFg, true);
@@ -6247,7 +6251,7 @@
stopServiceLocked(sr, true);
} else {
sr.pendingStarts.add(new ServiceRecord.StartItem(sr, true,
- sr.getLastStartId(), baseIntent, null, 0, null));
+ sr.getLastStartId(), baseIntent, null, 0, null, null));
if (sr.app != null && sr.app.getThread() != null) {
// We always run in the foreground, since this is called as
// part of the "remove task" UI operation.
@@ -7318,7 +7322,7 @@
if (!r.mAllowWhileInUsePermissionInFgs
|| (r.mAllowStartForeground == REASON_DENIED)) {
final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked(
- callingPackage, callingPid, callingUid, r, backgroundStartPrivileges,
+ callingPackage, callingPid, callingUid, r.app, backgroundStartPrivileges,
isBindService);
if (!r.mAllowWhileInUsePermissionInFgs) {
r.mAllowWhileInUsePermissionInFgs = (allowWhileInUse != REASON_DENIED);
@@ -7345,7 +7349,7 @@
return true;
}
final @ReasonCode int allowWhileInUse = shouldAllowFgsWhileInUsePermissionLocked(
- callingPackage, callingPid, callingUid, null /* serviceRecord */,
+ callingPackage, callingPid, callingUid, null /* targetProcess */,
BackgroundStartPrivileges.NONE, false);
@ReasonCode int allowStartFgs = shouldAllowFgsStartForegroundNoBindingCheckLocked(
allowWhileInUse, callingPid, callingUid, callingPackage, null /* targetService */,
@@ -7362,13 +7366,14 @@
/**
* Should allow while-in-use permissions in FGS or not.
* A typical BG started FGS is not allowed to have while-in-use permissions.
+ *
* @param callingPackage caller app's package name.
- * @param callingUid caller app's uid.
- * @param targetService the service to start.
+ * @param callingUid caller app's uid.
+ * @param targetProcess the process of the service to start.
* @return {@link ReasonCode}
*/
private @ReasonCode int shouldAllowFgsWhileInUsePermissionLocked(String callingPackage,
- int callingPid, int callingUid, @Nullable ServiceRecord targetService,
+ int callingPid, int callingUid, @Nullable ProcessRecord targetProcess,
BackgroundStartPrivileges backgroundStartPrivileges, boolean isBindService) {
int ret = REASON_DENIED;
@@ -7436,8 +7441,8 @@
}
if (ret == REASON_DENIED) {
- if (targetService != null && targetService.app != null) {
- ActiveInstrumentation instr = targetService.app.getActiveInstrumentation();
+ if (targetProcess != null) {
+ ActiveInstrumentation instr = targetProcess.getActiveInstrumentation();
if (instr != null && instr.mHasBackgroundActivityStartsPermission) {
ret = REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
}
@@ -7522,7 +7527,7 @@
final @ReasonCode int allowWhileInUse2 =
shouldAllowFgsWhileInUsePermissionLocked(
clientPackageName,
- clientPid, clientUid, null /* serviceRecord */,
+ clientPid, clientUid, null /* targetProcess */,
BackgroundStartPrivileges.NONE, false);
final @ReasonCode int allowStartFgs =
shouldAllowFgsStartForegroundNoBindingCheckLocked(
@@ -7942,11 +7947,18 @@
boolean canAllowWhileInUsePermissionInFgsLocked(int callingPid, int callingUid,
String callingPackage) {
return shouldAllowFgsWhileInUsePermissionLocked(callingPackage, callingPid, callingUid,
- /* targetService */ null,
+ /* targetProcess */ null,
BackgroundStartPrivileges.NONE, false)
!= REASON_DENIED;
}
+ boolean canAllowWhileInUsePermissionInFgsLocked(int callingPid, int callingUid,
+ String callingPackage, @Nullable ProcessRecord targetProcess,
+ @NonNull BackgroundStartPrivileges backgroundStartPrivileges) {
+ return shouldAllowFgsWhileInUsePermissionLocked(callingPackage, callingPid, callingUid,
+ targetProcess, backgroundStartPrivileges, false) != REASON_DENIED;
+ }
+
/**
* Checks if a given packageName belongs to a given uid.
* @param packageName the package of the caller
diff --git a/services/core/java/com/android/server/am/ActivityManagerConstants.java b/services/core/java/com/android/server/am/ActivityManagerConstants.java
index 4fa28a1..82c4796a 100644
--- a/services/core/java/com/android/server/am/ActivityManagerConstants.java
+++ b/services/core/java/com/android/server/am/ActivityManagerConstants.java
@@ -118,6 +118,8 @@
static final String KEY_PROCESS_CRASH_COUNT_LIMIT = "process_crash_count_limit";
static final String KEY_BOOT_TIME_TEMP_ALLOWLIST_DURATION = "boot_time_temp_allowlist_duration";
static final String KEY_FG_TO_BG_FGS_GRACE_DURATION = "fg_to_bg_fgs_grace_duration";
+ static final String KEY_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION =
+ "vis_to_invis_uij_schedule_grace_duration";
static final String KEY_FGS_START_FOREGROUND_TIMEOUT = "fgs_start_foreground_timeout";
static final String KEY_FGS_ATOM_SAMPLE_RATE = "fgs_atom_sample_rate";
static final String KEY_FGS_START_ALLOWED_LOG_SAMPLE_RATE = "fgs_start_allowed_log_sample_rate";
@@ -191,6 +193,8 @@
private static final int DEFAULT_PROCESS_CRASH_COUNT_LIMIT = 12;
private static final int DEFAULT_BOOT_TIME_TEMP_ALLOWLIST_DURATION = 20 * 1000;
private static final long DEFAULT_FG_TO_BG_FGS_GRACE_DURATION = 5 * 1000;
+ private static final long DEFAULT_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION =
+ DEFAULT_FG_TO_BG_FGS_GRACE_DURATION;
private static final int DEFAULT_FGS_START_FOREGROUND_TIMEOUT_MS = 10 * 1000;
private static final float DEFAULT_FGS_ATOM_SAMPLE_RATE = 1; // 100 %
private static final float DEFAULT_FGS_START_ALLOWED_LOG_SAMPLE_RATE = 0.25f; // 25%
@@ -680,6 +684,15 @@
volatile long mFgToBgFgsGraceDuration = DEFAULT_FG_TO_BG_FGS_GRACE_DURATION;
/**
+ * The grace period in milliseconds to allow a process to schedule a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}
+ * after switching from visible to a non-visible state.
+ * Currently it's only applicable to its activities.
+ */
+ volatile long mVisibleToInvisibleUijScheduleGraceDurationMs =
+ DEFAULT_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION;
+
+ /**
* When service started from background, before the timeout it can be promoted to FGS by calling
* Service.startForeground().
*/
@@ -1123,6 +1136,9 @@
case KEY_FG_TO_BG_FGS_GRACE_DURATION:
updateFgToBgFgsGraceDuration();
break;
+ case KEY_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION:
+ updateFgToBgFgsGraceDuration();
+ break;
case KEY_FGS_START_FOREGROUND_TIMEOUT:
updateFgsStartForegroundTimeout();
break;
@@ -1598,6 +1614,13 @@
DEFAULT_FG_TO_BG_FGS_GRACE_DURATION);
}
+ private void updateVisibleToInvisibleUijScheduleGraceDuration() {
+ mVisibleToInvisibleUijScheduleGraceDurationMs = DeviceConfig.getLong(
+ DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
+ KEY_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION,
+ DEFAULT_VISIBLE_TO_INVISIBLE_UIJ_SCHEDULE_GRACE_DURATION);
+ }
+
private void updateFgsStartForegroundTimeout() {
mFgsStartForegroundTimeoutMs = DeviceConfig.getLong(
DeviceConfig.NAMESPACE_ACTIVITY_MANAGER,
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index c72a720..9eb482e 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -23,6 +23,7 @@
import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
import static android.Manifest.permission.MANAGE_ACTIVITY_TASKS;
import static android.Manifest.permission.MANAGE_USERS;
+import static android.Manifest.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND;
import static android.Manifest.permission.START_ACTIVITIES_FROM_BACKGROUND;
import static android.Manifest.permission.START_FOREGROUND_SERVICES_FROM_BACKGROUND;
import static android.app.ActivityManager.INSTR_FLAG_ALWAYS_CHECK_SIGNATURE;
@@ -32,6 +33,7 @@
import static android.app.ActivityManager.INSTR_FLAG_NO_RESTART;
import static android.app.ActivityManager.INTENT_SENDER_ACTIVITY;
import static android.app.ActivityManager.PROCESS_CAPABILITY_ALL;
+import static android.app.ActivityManager.PROCESS_STATE_BOUND_TOP;
import static android.app.ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT;
import static android.app.ActivityManager.PROCESS_STATE_TOP;
@@ -60,9 +62,22 @@
import static android.os.IServiceManager.DUMP_FLAG_PRIORITY_NORMAL;
import static android.os.IServiceManager.DUMP_FLAG_PROTO;
import static android.os.InputConstants.DEFAULT_DISPATCHING_TIMEOUT_MILLIS;
+import static android.os.PowerExemptionManager.REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD;
+import static android.os.PowerExemptionManager.REASON_BACKGROUND_ACTIVITY_PERMISSION;
+import static android.os.PowerExemptionManager.REASON_COMPANION_DEVICE_MANAGER;
+import static android.os.PowerExemptionManager.REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION;
+import static android.os.PowerExemptionManager.REASON_PROC_STATE_BTOP;
+import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT;
+import static android.os.PowerExemptionManager.REASON_PROC_STATE_PERSISTENT_UI;
+import static android.os.PowerExemptionManager.REASON_PROC_STATE_TOP;
+import static android.os.PowerExemptionManager.REASON_START_ACTIVITY_FLAG;
+import static android.os.PowerExemptionManager.REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
import static android.os.PowerExemptionManager.REASON_SYSTEM_ALLOW_LISTED;
+import static android.os.PowerExemptionManager.REASON_SYSTEM_UID;
+import static android.os.PowerExemptionManager.REASON_UID_VISIBLE;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
import static android.os.PowerExemptionManager.TEMPORARY_ALLOW_LIST_TYPE_NONE;
+import static android.os.PowerExemptionManager.getReasonCodeFromProcState;
import static android.os.Process.BLUETOOTH_UID;
import static android.os.Process.FIRST_APPLICATION_UID;
import static android.os.Process.INVALID_UID;
@@ -99,7 +114,6 @@
import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
import static android.provider.Settings.Global.DEBUG_APP;
import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
-import static android.text.format.DateUtils.DAY_IN_MILLIS;
import static android.util.FeatureFlagUtils.SETTINGS_ENABLE_MONITOR_PHANTOM_PROCS;
import static android.view.Display.INVALID_DISPLAY;
@@ -108,7 +122,6 @@
import static com.android.internal.util.FrameworkStatsLog.UNSAFE_INTENT_EVENT_REPORTED__EVENT_TYPE__NEW_MUTABLE_IMPLICIT_PENDING_INTENT_RETRIEVED;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALLOWLISTS;
-import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKGROUND_CHECK;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
@@ -176,6 +189,7 @@
import android.app.ActivityManager.ProcessCapability;
import android.app.ActivityManager.RestrictionLevel;
import android.app.ActivityManager.RunningTaskInfo;
+import android.app.ActivityManager.UidFrozenStateChangedCallback.UidFrozenState;
import android.app.ActivityManagerInternal;
import android.app.ActivityManagerInternal.BindServiceEventListener;
import android.app.ActivityManagerInternal.BroadcastEventListener;
@@ -208,6 +222,7 @@
import android.app.IStopUserCallback;
import android.app.ITaskStackListener;
import android.app.IUiAutomationConnection;
+import android.app.IUidFrozenStateChangedCallback;
import android.app.IUidObserver;
import android.app.IUnsafeIntentStrictModeCallback;
import android.app.IUserSwitchObserver;
@@ -316,6 +331,7 @@
import android.os.PowerManagerInternal;
import android.os.Process;
import android.os.RemoteCallback;
+import android.os.RemoteCallbackList;
import android.os.RemoteException;
import android.os.ResultReceiver;
import android.os.ServiceManager;
@@ -353,7 +369,6 @@
import android.util.PrintWriterPrinter;
import android.util.Slog;
import android.util.SparseArray;
-import android.util.SparseBooleanArray;
import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.proto.ProtoOutputStream;
@@ -390,7 +405,6 @@
import com.android.internal.os.TimeoutRecord;
import com.android.internal.os.TransferPipe;
import com.android.internal.os.Zygote;
-import com.android.internal.os.anr.AnrLatencyTracker;
import com.android.internal.policy.AttributeCache;
import com.android.internal.protolog.common.ProtoLog;
import com.android.internal.util.ArrayUtils;
@@ -469,14 +483,10 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
-import java.io.StringWriter;
-import java.nio.charset.StandardCharsets;
-import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
-import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -487,18 +497,13 @@
import java.util.Objects;
import java.util.Set;
import java.util.UUID;
-import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executor;
-import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
-import java.util.concurrent.atomic.AtomicLong;
import java.util.function.BiFunction;
import java.util.function.Consumer;
-import java.util.function.Supplier;
public class ActivityManagerService extends IActivityManager.Stub
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback, ActivityManagerGlobalLock {
@@ -536,8 +541,6 @@
static final String SYSTEM_USER_HOME_NEEDED = "ro.system_user_home_needed";
- public static final String ANR_TRACE_DIR = "/data/anr";
-
// Maximum number of receivers an app can register.
private static final int MAX_RECEIVERS_ALLOWED_PER_APP = 1000;
@@ -599,10 +602,6 @@
private static final int MAX_BUGREPORT_TITLE_SIZE = 100;
private static final int MAX_BUGREPORT_DESCRIPTION_SIZE = 150;
- private static final int NATIVE_DUMP_TIMEOUT_MS =
- 2000 * Build.HW_TIMEOUT_MULTIPLIER; // 2 seconds;
- private static final int JAVA_DUMP_MINIMUM_SIZE = 100; // 100 bytes.
-
OomAdjuster mOomAdjuster;
static final String EXTRA_TITLE = "android.intent.extra.TITLE";
@@ -3409,432 +3408,6 @@
}
}
- /**
- * If a stack trace dump file is configured, dump process stack traces.
- * @param firstPids of dalvik VM processes to dump stack traces for first
- * @param lastPids of dalvik VM processes to dump stack traces for last
- * @param nativePids optional list of native pids to dump stack crawls
- * @param logExceptionCreatingFile optional writer to which we log errors creating the file
- * @param auxiliaryTaskExecutor executor to execute auxiliary tasks on
- * @param latencyTracker the latency tracker instance of the current ANR.
- */
- public static File dumpStackTraces(ArrayList<Integer> firstPids,
- ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
- Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
- @NonNull Executor auxiliaryTaskExecutor, AnrLatencyTracker latencyTracker) {
- return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePidsFuture,
- logExceptionCreatingFile, null, null, null, auxiliaryTaskExecutor, latencyTracker);
- }
-
- /**
- * If a stack trace dump file is configured, dump process stack traces.
- * @param firstPids of dalvik VM processes to dump stack traces for first
- * @param lastPids of dalvik VM processes to dump stack traces for last
- * @param nativePids optional list of native pids to dump stack crawls
- * @param logExceptionCreatingFile optional writer to which we log errors creating the file
- * @param subject optional line related to the error
- * @param criticalEventSection optional lines containing recent critical events.
- * @param auxiliaryTaskExecutor executor to execute auxiliary tasks on
- * @param latencyTracker the latency tracker instance of the current ANR.
- */
- public static File dumpStackTraces(ArrayList<Integer> firstPids,
- ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
- Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
- String subject, String criticalEventSection, @NonNull Executor auxiliaryTaskExecutor,
- AnrLatencyTracker latencyTracker) {
- return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePidsFuture,
- logExceptionCreatingFile, null, subject, criticalEventSection,
- auxiliaryTaskExecutor, latencyTracker);
- }
-
- /**
- * @param firstPidEndOffset Optional, when it's set, it receives the start/end offset
- * of the very first pid to be dumped.
- */
- /* package */ static File dumpStackTraces(ArrayList<Integer> firstPids,
- ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
- Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
- AtomicLong firstPidEndOffset, String subject, String criticalEventSection,
- @NonNull Executor auxiliaryTaskExecutor, AnrLatencyTracker latencyTracker) {
- try {
-
- if (latencyTracker != null) {
- latencyTracker.dumpStackTracesStarted();
- }
-
- Slog.i(TAG, "dumpStackTraces pids=" + lastPids);
-
- // Measure CPU usage as soon as we're called in order to get a realistic sampling
- // of the top users at the time of the request.
- Supplier<ArrayList<Integer>> extraPidsSupplier = processCpuTracker != null
- ? () -> getExtraPids(processCpuTracker, lastPids, latencyTracker) : null;
- Future<ArrayList<Integer>> extraPidsFuture = null;
- if (extraPidsSupplier != null) {
- extraPidsFuture =
- CompletableFuture.supplyAsync(extraPidsSupplier, auxiliaryTaskExecutor);
- }
-
- final File tracesDir = new File(ANR_TRACE_DIR);
-
- // NOTE: We should consider creating the file in native code atomically once we've
- // gotten rid of the old scheme of dumping and lot of the code that deals with paths
- // can be removed.
- File tracesFile;
- try {
- tracesFile = createAnrDumpFile(tracesDir);
- } catch (IOException e) {
- Slog.w(TAG, "Exception creating ANR dump file:", e);
- if (logExceptionCreatingFile != null) {
- logExceptionCreatingFile.append(
- "----- Exception creating ANR dump file -----\n");
- e.printStackTrace(new PrintWriter(logExceptionCreatingFile));
- }
- if (latencyTracker != null) {
- latencyTracker.anrSkippedDumpStackTraces();
- }
- return null;
- }
-
- if (subject != null || criticalEventSection != null) {
- appendtoANRFile(tracesFile.getAbsolutePath(),
- (subject != null ? "Subject: " + subject + "\n\n" : "")
- + (criticalEventSection != null ? criticalEventSection : ""));
- }
-
- long firstPidEndPos = dumpStackTraces(
- tracesFile.getAbsolutePath(), firstPids, nativePidsFuture,
- extraPidsFuture, latencyTracker);
- if (firstPidEndOffset != null) {
- firstPidEndOffset.set(firstPidEndPos);
- }
- // Each set of ANR traces is written to a separate file and dumpstate will process
- // all such files and add them to a captured bug report if they're recent enough.
- maybePruneOldTraces(tracesDir);
-
- return tracesFile;
- } finally {
- if (latencyTracker != null) {
- latencyTracker.dumpStackTracesEnded();
- }
- }
-
- }
-
- @GuardedBy("ActivityManagerService.class")
- private static SimpleDateFormat sAnrFileDateFormat;
- static final String ANR_FILE_PREFIX = "anr_";
-
- private static ArrayList<Integer> getExtraPids(ProcessCpuTracker processCpuTracker,
- SparseBooleanArray lastPids, AnrLatencyTracker latencyTracker) {
- if (latencyTracker != null) {
- latencyTracker.processCpuTrackerMethodsCalled();
- }
- ArrayList<Integer> extraPids = new ArrayList<>();
- processCpuTracker.init();
- try {
- Thread.sleep(200);
- } catch (InterruptedException ignored) {
- }
-
- processCpuTracker.update();
-
- // We'll take the stack crawls of just the top apps using CPU.
- final int workingStatsNumber = processCpuTracker.countWorkingStats();
- for (int i = 0; i < workingStatsNumber && extraPids.size() < 2; i++) {
- ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
- if (lastPids.indexOfKey(stats.pid) >= 0) {
- if (DEBUG_ANR) {
- Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
- }
-
- extraPids.add(stats.pid);
- } else {
- Slog.i(TAG,
- "Skipping next CPU consuming process, not a java proc: "
- + stats.pid);
- }
- }
- if (latencyTracker != null) {
- latencyTracker.processCpuTrackerMethodsReturned();
- }
- return extraPids;
- }
-
- private static synchronized File createAnrDumpFile(File tracesDir) throws IOException {
- if (sAnrFileDateFormat == null) {
- sAnrFileDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
- }
-
- final String formattedDate = sAnrFileDateFormat.format(new Date());
- final File anrFile = new File(tracesDir, ANR_FILE_PREFIX + formattedDate);
-
- if (anrFile.createNewFile()) {
- FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
- return anrFile;
- } else {
- throw new IOException("Unable to create ANR dump file: createNewFile failed");
- }
- }
-
- /**
- * Prune all trace files that are more than a day old.
- *
- * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
- * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
- * since it's the system_server that creates trace files for most ANRs.
- */
- private static void maybePruneOldTraces(File tracesDir) {
- final File[] files = tracesDir.listFiles();
- if (files == null) return;
-
- final int max = SystemProperties.getInt("tombstoned.max_anr_count", 64);
- final long now = System.currentTimeMillis();
- try {
- Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed());
- for (int i = 0; i < files.length; ++i) {
- if (i > max || (now - files[i].lastModified()) > DAY_IN_MILLIS) {
- if (!files[i].delete()) {
- Slog.w(TAG, "Unable to prune stale trace file: " + files[i]);
- }
- }
- }
- } catch (IllegalArgumentException e) {
- // The modification times changed while we were sorting. Bail...
- // https://issuetracker.google.com/169836837
- Slog.w(TAG, "tombstone modification times changed while sorting; not pruning", e);
- }
- }
-
- /**
- * Dump java traces for process {@code pid} to the specified file. If java trace dumping
- * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
- * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
- * attempting to obtain native traces in the case of a failure. Returns the total time spent
- * capturing traces.
- */
- private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
- final long timeStart = SystemClock.elapsedRealtime();
- int headerSize = writeUptimeStartHeaderForPid(pid, fileName);
- boolean javaSuccess = Debug.dumpJavaBacktraceToFileTimeout(pid, fileName,
- (int) (timeoutMs / 1000));
- if (javaSuccess) {
- // Check that something is in the file, actually. Try-catch should not be necessary,
- // but better safe than sorry.
- try {
- long size = new File(fileName).length();
- if ((size - headerSize) < JAVA_DUMP_MINIMUM_SIZE) {
- Slog.w(TAG, "Successfully created Java ANR file is empty!");
- javaSuccess = false;
- }
- } catch (Exception e) {
- Slog.w(TAG, "Unable to get ANR file size", e);
- javaSuccess = false;
- }
- }
- if (!javaSuccess) {
- Slog.w(TAG, "Dumping Java threads failed, initiating native stack dump.");
- if (!Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
- (NATIVE_DUMP_TIMEOUT_MS / 1000))) {
- Slog.w(TAG, "Native stack dump failed!");
- }
- }
-
- return SystemClock.elapsedRealtime() - timeStart;
- }
-
- private static int appendtoANRFile(String fileName, String text) {
- try (FileOutputStream fos = new FileOutputStream(fileName, true)) {
- byte[] header = text.getBytes(StandardCharsets.UTF_8);
- fos.write(header);
- return header.length;
- } catch (IOException e) {
- Slog.w(TAG, "Exception writing to ANR dump file:", e);
- return 0;
- }
- }
-
- /*
- * Writes a header containing the process id and the current system uptime.
- */
- private static int writeUptimeStartHeaderForPid(int pid, String fileName) {
- return appendtoANRFile(fileName, "----- dumping pid: " + pid + " at "
- + SystemClock.uptimeMillis() + "\n");
- }
-
-
- /**
- * @return The end offset of the trace of the very first PID
- */
- public static long dumpStackTraces(String tracesFile,
- ArrayList<Integer> firstPids, Future<ArrayList<Integer>> nativePidsFuture,
- Future<ArrayList<Integer>> extraPidsFuture, AnrLatencyTracker latencyTracker) {
-
- Slog.i(TAG, "Dumping to " + tracesFile);
-
- // We don't need any sort of inotify based monitoring when we're dumping traces via
- // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
- // control of all writes to the file in question.
-
- // We must complete all stack dumps within 20 seconds.
- long remainingTime = 20 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
-
- // As applications are usually interested with the ANR stack traces, but we can't share with
- // them the stack traces other than their own stacks. So after the very first PID is
- // dumped, remember the current file size.
- long firstPidEnd = -1;
-
- // First collect all of the stacks of the most important pids.
- if (firstPids != null) {
- if (latencyTracker != null) {
- latencyTracker.dumpingFirstPidsStarted();
- }
-
- int num = firstPids.size();
- for (int i = 0; i < num; i++) {
- final int pid = firstPids.get(i);
- // We don't copy ANR traces from the system_server intentionally.
- final boolean firstPid = i == 0 && MY_PID != pid;
- if (latencyTracker != null) {
- latencyTracker.dumpingPidStarted(pid);
- }
-
- Slog.i(TAG, "Collecting stacks for pid " + pid);
- final long timeTaken = dumpJavaTracesTombstoned(pid, tracesFile,
- remainingTime);
- if (latencyTracker != null) {
- latencyTracker.dumpingPidEnded();
- }
-
- remainingTime -= timeTaken;
- if (remainingTime <= 0) {
- Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + pid
- + "); deadline exceeded.");
- return firstPidEnd;
- }
-
- if (firstPid) {
- firstPidEnd = new File(tracesFile).length();
- // Full latency dump
- if (latencyTracker != null) {
- appendtoANRFile(tracesFile,
- latencyTracker.dumpAsCommaSeparatedArrayWithHeader());
- }
- }
- if (DEBUG_ANR) {
- Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
- }
- }
- if (latencyTracker != null) {
- latencyTracker.dumpingFirstPidsEnded();
- }
- }
-
- // Next collect the stacks of the native pids
- ArrayList<Integer> nativePids = collectPids(nativePidsFuture, "native pids");
-
- Slog.i(TAG, "dumpStackTraces nativepids=" + nativePids);
-
- if (nativePids != null) {
- if (latencyTracker != null) {
- latencyTracker.dumpingNativePidsStarted();
- }
- for (int pid : nativePids) {
- Slog.i(TAG, "Collecting stacks for native pid " + pid);
- final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
-
- if (latencyTracker != null) {
- latencyTracker.dumpingPidStarted(pid);
- }
- final long start = SystemClock.elapsedRealtime();
- Debug.dumpNativeBacktraceToFileTimeout(
- pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
- final long timeTaken = SystemClock.elapsedRealtime() - start;
- if (latencyTracker != null) {
- latencyTracker.dumpingPidEnded();
- }
- remainingTime -= timeTaken;
- if (remainingTime <= 0) {
- Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid +
- "); deadline exceeded.");
- return firstPidEnd;
- }
-
- if (DEBUG_ANR) {
- Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
- }
- }
- if (latencyTracker != null) {
- latencyTracker.dumpingNativePidsEnded();
- }
- }
-
- // Lastly, dump stacks for all extra PIDs from the CPU tracker.
- ArrayList<Integer> extraPids = collectPids(extraPidsFuture, "extra pids");
-
- if (extraPidsFuture != null) {
- try {
- extraPids = extraPidsFuture.get();
- } catch (ExecutionException e) {
- Slog.w(TAG, "Failed to collect extra pids", e.getCause());
- } catch (InterruptedException e) {
- Slog.w(TAG, "Interrupted while collecting extra pids", e);
- }
- }
- Slog.i(TAG, "dumpStackTraces extraPids=" + extraPids);
-
- if (extraPids != null) {
- if (latencyTracker != null) {
- latencyTracker.dumpingExtraPidsStarted();
- }
- for (int pid : extraPids) {
- Slog.i(TAG, "Collecting stacks for extra pid " + pid);
- if (latencyTracker != null) {
- latencyTracker.dumpingPidStarted(pid);
- }
- final long timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
- if (latencyTracker != null) {
- latencyTracker.dumpingPidEnded();
- }
- remainingTime -= timeTaken;
- if (remainingTime <= 0) {
- Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid +
- "); deadline exceeded.");
- return firstPidEnd;
- }
-
- if (DEBUG_ANR) {
- Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
- }
- }
- if (latencyTracker != null) {
- latencyTracker.dumpingExtraPidsEnded();
- }
- }
- // Append the dumping footer with the current uptime
- appendtoANRFile(tracesFile, "----- dumping ended at " + SystemClock.uptimeMillis() + "\n");
- Slog.i(TAG, "Done dumping");
-
- return firstPidEnd;
- }
-
- private static ArrayList<Integer> collectPids(Future<ArrayList<Integer>> pidsFuture,
- String logName) {
-
- ArrayList<Integer> pids = null;
-
- if (pidsFuture == null) {
- return pids;
- }
- try {
- pids = pidsFuture.get();
- } catch (ExecutionException e) {
- Slog.w(TAG, "Failed to collect " + logName, e.getCause());
- } catch (InterruptedException e) {
- Slog.w(TAG, "Interrupted while collecting " + logName , e);
- }
- return pids;
- }
-
@Override
public boolean clearApplicationUserData(final String packageName, boolean keepState,
final IPackageDataObserver observer, int userId) {
@@ -6527,13 +6100,154 @@
@NonNull
private BackgroundStartPrivileges getBackgroundStartPrivileges(int uid) {
synchronized (mProcLock) {
+ final UidRecord uidRecord = mProcessList.getUidRecordLOSP(uid);
+ if (uidRecord == null) {
+ return BackgroundStartPrivileges.NONE;
+ }
mGetBackgroundStartPrivilegesFunctor.prepare(uid);
- mProcessList.forEachLruProcessesLOSP(false, mGetBackgroundStartPrivilegesFunctor);
+ uidRecord.forEachProcess(mGetBackgroundStartPrivilegesFunctor);
return mGetBackgroundStartPrivilegesFunctor.getResult();
}
}
/**
+ * Returns true if the reasonCode is included in the base set of reasons an app may be
+ * allowed to schedule a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}.
+ * This is a shortcut and <b>DOES NOT</b> include all reasons.
+ * Use {@link #canScheduleUserInitiatedJobs(int, int, String)} to cover all cases.
+ */
+ private boolean doesReasonCodeAllowSchedulingUserInitiatedJobs(int reasonCode) {
+ switch (reasonCode) {
+ case REASON_PROC_STATE_PERSISTENT:
+ case REASON_PROC_STATE_PERSISTENT_UI:
+ case REASON_PROC_STATE_TOP:
+ case REASON_PROC_STATE_BTOP:
+ case REASON_UID_VISIBLE:
+ case REASON_SYSTEM_UID:
+ case REASON_START_ACTIVITY_FLAG:
+ case REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD:
+ case REASON_SYSTEM_ALERT_WINDOW_PERMISSION:
+ case REASON_COMPANION_DEVICE_MANAGER:
+ case REASON_BACKGROUND_ACTIVITY_PERMISSION:
+ case REASON_INSTR_BACKGROUND_ACTIVITY_PERMISSION:
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Returns true if the ProcessRecord has some conditions that allow the app to schedule a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}.
+ * This is a shortcut and <b>DOES NOT</b> include all reasons.
+ * Use {@link #canScheduleUserInitiatedJobs(int, int, String)} to cover all cases.
+ */
+ @GuardedBy(anyOf = {"this", "mProcLock"})
+ private boolean isProcessInStateToScheduleUserInitiatedJobsLocked(
+ @Nullable ProcessRecord pr, long nowElapsed) {
+ if (pr == null) {
+ return false;
+ }
+
+ final BackgroundStartPrivileges backgroundStartPrivileges =
+ pr.getBackgroundStartPrivileges();
+ // Is the allow activity background start flag on?
+ if (backgroundStartPrivileges.allowsBackgroundActivityStarts()) {
+ // REASON_START_ACTIVITY_FLAG;
+ return true;
+ }
+
+ final ProcessStateRecord state = pr.mState;
+ final int procstate = state.getCurProcState();
+ if (procstate <= PROCESS_STATE_BOUND_TOP) {
+ if (doesReasonCodeAllowSchedulingUserInitiatedJobs(
+ getReasonCodeFromProcState(procstate))) {
+ return true;
+ }
+ }
+
+ final long lastInvisibleTime = state.getLastInvisibleTime();
+ if (lastInvisibleTime > 0 && lastInvisibleTime < Long.MAX_VALUE) {
+ final long timeSinceVisibleMs = nowElapsed - lastInvisibleTime;
+ if (timeSinceVisibleMs < mConstants.mVisibleToInvisibleUijScheduleGraceDurationMs) {
+ // REASON_ACTIVITY_VISIBILITY_GRACE_PERIOD
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ /**
+ * Returns whether the app in question is in a state where we allow scheduling a
+ * {@link android.app.job.JobInfo.Builder#setUserInitiated(boolean) user-initiated job}.
+ */
+ // TODO(262260570): log allow reason to an atom
+ private boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName) {
+ synchronized (this) {
+ final ProcessRecord processRecord;
+ synchronized (mPidsSelfLocked) {
+ processRecord = mPidsSelfLocked.get(pid);
+ }
+
+ final long nowElapsed = SystemClock.elapsedRealtime();
+ final BackgroundStartPrivileges backgroundStartPrivileges;
+ if (processRecord != null) {
+ if (isProcessInStateToScheduleUserInitiatedJobsLocked(processRecord, nowElapsed)) {
+ return true;
+ }
+ backgroundStartPrivileges = processRecord.getBackgroundStartPrivileges();
+ } else {
+ backgroundStartPrivileges = getBackgroundStartPrivileges(uid);
+ }
+ // Is the allow activity background start flag on?
+ if (backgroundStartPrivileges.allowsBackgroundActivityStarts()) {
+ // REASON_START_ACTIVITY_FLAG;
+ return true;
+ }
+
+ // We allow scheduling a user-initiated job when the app is in the TOP or a
+ // Background Activity Launch approved state. These are cases that indicate the user
+ // has interacted with the app and therefore it is reasonable to believe the app may
+ // attempt to schedule a user-initiated job in response to the user interaction.
+ // As of Android UDC, the conditions required to grant a while-in-use permission
+ // covers the majority of those cases, and so we piggyback on that logic as the base.
+ // Missing cases are added after.
+ if (mServices.canAllowWhileInUsePermissionInFgsLocked(
+ pid, uid, pkgName, processRecord, backgroundStartPrivileges)) {
+ return true;
+ }
+
+ final UidRecord uidRecord = mProcessList.getUidRecordLOSP(uid);
+ if (uidRecord != null) {
+ for (int i = uidRecord.getNumOfProcs() - 1; i >= 0; --i) {
+ ProcessRecord pr = uidRecord.getProcessRecordByIndex(i);
+ if (isProcessInStateToScheduleUserInitiatedJobsLocked(pr, nowElapsed)) {
+ return true;
+ }
+ }
+ }
+
+ if (mAtmInternal.hasSystemAlertWindowPermission(uid, pid, pkgName)) {
+ // REASON_SYSTEM_ALERT_WINDOW_PERMISSION;
+ return true;
+ }
+
+ final int userId = UserHandle.getUserId(uid);
+ final boolean isCompanionApp = mInternal.isAssociatedCompanionApp(userId, uid);
+ if (isCompanionApp) {
+ if (checkPermission(REQUEST_COMPANION_RUN_IN_BACKGROUND, pid, uid)
+ == PERMISSION_GRANTED) {
+ // REASON_COMPANION_DEVICE_MANAGER;
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ /**
* @return allowlist tag for a uid from mPendingTempAllowlist, null if not currently on
* the allowlist
*/
@@ -7757,6 +7471,66 @@
return uidRecord != null && !uidRecord.isSetIdle();
}
+ @GuardedBy("mUidFrozenStateChangedCallbackList")
+ private final RemoteCallbackList<IUidFrozenStateChangedCallback>
+ mUidFrozenStateChangedCallbackList = new RemoteCallbackList<>();
+
+ /**
+ * Register a {@link IUidFrozenStateChangedCallback} to receive Uid frozen state events.
+ *
+ * @param callback remote callback object to be registered
+ */
+ public void registerUidFrozenStateChangedCallback(
+ @NonNull IUidFrozenStateChangedCallback callback) {
+ synchronized (mUidFrozenStateChangedCallbackList) {
+ boolean registered = mUidFrozenStateChangedCallbackList.register(callback);
+ if (!registered) {
+ Slog.w(TAG, "Failed to register with RemoteCallbackList!");
+ }
+ }
+ }
+
+ /**
+ * Unregister a {@link IUidFrozenStateChangedCallback}.
+ *
+ * @param callback remote callback object to be unregistered
+ */
+ public void unregisterUidFrozenStateChangedCallback(
+ @NonNull IUidFrozenStateChangedCallback callback) {
+ synchronized (mUidFrozenStateChangedCallbackList) {
+ mUidFrozenStateChangedCallbackList.unregister(callback);
+ }
+ }
+
+ /**
+ * Notify the system that a UID has been frozen or unfrozen.
+ *
+ * @param uids The Uid(s) in question
+ * @param frozenStates Frozen state for each UID index
+ *
+ * @hide
+ */
+ public void reportUidFrozenStateChanged(@NonNull int[] uids,
+ @UidFrozenState int[] frozenStates) {
+ synchronized (mUidFrozenStateChangedCallbackList) {
+ final int n = mUidFrozenStateChangedCallbackList.beginBroadcast();
+ for (int i = 0; i < n; i++) {
+ try {
+ mUidFrozenStateChangedCallbackList.getBroadcastItem(i).onUidFrozenStateChanged(
+ uids, frozenStates);
+ } catch (RemoteException e) {
+ /*
+ * The process at the other end has died or otherwise gone away.
+ * According to spec, RemoteCallbacklist will take care of unregistering any
+ * object associated with that process - we are safe to ignore the exception
+ * here.
+ */
+ }
+ }
+ mUidFrozenStateChangedCallbackList.finishBroadcast();
+ }
+ }
+
@Override
public void setPersistentVrThread(int tid) {
mActivityTaskManager.setPersistentVrThread(tid);
@@ -9351,7 +9125,9 @@
String logcatSetting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
String maxBytesSetting = Settings.Global.MAX_ERROR_BYTES_PREFIX + dropboxTag;
- int lines = Settings.Global.getInt(mContext.getContentResolver(), logcatSetting, 0);
+ int lines = Build.IS_USER
+ ? 0
+ : Settings.Global.getInt(mContext.getContentResolver(), logcatSetting, 0);
int dropboxMaxSize = Settings.Global.getInt(
mContext.getContentResolver(), maxBytesSetting, DROPBOX_DEFAULT_MAX_SIZE);
int maxDataFileSize = dropboxMaxSize - sb.length()
@@ -13864,7 +13640,7 @@
if (!sdkSandboxManagerLocal.canRegisterBroadcastReceiver(
/*IntentFilter=*/ filter, flags, onlyProtectedBroadcasts)) {
throw new SecurityException("SDK sandbox not allowed to register receiver"
- + " with the given IntentFilter");
+ + " with the given IntentFilter: " + filter.toString());
}
}
@@ -16847,7 +16623,7 @@
*/
public void dumpAllResources(ParcelFileDescriptor fd, PrintWriter pw) throws RemoteException {
final ArrayList<ProcessRecord> processes = new ArrayList<>();
- synchronized (mPidsSelfLocked) {
+ synchronized (this) {
processes.addAll(mProcessList.getLruProcessesLOSP());
}
for (int i = 0, size = processes.size(); i < size; i++) {
@@ -18087,6 +17863,11 @@
return ActivityManagerService.this.getBackgroundStartPrivileges(uid);
}
+ @Override
+ public boolean canScheduleUserInitiatedJobs(int uid, int pid, String pkgName) {
+ return ActivityManagerService.this.canScheduleUserInitiatedJobs(uid, pid, pkgName);
+ }
+
public void reportCurKeyguardUsageEvent(boolean keyguardShowing) {
ActivityManagerService.this.reportGlobalUsageEvent(keyguardShowing
? UsageEvents.Event.KEYGUARD_SHOWN
@@ -18736,13 +18517,17 @@
@Override
public void logFgsApiBegin(@ForegroundServiceApiType int apiType,
int uid, int pid) {
- ActivityManagerService.this.logFgsApiBegin(apiType, uid, pid);
+ synchronized (this) {
+ mServices.logFgsApiBeginLocked(apiType, uid, pid);
+ }
}
@Override
public void logFgsApiEnd(@ForegroundServiceApiType int apiType,
int uid, int pid) {
- ActivityManagerService.this.logFgsApiEnd(apiType, uid, pid);
+ synchronized (this) {
+ mServices.logFgsApiEndLocked(apiType, uid, pid);
+ }
}
@Override
diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java
index 1ba3266..4443636 100644
--- a/services/core/java/com/android/server/am/AppExitInfoTracker.java
+++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java
@@ -1153,7 +1153,7 @@
final ArraySet<String> allFiles = new ArraySet();
final File[] files = mProcExitStoreDir.listFiles((f) -> {
final String name = f.getName();
- boolean trace = name.startsWith(ActivityManagerService.ANR_FILE_PREFIX)
+ boolean trace = name.startsWith(StackTracesDumpHelper.ANR_FILE_PREFIX)
&& name.endsWith(APP_TRACE_FILE_SUFFIX);
if (trace) {
allFiles.add(name);
diff --git a/services/core/java/com/android/server/am/AppRestrictionController.java b/services/core/java/com/android/server/am/AppRestrictionController.java
index 2d779c4..6928bd3 100644
--- a/services/core/java/com/android/server/am/AppRestrictionController.java
+++ b/services/core/java/com/android/server/am/AppRestrictionController.java
@@ -106,7 +106,6 @@
import android.app.usage.AppStandbyInfo;
import android.app.usage.UsageStatsManager;
import android.content.BroadcastReceiver;
-import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -117,7 +116,6 @@
import android.content.pm.PackageManagerInternal;
import android.content.pm.ServiceInfo;
import android.content.pm.ServiceInfo.ForegroundServiceType;
-import android.database.ContentObserver;
import android.graphics.drawable.Icon;
import android.net.Uri;
import android.os.AppBackgroundRestrictionsInfo;
@@ -137,7 +135,6 @@
import android.provider.DeviceConfig.OnPropertiesChangedListener;
import android.provider.DeviceConfig.Properties;
import android.provider.Settings;
-import android.provider.Settings.Global;
import android.telephony.TelephonyManager;
import android.text.TextUtils;
import android.util.ArraySet;
@@ -1069,8 +1066,7 @@
}
}
- final class ConstantsObserver extends ContentObserver implements
- OnPropertiesChangedListener {
+ final class ConstantsObserver implements OnPropertiesChangedListener {
/**
* Whether or not to set the app to restricted standby bucket automatically
* when it's background-restricted.
@@ -1181,8 +1177,6 @@
volatile boolean mBgAutoRestrictAbusiveApps;
- volatile boolean mRestrictedBucketEnabled;
-
volatile long mBgAbusiveNotificationMinIntervalMs;
volatile long mBgLongFgsNotificationMinIntervalMs;
@@ -1215,7 +1209,6 @@
volatile boolean mBgPromptAbusiveAppsToBgRestricted;
ConstantsObserver(Handler handler, Context context) {
- super(handler);
mDefaultBgPromptFgsWithNotiToBgRestricted = context.getResources().getBoolean(
com.android.internal.R.bool.config_bg_prompt_fgs_with_noti_to_bg_restricted);
mDefaultBgPromptAbusiveAppToBgRestricted = context.getResources().getBoolean(
@@ -1261,29 +1254,10 @@
}
}
- @Override
- public void onChange(boolean selfChange) {
- updateSettings();
- }
-
public void start() {
- final ContentResolver cr = mContext.getContentResolver();
- cr.registerContentObserver(Global.getUriFor(Global.ENABLE_RESTRICTED_BUCKET),
- false, this);
- updateSettings();
updateDeviceConfig();
}
- void updateSettings() {
- mRestrictedBucketEnabled = isRestrictedBucketEnabled();
- }
-
- private boolean isRestrictedBucketEnabled() {
- return Global.getInt(mContext.getContentResolver(),
- Global.ENABLE_RESTRICTED_BUCKET,
- Global.DEFAULT_ENABLE_RESTRICTED_BUCKET) == 1;
- }
-
void updateDeviceConfig() {
updateBgAutoRestrictedBucketChanged();
updateBgAutoRestrictAbusiveApps();
@@ -1763,8 +1737,7 @@
.isAppBackgroundRestricted(uid, packageName)) {
return new Pair<>(RESTRICTION_LEVEL_BACKGROUND_RESTRICTED, mEmptyTrackerInfo);
}
- level = mConstantsObserver.mRestrictedBucketEnabled
- && standbyBucket == STANDBY_BUCKET_RESTRICTED
+ level = standbyBucket == STANDBY_BUCKET_RESTRICTED
? RESTRICTION_LEVEL_RESTRICTED_BUCKET
: RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
if (calcTrackers) {
@@ -1811,13 +1784,9 @@
@RestrictionLevel int level = RESTRICTION_LEVEL_UNKNOWN;
@RestrictionLevel int prevLevel = level;
BaseAppStateTracker resultTracker = null;
- final boolean isRestrictedBucketEnabled = mConstantsObserver.mRestrictedBucketEnabled;
for (int i = mAppStateTrackers.size() - 1; i >= 0; i--) {
@RestrictionLevel int l = mAppStateTrackers.get(i).getPolicy()
.getProposedRestrictionLevel(packageName, uid, maxLevel);
- if (!isRestrictedBucketEnabled && l == RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
- l = RESTRICTION_LEVEL_ADAPTIVE_BUCKET;
- }
level = Math.max(level, l);
if (level != prevLevel) {
resultTracker = mAppStateTrackers.get(i);
@@ -2193,9 +2162,6 @@
}
if (level >= RESTRICTION_LEVEL_RESTRICTED_BUCKET
&& curLevel < RESTRICTION_LEVEL_RESTRICTED_BUCKET) {
- if (!mConstantsObserver.mRestrictedBucketEnabled) {
- return;
- }
// Moving the app standby bucket to restricted in the meanwhile.
if (DEBUG_BG_RESTRICTION_CONTROLLER
&& level == RESTRICTION_LEVEL_BACKGROUND_RESTRICTED) {
diff --git a/services/core/java/com/android/server/am/BatteryStatsService.java b/services/core/java/com/android/server/am/BatteryStatsService.java
index d09ca5c..7c84b72 100644
--- a/services/core/java/com/android/server/am/BatteryStatsService.java
+++ b/services/core/java/com/android/server/am/BatteryStatsService.java
@@ -843,7 +843,10 @@
final long sessionStart = mBatteryUsageStatsStore
.getLastBatteryUsageStatsBeforeResetAtomPullTimestamp();
- final long sessionEnd = mStats.getStartClockTime();
+ final long sessionEnd;
+ synchronized (mStats) {
+ sessionEnd = mStats.getStartClockTime();
+ }
final BatteryUsageStatsQuery queryBeforeReset =
new BatteryUsageStatsQuery.Builder()
.setMaxStatsAgeMs(0)
diff --git a/services/core/java/com/android/server/am/BroadcastProcessQueue.java b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
index 7591057..0cdd4e9 100644
--- a/services/core/java/com/android/server/am/BroadcastProcessQueue.java
+++ b/services/core/java/com/android/server/am/BroadcastProcessQueue.java
@@ -385,9 +385,11 @@
public void setProcess(@Nullable ProcessRecord app) {
this.app = app;
if (app != null) {
+ setProcessCached(app.isCached());
setProcessInstrumented(app.getActiveInstrumentation() != null);
setProcessPersistent(app.isPersistent());
} else {
+ setProcessCached(false);
setProcessInstrumented(false);
setProcessPersistent(false);
}
@@ -397,7 +399,8 @@
* Update if this process is in the "cached" state, typically signaling that
* broadcast dispatch should be paused or delayed.
*/
- public void setProcessCached(boolean cached) {
+ @VisibleForTesting
+ void setProcessCached(boolean cached) {
if (mProcessCached != cached) {
mProcessCached = cached;
invalidateRunnableAt();
diff --git a/services/core/java/com/android/server/am/BroadcastQueueImpl.java b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
index c085706..fcddff0 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueImpl.java
@@ -601,7 +601,9 @@
r.dispatchTime - r.enqueueTime,
r.receiverTime - r.dispatchTime,
finishTime - r.receiverTime,
- packageState);
+ packageState,
+ r.curApp.info.packageName,
+ r.callerPackage);
}
if (state == BroadcastRecord.IDLE) {
Slog.w(TAG_BROADCAST, "finishReceiver [" + mQueueName + "] called but state is IDLE");
@@ -780,7 +782,8 @@
BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__RUNTIME,
BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM,
dispatchDelay, receiveDelay, 0 /* finish_delay */,
- SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL);
+ SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL,
+ app != null ? app.info.packageName : null, callingPackage);
}
}
diff --git a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
index 6c2bfe1..8edde71 100644
--- a/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
+++ b/services/core/java/com/android/server/am/BroadcastQueueModernImpl.java
@@ -1122,7 +1122,7 @@
}
r.terminalCount++;
- notifyFinishReceiver(queue, r, index, receiver);
+ notifyFinishReceiver(queue, app, r, index, receiver);
checkFinished = true;
}
// When entire ordered broadcast finished, deliver final result
@@ -1328,7 +1328,9 @@
synchronized (mService) {
BroadcastProcessQueue leaf = mProcessQueues.get(uid);
while (leaf != null) {
- leaf.setProcessCached(cached);
+ // Update internal state by refreshing values previously
+ // read from any known running process
+ leaf.setProcess(leaf.app);
updateQueueDeferred(leaf);
updateRunnableList(leaf);
leaf = leaf.processNameNext;
@@ -1339,7 +1341,7 @@
}, ActivityManager.UID_OBSERVER_CACHED, 0, "android");
// Kick off periodic health checks
- checkHealthLocked();
+ mLocalHandler.sendEmptyMessage(MSG_CHECK_HEALTH);
}
@Override
@@ -1595,9 +1597,10 @@
* typically for internal bookkeeping.
*/
private void notifyFinishReceiver(@Nullable BroadcastProcessQueue queue,
- @NonNull BroadcastRecord r, int index, @NonNull Object receiver) {
+ @Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index,
+ @NonNull Object receiver) {
if (r.wasDeliveryAttempted(index)) {
- logBroadcastDeliveryEventReported(queue, r, index, receiver);
+ logBroadcastDeliveryEventReported(queue, app, r, index, receiver);
}
final boolean recordFinished = (r.terminalCount == r.receivers.size());
@@ -1607,7 +1610,8 @@
}
private void logBroadcastDeliveryEventReported(@Nullable BroadcastProcessQueue queue,
- @NonNull BroadcastRecord r, int index, @NonNull Object receiver) {
+ @Nullable ProcessRecord app, @NonNull BroadcastRecord r, int index,
+ @NonNull Object receiver) {
// Report statistics for each individual receiver
final int uid = getReceiverUid(receiver);
final int senderUid = (r.callingUid == -1) ? Process.SYSTEM_UID : r.callingUid;
@@ -1633,7 +1637,8 @@
? SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_STOPPED
: SERVICE_REQUEST_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL;
FrameworkStatsLog.write(BROADCAST_DELIVERY_EVENT_REPORTED, uid, senderUid, actionName,
- receiverType, type, dispatchDelay, receiveDelay, finishDelay, packageState);
+ receiverType, type, dispatchDelay, receiveDelay, finishDelay, packageState,
+ app != null ? app.info.packageName : null, r.callerPackage);
}
}
diff --git a/services/core/java/com/android/server/am/CachedAppOptimizer.java b/services/core/java/com/android/server/am/CachedAppOptimizer.java
index 8675bfd..e8b65b8 100644
--- a/services/core/java/com/android/server/am/CachedAppOptimizer.java
+++ b/services/core/java/com/android/server/am/CachedAppOptimizer.java
@@ -16,6 +16,9 @@
package com.android.server.am;
+import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_FROZEN;
+import static android.app.ActivityManager.UidFrozenStateChangedCallback.UID_FROZEN_STATE_UNFROZEN;
+
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_COMPACTION;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FREEZER;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
@@ -170,6 +173,7 @@
static final int SET_FROZEN_PROCESS_MSG = 3;
static final int REPORT_UNFREEZE_MSG = 4;
static final int COMPACT_NATIVE_MSG = 5;
+ static final int UID_FROZEN_STATE_CHANGED_MSG = 6;
// When free swap falls below this percentage threshold any full (file + anon)
// compactions will be downgraded to file only compactions to reduce pressure
@@ -1228,6 +1232,13 @@
}
}
+ UidRecord uidRec = app.getUidRecord();
+ if (uidRec.isFrozen()) {
+ uidRec.setFrozen(false);
+ mFreezeHandler.removeMessages(UID_FROZEN_STATE_CHANGED_MSG, app);
+ reportOneUidFrozenStateChanged(app.uid, false);
+ }
+
opt.setFreezerOverride(false);
if (pid == 0 || !opt.isFrozen()) {
return;
@@ -1357,6 +1368,13 @@
opt.setPendingFreeze(false);
}
+ UidRecord uidRec = app.getUidRecord();
+ if (uidRec != null && uidRec.isFrozen()) {
+ uidRec.setFrozen(false);
+ mFreezeHandler.removeMessages(UID_FROZEN_STATE_CHANGED_MSG, app);
+ reportOneUidFrozenStateChanged(app.uid, false);
+ }
+
mFrozenProcesses.delete(app.getPid());
}
}
@@ -1889,6 +1907,20 @@
}
}
+ private void reportOneUidFrozenStateChanged(int uid, boolean frozen) {
+ final int[] uids = new int[1];
+ final int[] frozenStates = new int[1];
+
+ uids[0] = uid;
+ frozenStates[0] = frozen ? UID_FROZEN_STATE_FROZEN : UID_FROZEN_STATE_UNFROZEN;
+
+ if (DEBUG_FREEZER) {
+ Slog.d(TAG_AM, "reportOneUidFrozenStateChanged uid " + uid + " frozen = " + frozen);
+ }
+
+ mAm.reportUidFrozenStateChanged(uids, frozenStates);
+ }
+
private final class FreezeHandler extends Handler implements
ProcLocksReader.ProcLocksReaderCallback {
private FreezeHandler() {
@@ -1929,6 +1961,10 @@
reportUnfreeze(pid, frozenDuration, processName, reason);
break;
+ case UID_FROZEN_STATE_CHANGED_MSG:
+ ProcessRecord proc = (ProcessRecord) msg.obj;
+ reportOneUidFrozenStateChanged(proc.uid, true);
+ break;
default:
return;
}
@@ -2014,6 +2050,13 @@
unfrozenDuration = opt.getFreezeUnfreezeTime() - unfreezeTime;
frozen = opt.isFrozen();
+
+ final UidRecord uidRec = proc.getUidRecord();
+ if (frozen && uidRec.areAllProcessesFrozen()) {
+ uidRec.setFrozen(true);
+ mFreezeHandler.sendMessage(mFreezeHandler.obtainMessage(
+ UID_FROZEN_STATE_CHANGED_MSG, proc));
+ }
}
if (!frozen) {
diff --git a/services/core/java/com/android/server/am/ContentProviderHelper.java b/services/core/java/com/android/server/am/ContentProviderHelper.java
index bb5f31a..824509a 100644
--- a/services/core/java/com/android/server/am/ContentProviderHelper.java
+++ b/services/core/java/com/android/server/am/ContentProviderHelper.java
@@ -262,7 +262,8 @@
PROVIDER_ACQUISITION_EVENT_REPORTED,
r.uid, callingUid,
PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM,
- PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL);
+ PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL,
+ cpi.packageName, callingPackage);
return holder;
}
@@ -333,7 +334,8 @@
PROVIDER_ACQUISITION_EVENT_REPORTED,
cpr.proc.uid, callingUid,
PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM,
- PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL);
+ PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL,
+ cpi.packageName, callingPackage);
}
} finally {
Binder.restoreCallingIdentity(origId);
@@ -509,7 +511,8 @@
PROVIDER_ACQUISITION_EVENT_REPORTED,
proc.uid, callingUid,
PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_WARM,
- PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL);
+ PROVIDER_ACQUISITION_EVENT_REPORTED__PACKAGE_STOPPED_STATE__PACKAGE_STATE_NORMAL,
+ cpi.packageName, callingPackage);
} else {
final int packageState =
((cpr.appInfo.flags & ApplicationInfo.FLAG_STOPPED) != 0)
@@ -534,7 +537,7 @@
PROVIDER_ACQUISITION_EVENT_REPORTED,
proc.uid, callingUid,
PROVIDER_ACQUISITION_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD,
- packageState);
+ packageState, cpi.packageName, callingPackage);
}
cpr.launchingApp = proc;
mLaunchingProviders.add(cpr);
diff --git a/services/core/java/com/android/server/am/OomAdjuster.md b/services/core/java/com/android/server/am/OomAdjuster.md
index febc37b..16091d1 100644
--- a/services/core/java/com/android/server/am/OomAdjuster.md
+++ b/services/core/java/com/android/server/am/OomAdjuster.md
@@ -17,10 +17,10 @@
## Purpose of Oom Adjuster
-The Android OS runs with limited hardware resources, i.e. CPU/RAM/Power. To strive for the better performance, Oom Ajuster is introduced to tweak the following 3 major factors:
+The Android OS runs with limited hardware resources, i.e. CPU/RAM/Power. To strive for the better performance, Oom Adjuster is introduced to tweak the following 3 major factors:
* Process State
- * Wildly used by the System Server, i.e., determine if it's foreground or not, change the GC behavior, etc.
+ * Widely used by the System Server, i.e., determine if it's foreground or not, change the GC behavior, etc.
* Defined in `ActivityManager#PROCESS_STATE_*`
* Oom Adj score
* Used by the lmkd to determine which process should be expunged on memory pressure.
@@ -31,36 +31,36 @@
## Process Capabilities
-Besides the above 3 major factors, Android R introduced the Process Capabilities `ActivityManager#PROCESS_CAPABILITY_*`. It's a new attribute to process record, mainly designed for supporting the "while-in-use" permission model - in additional to the traditional Android permissions, wheather or not a process has access to a given API, will be guarded by its current process state as well. The OomAdjuster will compute the process capabilities during updating the oom adj. Meanwhile, the flag `ActivityManager#BIND_INCLUDE_CAPABILITIES` enables to possiblity to "transfer" the capability from a client process to the service process it binds to.
+Besides the above 3 major factors, Android R introduced the Process Capabilities `ActivityManager#PROCESS_CAPABILITY_*`. It's a new attribute to process record, mainly designed for supporting the "while-in-use" permission model - in addition to the traditional Android permissions, whether or not a process has access to a given API, will be guarded by its current process state as well. The OomAdjuster will compute the process capabilities during updating the oom adj. Meanwhile, the flag `ActivityManager#BIND_INCLUDE_CAPABILITIES` enables the possibility to "transfer" the capability from a client process to the service process it binds to.
## Rationale of Oom Adjuster
-System server keeps a list of recent used app processes. Given the 4 types of entities that an Android processes could have: Activity, Service, Content Provider and Broadcast Receiver, the System Server has to adjust the above 3 factors to give the users the best performance according to the states of the entities. A typical case would be that: foreground app A binds into a background service B in order to serve the user, in the case of memory pressure, the background service B should be avoided from being expunged since it would result user-perceptible interruption of service. The Oom Adjuster is to tweak the aforementioned 3 factors for those app processes.
+System server keeps a list of recent used app processes. Given the 4 types of entities that an Android processes could have: Activity, Service, Content Provider and Broadcast Receiver, the System Server has to adjust the above 3 factors to give the users the best performance according to the states of the entities. A typical case would be that: foreground app A binds into a background service B in order to serve the user, in the case of memory pressure, the background service B should be avoided from being expunged since it would result in user-perceptible interruption of service. The Oom Adjuster is to tweak the aforementioned 3 factors for those app processes.
The timing of updating the Oom Adj score is vital: assume a camera process in background gets launched into foreground, launching camera typically incurs high memory pressure, which could incur low memory kills - if the camera process isn't moved out of the background adj group, it could get killed by lmkd. Therefore the updates have to be called pretty frequently: in case there is an activity start, service binding, etc.
The update procedure basically consists of 3 parts:
* Find out the process record to be updated
- * There are two categories of updateOomAdjLocked: one with the target process record to be updated, while the other one is to update all process record.
+ * There are two categories of updateOomAdjLocked: one with the target process record to be updated, while the other one is to update all process records.
* Besides that, while computing the Oom Aj score, the clients of service connections or content providers of the present process record, which forms a process dependency graph actually, will be evaluated as well.
- * Starting from Android R, when updating for a specific process record, an optimization is made that, only the reachable process records starting from this process record in the process dependency graph, will be re-evaluated.
+ * Starting from Android R, when updating a specific process record, an optimization is made that only the reachable process records starting from this process record in the process dependency graph will be re-evaluated.
* The `cached` Oom Adj scores are grouped in `bucket`, which is used in the isolated processes: they could be correlated - assume one isolated Chrome process is at Oom Adj score 920 and another one is 980; the later one could get expunged much earlier than the former one, which doesn't make sense; grouping them would be a big relief for this case.
* Compute Oom Adj score
* This procedure returns true if there is a score change, false if there is no.
* The curAdj field in the process record is used as an intermediate value during the computation.
* Initialize the Process State to `PROCESS_STATE_CACHED_EMPTY`, which is the lowest importance.
* Calculate the scores based on various factors:
- * If it's not allowed to be lower than `ProcessList#FOREGROUND_APP_ADJ`, meaning it's propbably a persistent process, there is no too much to do here.
+ * If it's not allowed to be lower than `ProcessList#FOREGROUND_APP_ADJ`, meaning it's probably a persistent process, there is no too much to do here.
* Exame if the process is the top app, running remote animation, running instrumentation, receiving broadcast, executing services, running on top but sleeping (screen off), update the intermediate values.
* Ask Window Manager (yes, ActivityTaskManager is with WindowManager now) to tell each activity's visibility information.
- * Check if the process has recent tasks, check if it's hosting a foreground service, overlay UI, toast etc. Note for the foreground service, if it was in foreground status, allow it to stay in higher rank in memory for a while: Assuming a camera captureing case, where the camera app is still processing the picture while being switched out of foreground - keep it stay in higher rank in memory would ensure the pictures are persisted correctly.
- * Check if the process is the heavy weight process, whose launching/exiting would be slow and it's better to keep it in the memory. Note there should be only one heavy weight process across the system.
+ * Check if the process has recent tasks, check if it's hosting a foreground service, overlay UI, toast etc. Note for the foreground service, if it was in foreground status, allow it to stay in higher rank in memory for a while: Assuming a camera capturing case, where the camera app is still processing the picture while being switched out of foreground - keep it stay in higher rank in memory would ensure the pictures are persisted correctly.
+ * Check if the process is the heavyweight process, whose launching/exiting would be slow and it's better to keep it in the memory. Note there should be only one heavyweight process across the system.
* For sure the Home process shouldn't be expunged frequently as well.
* The next two factors are either it was the previous process with visible UI to the user, or it's a backup agent.
* And then it goes to the massive searches against the service connections and the content providers, each of the clients will be evaluated, and the Oom Adj score could get updated according to its clients' scores. However there are a bunch of service binding flags which could impact the result:
* Below table captures the results with given various service binding states:
- | Conditon #1 | Condition #2 | Condition #3 | Condition #4 | Result |
+ | Condition #1 | Condition #2 | Condition #3 | Condition #4 | Result |
|---------------------------------|------------------------------------------------------------|----------------------------------------------|---------------------------------------------------|--------------------------|
| `BIND_WAIVE_PRIORITY` not set | `BIND_ALLOW_OOM_MANAGEMENT` set | Shown UI && Not Home | | Use the app's own Adj |
| | | Inactive for a while | | Use the app's own Adj |
@@ -85,7 +85,7 @@
| | | | `BIND_IMPORTANT` is NOT set | Sched = default |
* Below table captures the results with given various content provider binding states:
- | Conditon #1 | Condition #2 | Condition #3 | Result |
+ | Condition #1 | Condition #2 | Condition #3 | Result |
|---------------------------------|------------------------------------------------------------|----------------------------------------------|--------------------------|
| Client's process state >= cached| | | Client ProcState = empty |
| Adj > Client Adj | Not shown UI or is Home, or Client's Adj <= perceptible | Client's Adj <= foreground Adj | Try foreground Adj |
@@ -94,11 +94,11 @@
| | Client's process state is NOT top | | ProcState = bound fg svc |
| Has external dependencies | Adj > fg app | | adj = fg app |
| | Process state > important foreground | | ProcState = important fg |
- | Still within retain time | Adj > previous app Adj | | adj = previuos app adj |
+ | Still within retain time | Adj > previous app Adj | | adj = previous app adj |
| | Process state > last activity | | ProcState = last activity|
* Some additional tweaks after the above ones:
- | Conditon #1 | Condition #2 | Condition #3 | Result |
+ | Condition #1 | Condition #2 | Condition #3 | Result |
|---------------------------------|------------------------------------------------------------|----------------------------------------------|------------------------------------|
| Process state >= cached empty | Has client activities | | ProcState = cached activity client |
| | treat like activity (IME) | | ProcState = cached activity |
@@ -108,7 +108,7 @@
## Cycles, Cycles, Cycles
-Another interesting aspect of the Oom Adjuster is the cycles of the dependencies. A simple example would be like below illustration, process A is hosting a service which is bound by process B; meanwhile the process B is hosting a service which is bound by process A.
+Another interesting aspect of the Oom Adjuster is the cycles of the dependencies. A simple example would be like the illustration below, process A is hosting a service which is bound by process B; meanwhile process B is hosting a service which is bound by process A.
<pre>
+-------------+ +-------------+
| Process A | <-------- | Process B |
@@ -116,7 +116,7 @@
+-------------+ +-------------+
</pre>
-There could be very complicated cases, which could involve multiple cycles, and in the dependency graph, each of the process record node could have different importance.
+There could be very complicated cases, which could involve multiple cycles, and in the dependency graph, each of the process record nodes could have different importance.
<pre>
+-------------+ +-------------+ +-------------+ +-------------+ +-------------+
| Process D | --------> | Process A | <-------- | Process B | <-------- | Process C | <-------- | Process A |
@@ -124,9 +124,9 @@
+-------------+ +-------------+ +-------------+ +-------------+ +-------------+
</pre>
-The Oom Adjuster maintains a global sequence ID `mAdjSeq` to track the current Oom Adjuster calling. And each of the process record has a field to track in which sequence the process record is evaluated. If during the Oom Adj computation, a process record with sequence ID as same as the current global sequence ID, this would mean that a cycle is detected; in this case:
+The Oom Adjuster maintains a global sequence ID `mAdjSeq` to track the current Oom Adjuster calling. And each of the process records has a field to track in which sequence the process record is evaluated. If during the Oom Adj computation, a process record with sequence ID as same as the current global sequence ID, this would mean that a cycle is detected; in this case:
* Decrement the sequence ID of each process if there is a cycle.
- * Re-evaluate each of the process record within the cycle until nothing was promoted.
+ * Re-evaluate each of the process records within the cycle until nothing was promoted.
* Iterate the processes from least important to most important ones.
* A maximum retries of 10 is enforced, while in practice, the maximum retries could reach only 2 to 3.
diff --git a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
index 0f9ded0..0f8871c 100644
--- a/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
+++ b/services/core/java/com/android/server/am/ProcessErrorStateRecord.java
@@ -350,7 +350,8 @@
if (mService.mTraceErrorLogger != null
&& mService.mTraceErrorLogger.isAddErrorIdEnabled()) {
errorId = mService.mTraceErrorLogger.generateErrorId();
- mService.mTraceErrorLogger.addErrorIdToTrace(mApp.processName, errorId);
+ mService.mTraceErrorLogger.addProcessInfoAndErrorIdToTrace(
+ mApp.processName, pid, errorId);
mService.mTraceErrorLogger.addSubjectToTrace(annotation, errorId);
} else {
errorId = null;
@@ -461,7 +462,10 @@
// don't dump native PIDs for background ANRs unless
// it is the process of interest
String[] nativeProcs = null;
- if (isSilentAnr || onlyDumpSelf) {
+ boolean isSystemApp = mApp.info.isSystemApp() || mApp.info.isSystemExt();
+ // Do not collect system daemons dumps as this is not likely to be useful
+ // for non-system apps.
+ if (!isSystemApp || isSilentAnr || onlyDumpSelf) {
for (int i = 0; i < NATIVE_STACKS_OF_INTEREST.length; i++) {
if (NATIVE_STACKS_OF_INTEREST[i].equals(mApp.processName)) {
nativeProcs = new String[] { mApp.processName };
@@ -491,7 +495,7 @@
StringWriter tracesFileException = new StringWriter();
// To hold the start and end offset to the ANR trace file respectively.
final AtomicLong firstPidEndOffset = new AtomicLong(-1);
- File tracesFile = ActivityManagerService.dumpStackTraces(firstPids,
+ File tracesFile = StackTracesDumpHelper.dumpStackTraces(firstPids,
isSilentAnr ? null : processCpuTracker, isSilentAnr ? null : lastPids,
nativePidsFuture, tracesFileException, firstPidEndOffset, annotation,
criticalEventLog, auxiliaryTaskExecutor, latencyTracker);
diff --git a/services/core/java/com/android/server/am/ProcessRecord.java b/services/core/java/com/android/server/am/ProcessRecord.java
index fa3f684..50d00b4 100644
--- a/services/core/java/com/android/server/am/ProcessRecord.java
+++ b/services/core/java/com/android/server/am/ProcessRecord.java
@@ -1039,7 +1039,13 @@
mInFullBackup = inFullBackup;
}
+ @GuardedBy("mService")
+ public void setCached(boolean cached) {
+ mState.setCached(cached);
+ }
+
@Override
+ @GuardedBy("mService")
public boolean isCached() {
return mState.isCached();
}
diff --git a/services/core/java/com/android/server/am/ServiceRecord.java b/services/core/java/com/android/server/am/ServiceRecord.java
index 663121e..4defdc6 100644
--- a/services/core/java/com/android/server/am/ServiceRecord.java
+++ b/services/core/java/com/android/server/am/ServiceRecord.java
@@ -249,6 +249,7 @@
final String mCallingProcessName;
final Intent intent;
final NeededUriGrants neededGrants;
+ final @Nullable String mCallingPackageName;
long deliveredTime;
int deliveryCount;
int doneExecutingCount;
@@ -258,7 +259,7 @@
StartItem(ServiceRecord _sr, boolean _taskRemoved, int _id,
Intent _intent, NeededUriGrants _neededGrants, int _callingId,
- String callingProcessName) {
+ String callingProcessName, @Nullable String callingPackageName) {
sr = _sr;
taskRemoved = _taskRemoved;
id = _id;
@@ -266,6 +267,7 @@
neededGrants = _neededGrants;
callingId = _callingId;
mCallingProcessName = callingProcessName;
+ mCallingPackageName = callingPackageName;
}
UriPermissionOwner getUriPermissionsLocked() {
diff --git a/services/core/java/com/android/server/am/StackTracesDumpHelper.java b/services/core/java/com/android/server/am/StackTracesDumpHelper.java
new file mode 100644
index 0000000..9373328
--- /dev/null
+++ b/services/core/java/com/android/server/am/StackTracesDumpHelper.java
@@ -0,0 +1,483 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.am;
+
+import static android.text.format.DateUtils.DAY_IN_MILLIS;
+
+import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
+import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+
+import android.annotation.NonNull;
+import android.os.Build;
+import android.os.Debug;
+import android.os.FileUtils;
+import android.os.SystemClock;
+import android.os.SystemProperties;
+import android.util.Slog;
+import android.util.SparseBooleanArray;
+
+import com.android.internal.annotations.GuardedBy;
+import com.android.internal.os.ProcessCpuTracker;
+import com.android.internal.os.anr.AnrLatencyTracker;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.nio.charset.StandardCharsets;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Date;
+import java.util.concurrent.CompletableFuture;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Executor;
+import java.util.concurrent.Future;
+import java.util.concurrent.atomic.AtomicLong;
+import java.util.function.Supplier;
+
+
+/**
+ * A helper for dumping stack traces.
+ */
+public class StackTracesDumpHelper {
+ static final String TAG = TAG_WITH_CLASS_NAME ? "StackTracesDumpHelper" : TAG_AM;
+
+ @GuardedBy("StackTracesDumpHelper.class")
+ private static final SimpleDateFormat ANR_FILE_DATE_FORMAT =
+ new SimpleDateFormat("yyyy-MM-dd-HH-mm-ss-SSS");
+
+ static final String ANR_FILE_PREFIX = "anr_";
+ public static final String ANR_TRACE_DIR = "/data/anr";
+
+ private static final int NATIVE_DUMP_TIMEOUT_MS =
+ 2000 * Build.HW_TIMEOUT_MULTIPLIER; // 2 seconds;
+ private static final int JAVA_DUMP_MINIMUM_SIZE = 100; // 100 bytes.
+
+ /**
+ * If a stack trace dump file is configured, dump process stack traces.
+ * @param firstPids of dalvik VM processes to dump stack traces for first
+ * @param lastPids of dalvik VM processes to dump stack traces for last
+ * @param nativePidsFuture optional future for a list of native pids to dump stack crawls
+ * @param logExceptionCreatingFile optional writer to which we log errors creating the file
+ * @param auxiliaryTaskExecutor executor to execute auxiliary tasks on
+ * @param latencyTracker the latency tracker instance of the current ANR.
+ */
+ public static File dumpStackTraces(ArrayList<Integer> firstPids,
+ ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
+ Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
+ @NonNull Executor auxiliaryTaskExecutor, AnrLatencyTracker latencyTracker) {
+ return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePidsFuture,
+ logExceptionCreatingFile, null, null, null, auxiliaryTaskExecutor, latencyTracker);
+ }
+
+ /**
+ * @param subject the subject of the dumped traces
+ * @param criticalEventSection the critical event log, passed as a string
+ */
+ public static File dumpStackTraces(ArrayList<Integer> firstPids,
+ ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
+ Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
+ String subject, String criticalEventSection, @NonNull Executor auxiliaryTaskExecutor,
+ AnrLatencyTracker latencyTracker) {
+ return dumpStackTraces(firstPids, processCpuTracker, lastPids, nativePidsFuture,
+ logExceptionCreatingFile, null, subject, criticalEventSection,
+ auxiliaryTaskExecutor, latencyTracker);
+ }
+
+ /**
+ * @param firstPidEndOffset Optional, when it's set, it receives the start/end offset
+ * of the very first pid to be dumped.
+ */
+ /* package */ static File dumpStackTraces(ArrayList<Integer> firstPids,
+ ProcessCpuTracker processCpuTracker, SparseBooleanArray lastPids,
+ Future<ArrayList<Integer>> nativePidsFuture, StringWriter logExceptionCreatingFile,
+ AtomicLong firstPidEndOffset, String subject, String criticalEventSection,
+ @NonNull Executor auxiliaryTaskExecutor, AnrLatencyTracker latencyTracker) {
+ try {
+
+ if (latencyTracker != null) {
+ latencyTracker.dumpStackTracesStarted();
+ }
+
+ Slog.i(TAG, "dumpStackTraces pids=" + lastPids);
+
+ // Measure CPU usage as soon as we're called in order to get a realistic sampling
+ // of the top users at the time of the request.
+ Supplier<ArrayList<Integer>> extraPidsSupplier = processCpuTracker != null
+ ? () -> getExtraPids(processCpuTracker, lastPids, latencyTracker) : null;
+ Future<ArrayList<Integer>> extraPidsFuture = null;
+ if (extraPidsSupplier != null) {
+ extraPidsFuture =
+ CompletableFuture.supplyAsync(extraPidsSupplier, auxiliaryTaskExecutor);
+ }
+
+ final File tracesDir = new File(ANR_TRACE_DIR);
+
+ // NOTE: We should consider creating the file in native code atomically once we've
+ // gotten rid of the old scheme of dumping and lot of the code that deals with paths
+ // can be removed.
+ File tracesFile;
+ try {
+ tracesFile = createAnrDumpFile(tracesDir);
+ } catch (IOException e) {
+ Slog.w(TAG, "Exception creating ANR dump file:", e);
+ if (logExceptionCreatingFile != null) {
+ logExceptionCreatingFile.append(
+ "----- Exception creating ANR dump file -----\n");
+ e.printStackTrace(new PrintWriter(logExceptionCreatingFile));
+ }
+ if (latencyTracker != null) {
+ latencyTracker.anrSkippedDumpStackTraces();
+ }
+ return null;
+ }
+
+ if (subject != null || criticalEventSection != null) {
+ appendtoANRFile(tracesFile.getAbsolutePath(),
+ (subject != null ? "Subject: " + subject + "\n\n" : "")
+ + (criticalEventSection != null ? criticalEventSection : ""));
+ }
+
+ long firstPidEndPos = dumpStackTraces(
+ tracesFile.getAbsolutePath(), firstPids, nativePidsFuture,
+ extraPidsFuture, latencyTracker);
+ if (firstPidEndOffset != null) {
+ firstPidEndOffset.set(firstPidEndPos);
+ }
+ // Each set of ANR traces is written to a separate file and dumpstate will process
+ // all such files and add them to a captured bug report if they're recent enough.
+ maybePruneOldTraces(tracesDir);
+
+ return tracesFile;
+ } finally {
+ if (latencyTracker != null) {
+ latencyTracker.dumpStackTracesEnded();
+ }
+ }
+
+ }
+
+ /**
+ * @return The end offset of the trace of the very first PID
+ */
+ public static long dumpStackTraces(String tracesFile,
+ ArrayList<Integer> firstPids, Future<ArrayList<Integer>> nativePidsFuture,
+ Future<ArrayList<Integer>> extraPidsFuture, AnrLatencyTracker latencyTracker) {
+
+ Slog.i(TAG, "Dumping to " + tracesFile);
+
+ // We don't need any sort of inotify based monitoring when we're dumping traces via
+ // tombstoned. Data is piped to an "intercept" FD installed in tombstoned so we're in full
+ // control of all writes to the file in question.
+
+ // We must complete all stack dumps within 20 seconds.
+ long remainingTime = 20 * 1000 * Build.HW_TIMEOUT_MULTIPLIER;
+
+ // As applications are usually interested with the ANR stack traces, but we can't share with
+ // them the stack traces other than their own stacks. So after the very first PID is
+ // dumped, remember the current file size.
+ long firstPidEnd = -1;
+
+ // First collect all of the stacks of the most important pids.
+ if (firstPids != null) {
+ if (latencyTracker != null) {
+ latencyTracker.dumpingFirstPidsStarted();
+ }
+
+ int num = firstPids.size();
+ for (int i = 0; i < num; i++) {
+ final int pid = firstPids.get(i);
+ // We don't copy ANR traces from the system_server intentionally.
+ final boolean firstPid = i == 0 && ActivityManagerService.MY_PID != pid;
+ if (latencyTracker != null) {
+ latencyTracker.dumpingPidStarted(pid);
+ }
+
+ Slog.i(TAG, "Collecting stacks for pid " + pid);
+ final long timeTaken = dumpJavaTracesTombstoned(pid, tracesFile,
+ remainingTime);
+ if (latencyTracker != null) {
+ latencyTracker.dumpingPidEnded();
+ }
+
+ remainingTime -= timeTaken;
+ if (remainingTime <= 0) {
+ Slog.e(TAG, "Aborting stack trace dump (current firstPid=" + pid
+ + "); deadline exceeded.");
+ return firstPidEnd;
+ }
+
+ if (firstPid) {
+ firstPidEnd = new File(tracesFile).length();
+ // Full latency dump
+ if (latencyTracker != null) {
+ appendtoANRFile(tracesFile,
+ latencyTracker.dumpAsCommaSeparatedArrayWithHeader());
+ }
+ }
+ if (DEBUG_ANR) {
+ Slog.d(TAG, "Done with pid " + firstPids.get(i) + " in " + timeTaken + "ms");
+ }
+ }
+ if (latencyTracker != null) {
+ latencyTracker.dumpingFirstPidsEnded();
+ }
+ }
+
+ // Next collect the stacks of the native pids
+ ArrayList<Integer> nativePids = collectPids(nativePidsFuture, "native pids");
+
+ Slog.i(TAG, "dumpStackTraces nativepids=" + nativePids);
+
+ if (nativePids != null) {
+ if (latencyTracker != null) {
+ latencyTracker.dumpingNativePidsStarted();
+ }
+ for (int pid : nativePids) {
+ Slog.i(TAG, "Collecting stacks for native pid " + pid);
+ final long nativeDumpTimeoutMs = Math.min(NATIVE_DUMP_TIMEOUT_MS, remainingTime);
+
+ if (latencyTracker != null) {
+ latencyTracker.dumpingPidStarted(pid);
+ }
+ final long start = SystemClock.elapsedRealtime();
+ Debug.dumpNativeBacktraceToFileTimeout(
+ pid, tracesFile, (int) (nativeDumpTimeoutMs / 1000));
+ final long timeTaken = SystemClock.elapsedRealtime() - start;
+ if (latencyTracker != null) {
+ latencyTracker.dumpingPidEnded();
+ }
+ remainingTime -= timeTaken;
+ if (remainingTime <= 0) {
+ Slog.e(TAG, "Aborting stack trace dump (current native pid=" + pid
+ + "); deadline exceeded.");
+ return firstPidEnd;
+ }
+
+ if (DEBUG_ANR) {
+ Slog.d(TAG, "Done with native pid " + pid + " in " + timeTaken + "ms");
+ }
+ }
+ if (latencyTracker != null) {
+ latencyTracker.dumpingNativePidsEnded();
+ }
+ }
+
+ // Lastly, dump stacks for all extra PIDs from the CPU tracker.
+ ArrayList<Integer> extraPids = collectPids(extraPidsFuture, "extra pids");
+
+ if (extraPidsFuture != null) {
+ try {
+ extraPids = extraPidsFuture.get();
+ } catch (ExecutionException e) {
+ Slog.w(TAG, "Failed to collect extra pids", e.getCause());
+ } catch (InterruptedException e) {
+ Slog.w(TAG, "Interrupted while collecting extra pids", e);
+ }
+ }
+ Slog.i(TAG, "dumpStackTraces extraPids=" + extraPids);
+
+ if (extraPids != null) {
+ if (latencyTracker != null) {
+ latencyTracker.dumpingExtraPidsStarted();
+ }
+ for (int pid : extraPids) {
+ Slog.i(TAG, "Collecting stacks for extra pid " + pid);
+ if (latencyTracker != null) {
+ latencyTracker.dumpingPidStarted(pid);
+ }
+ final long timeTaken = dumpJavaTracesTombstoned(pid, tracesFile, remainingTime);
+ if (latencyTracker != null) {
+ latencyTracker.dumpingPidEnded();
+ }
+ remainingTime -= timeTaken;
+ if (remainingTime <= 0) {
+ Slog.e(TAG, "Aborting stack trace dump (current extra pid=" + pid
+ + "); deadline exceeded.");
+ return firstPidEnd;
+ }
+
+ if (DEBUG_ANR) {
+ Slog.d(TAG, "Done with extra pid " + pid + " in " + timeTaken + "ms");
+ }
+ }
+ if (latencyTracker != null) {
+ latencyTracker.dumpingExtraPidsEnded();
+ }
+ }
+ // Append the dumping footer with the current uptime
+ appendtoANRFile(tracesFile, "----- dumping ended at " + SystemClock.uptimeMillis() + "\n");
+ Slog.i(TAG, "Done dumping");
+
+ return firstPidEnd;
+ }
+
+ private static synchronized File createAnrDumpFile(File tracesDir) throws IOException {
+ final String formattedDate = ANR_FILE_DATE_FORMAT.format(new Date());
+ final File anrFile = new File(tracesDir, ANR_FILE_PREFIX + formattedDate);
+
+ if (anrFile.createNewFile()) {
+ FileUtils.setPermissions(anrFile.getAbsolutePath(), 0600, -1, -1); // -rw-------
+ return anrFile;
+ } else {
+ throw new IOException("Unable to create ANR dump file: createNewFile failed");
+ }
+ }
+
+ private static ArrayList<Integer> getExtraPids(ProcessCpuTracker processCpuTracker,
+ SparseBooleanArray lastPids, AnrLatencyTracker latencyTracker) {
+ if (latencyTracker != null) {
+ latencyTracker.processCpuTrackerMethodsCalled();
+ }
+ ArrayList<Integer> extraPids = new ArrayList<>();
+ processCpuTracker.init();
+ try {
+ Thread.sleep(200);
+ } catch (InterruptedException ignored) {
+ }
+
+ processCpuTracker.update();
+
+ // We'll take the stack crawls of just the top apps using CPU.
+ final int workingStatsNumber = processCpuTracker.countWorkingStats();
+ for (int i = 0; i < workingStatsNumber && extraPids.size() < 2; i++) {
+ ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
+ if (lastPids.indexOfKey(stats.pid) >= 0) {
+ if (DEBUG_ANR) {
+ Slog.d(TAG, "Collecting stacks for extra pid " + stats.pid);
+ }
+
+ extraPids.add(stats.pid);
+ } else {
+ Slog.i(TAG,
+ "Skipping next CPU consuming process, not a java proc: "
+ + stats.pid);
+ }
+ }
+ if (latencyTracker != null) {
+ latencyTracker.processCpuTrackerMethodsReturned();
+ }
+ return extraPids;
+ }
+
+ /**
+ * Prune all trace files that are more than a day old.
+ *
+ * NOTE: It might make sense to move this functionality to tombstoned eventually, along with a
+ * shift away from anr_XX and tombstone_XX to a more descriptive name. We do it here for now
+ * since it's the system_server that creates trace files for most ANRs.
+ */
+ private static void maybePruneOldTraces(File tracesDir) {
+ final File[] files = tracesDir.listFiles();
+ if (files == null) return;
+
+ final int max = SystemProperties.getInt("tombstoned.max_anr_count", 64);
+ final long now = System.currentTimeMillis();
+ try {
+ Arrays.sort(files, Comparator.comparingLong(File::lastModified).reversed());
+ for (int i = 0; i < files.length; ++i) {
+ if (i > max || (now - files[i].lastModified()) > DAY_IN_MILLIS) {
+ if (!files[i].delete()) {
+ Slog.w(TAG, "Unable to prune stale trace file: " + files[i]);
+ }
+ }
+ }
+ } catch (IllegalArgumentException e) {
+ // The modification times changed while we were sorting. Bail...
+ // https://issuetracker.google.com/169836837
+ Slog.w(TAG, "tombstone modification times changed while sorting; not pruning", e);
+ }
+ }
+ /**
+ * Dump java traces for process {@code pid} to the specified file. If java trace dumping
+ * fails, a native backtrace is attempted. Note that the timeout {@code timeoutMs} only applies
+ * to the java section of the trace, a further {@code NATIVE_DUMP_TIMEOUT_MS} might be spent
+ * attempting to obtain native traces in the case of a failure. Returns the total time spent
+ * capturing traces.
+ */
+ private static long dumpJavaTracesTombstoned(int pid, String fileName, long timeoutMs) {
+ final long timeStart = SystemClock.elapsedRealtime();
+ int headerSize = writeUptimeStartHeaderForPid(pid, fileName);
+ boolean javaSuccess = Debug.dumpJavaBacktraceToFileTimeout(pid, fileName,
+ (int) (timeoutMs / 1000));
+ if (javaSuccess) {
+ // Check that something is in the file, actually. Try-catch should not be necessary,
+ // but better safe than sorry.
+ try {
+ long size = new File(fileName).length();
+ if ((size - headerSize) < JAVA_DUMP_MINIMUM_SIZE) {
+ Slog.w(TAG, "Successfully created Java ANR file is empty!");
+ javaSuccess = false;
+ }
+ } catch (Exception e) {
+ Slog.w(TAG, "Unable to get ANR file size", e);
+ javaSuccess = false;
+ }
+ }
+ if (!javaSuccess) {
+ Slog.w(TAG, "Dumping Java threads failed, initiating native stack dump.");
+ if (!Debug.dumpNativeBacktraceToFileTimeout(pid, fileName,
+ (NATIVE_DUMP_TIMEOUT_MS / 1000))) {
+ Slog.w(TAG, "Native stack dump failed!");
+ }
+ }
+
+ return SystemClock.elapsedRealtime() - timeStart;
+ }
+
+ private static int appendtoANRFile(String fileName, String text) {
+ try (FileOutputStream fos = new FileOutputStream(fileName, true)) {
+ byte[] header = text.getBytes(StandardCharsets.UTF_8);
+ fos.write(header);
+ return header.length;
+ } catch (IOException e) {
+ Slog.w(TAG, "Exception writing to ANR dump file:", e);
+ return 0;
+ }
+ }
+
+ /*
+ * Writes a header containing the process id and the current system uptime.
+ */
+ private static int writeUptimeStartHeaderForPid(int pid, String fileName) {
+ return appendtoANRFile(fileName, "----- dumping pid: " + pid + " at "
+ + SystemClock.uptimeMillis() + "\n");
+ }
+
+ private static ArrayList<Integer> collectPids(Future<ArrayList<Integer>> pidsFuture,
+ String logName) {
+
+ ArrayList<Integer> pids = null;
+
+ if (pidsFuture == null) {
+ return pids;
+ }
+ try {
+ pids = pidsFuture.get();
+ } catch (ExecutionException e) {
+ Slog.w(TAG, "Failed to collect " + logName, e.getCause());
+ } catch (InterruptedException e) {
+ Slog.w(TAG, "Interrupted while collecting " + logName , e);
+ }
+ return pids;
+ }
+
+}
diff --git a/services/core/java/com/android/server/am/TraceErrorLogger.java b/services/core/java/com/android/server/am/TraceErrorLogger.java
index ec0587f..ea65248 100644
--- a/services/core/java/com/android/server/am/TraceErrorLogger.java
+++ b/services/core/java/com/android/server/am/TraceErrorLogger.java
@@ -45,12 +45,13 @@
* can be uniquely identified. We also add the same id to the dropbox entry of the error, so
* that we can join the trace and the error server-side.
*
- * @param processName The process name to include in the error id.
+ * @param processName The name of the ANRing process.
+ * @param pid The pid of the ANRing process.
* @param errorId The unique id with which to tag the trace.
*/
- public void addErrorIdToTrace(String processName, UUID errorId) {
+ public void addProcessInfoAndErrorIdToTrace(String processName, int pid, UUID errorId) {
Trace.traceCounter(Trace.TRACE_TAG_ACTIVITY_MANAGER,
- COUNTER_PREFIX + processName + "#" + errorId.toString(),
+ COUNTER_PREFIX + processName + " " + pid + "#" + errorId.toString(),
PLACEHOLDER_VALUE);
}
diff --git a/services/core/java/com/android/server/am/UidRecord.java b/services/core/java/com/android/server/am/UidRecord.java
index bfc022b..e39ac2b 100644
--- a/services/core/java/com/android/server/am/UidRecord.java
+++ b/services/core/java/com/android/server/am/UidRecord.java
@@ -151,6 +151,14 @@
@GuardedBy("mService")
private int mLastReportedChange;
+ /**
+ * This indicates whether the entire Uid is frozen or not.
+ * It is used by CachedAppOptimizer to avoid sending multiple
+ * UID_FROZEN_STATE_UNFROZEN messages on process unfreeze.
+ */
+ @GuardedBy(anyOf = {"mService", "mProcLock"})
+ private boolean mUidIsFrozen;
+
public UidRecord(int uid, ActivityManagerService service) {
mUid = uid;
mService = service;
@@ -303,6 +311,11 @@
}
@GuardedBy(anyOf = {"mService", "mProcLock"})
+ ProcessRecord getProcessRecordByIndex(int idx) {
+ return mProcRecords.valueAt(idx);
+ }
+
+ @GuardedBy(anyOf = {"mService", "mProcLock"})
ProcessRecord getProcessInPackage(String packageName) {
for (int i = mProcRecords.size() - 1; i >= 0; i--) {
final ProcessRecord app = mProcRecords.valueAt(i);
@@ -313,6 +326,32 @@
return null;
}
+ /**
+ * @return true if all processes in the Uid are frozen, false otherwise.
+ */
+ @GuardedBy(anyOf = {"mService", "mProcLock"})
+ public boolean areAllProcessesFrozen() {
+ for (int i = mProcRecords.size() - 1; i >= 0; i--) {
+ final ProcessRecord app = mProcRecords.valueAt(i);
+ final ProcessCachedOptimizerRecord opt = app.mOptRecord;
+
+ if (!opt.isFrozen()) {
+ return false;
+ }
+ }
+ return true;
+ }
+
+ @GuardedBy(anyOf = {"mService", "mProcLock"})
+ public void setFrozen(boolean frozen) {
+ mUidIsFrozen = frozen;
+ }
+
+ @GuardedBy(anyOf = {"mService", "mProcLock"})
+ public boolean isFrozen() {
+ return mUidIsFrozen;
+ }
+
@GuardedBy({"mService", "mProcLock"})
void addProcess(ProcessRecord app) {
mProcRecords.add(app);
diff --git a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
index d7c3100..46e6001 100644
--- a/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
+++ b/services/core/java/com/android/server/ambientcontext/AmbientContextManagerService.java
@@ -594,10 +594,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT)
@Override
public void unregisterObserver(String callingPackage) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_AMBIENT_CONTEXT_EVENT, TAG);
+ unregisterObserver_enforcePermission();
assertCalledByPackageOwner(callingPackage);
synchronized (mLock) {
diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java
index fc22935..9bd5d6a 100644
--- a/services/core/java/com/android/server/appop/AppOpsService.java
+++ b/services/core/java/com/android/server/appop/AppOpsService.java
@@ -5611,10 +5611,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APPOPS)
@Override
public void resetPackageOpsNoHistory(@NonNull String packageName) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APPOPS,
- "resetPackageOpsNoHistory");
+ resetPackageOpsNoHistory_enforcePermission();
synchronized (AppOpsService.this) {
final int uid = mPackageManagerInternal.getPackageUid(packageName, 0,
UserHandle.getCallingUserId());
@@ -5633,52 +5633,52 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APPOPS)
@Override
public void setHistoryParameters(@AppOpsManager.HistoricalMode int mode,
long baseSnapshotInterval, int compressionStep) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APPOPS,
- "setHistoryParameters");
+ setHistoryParameters_enforcePermission();
// Must not hold the appops lock
mHistoricalRegistry.setHistoryParameters(mode, baseSnapshotInterval, compressionStep);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APPOPS)
@Override
public void offsetHistory(long offsetMillis) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APPOPS,
- "offsetHistory");
+ offsetHistory_enforcePermission();
// Must not hold the appops lock
mHistoricalRegistry.offsetHistory(offsetMillis);
mHistoricalRegistry.offsetDiscreteHistory(offsetMillis);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APPOPS)
@Override
public void addHistoricalOps(HistoricalOps ops) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APPOPS,
- "addHistoricalOps");
+ addHistoricalOps_enforcePermission();
// Must not hold the appops lock
mHistoricalRegistry.addHistoricalOps(ops);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APPOPS)
@Override
public void resetHistoryParameters() {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APPOPS,
- "resetHistoryParameters");
+ resetHistoryParameters_enforcePermission();
// Must not hold the appops lock
mHistoricalRegistry.resetHistoryParameters();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APPOPS)
@Override
public void clearHistory() {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APPOPS,
- "clearHistory");
+ clearHistory_enforcePermission();
// Must not hold the appops lock
mHistoricalRegistry.clearAllHistory();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APPOPS)
@Override
public void rebootHistory(long offlineDurationMillis) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_APPOPS,
- "rebootHistory");
+ rebootHistory_enforcePermission();
Preconditions.checkArgument(offlineDurationMillis >= 0);
diff --git a/services/core/java/com/android/server/audio/AudioDeviceInventory.java b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
index aae1d38..6758581 100644
--- a/services/core/java/com/android/server/audio/AudioDeviceInventory.java
+++ b/services/core/java/com/android/server/audio/AudioDeviceInventory.java
@@ -597,7 +597,13 @@
if (wdcs.mState == AudioService.CONNECTION_STATE_DISCONNECTED
&& AudioSystem.DEVICE_OUT_ALL_USB_SET.contains(
wdcs.mAttributes.getInternalType())) {
- mDeviceBroker.dispatchPreferredMixerAttributesChangedCausedByDeviceRemoved(info);
+ if (info != null) {
+ mDeviceBroker.dispatchPreferredMixerAttributesChangedCausedByDeviceRemoved(
+ info);
+ } else {
+ Log.e(TAG, "Didn't find AudioDeviceInfo to notify preferred mixer "
+ + "attributes change for type=" + wdcs.mAttributes.getType());
+ }
}
sendDeviceConnectionIntent(type, wdcs.mState,
wdcs.mAttributes.getAddress(), wdcs.mAttributes.getName());
diff --git a/services/core/java/com/android/server/audio/AudioService.java b/services/core/java/com/android/server/audio/AudioService.java
index e403861..e5e6d4c 100644
--- a/services/core/java/com/android/server/audio/AudioService.java
+++ b/services/core/java/com/android/server/audio/AudioService.java
@@ -1046,9 +1046,14 @@
mSfxHelper = new SoundEffectsHelper(mContext, playerBase -> ignorePlayerLogs(playerBase));
- final boolean headTrackingDefault = mContext.getResources().getBoolean(
+ final boolean binauralEnabledDefault = SystemProperties.getBoolean(
+ "ro.audio.spatializer_binaural_enabled_default", true);
+ final boolean transauralEnabledDefault = SystemProperties.getBoolean(
+ "ro.audio.spatializer_transaural_enabled_default", true);
+ final boolean headTrackingEnabledDefault = mContext.getResources().getBoolean(
com.android.internal.R.bool.config_spatial_audio_head_tracking_enabled_default);
- mSpatializerHelper = new SpatializerHelper(this, mAudioSystem, headTrackingDefault);
+ mSpatializerHelper = new SpatializerHelper(this, mAudioSystem,
+ binauralEnabledDefault, transauralEnabledDefault, headTrackingEnabledDefault);
mVibrator = (Vibrator) context.getSystemService(Context.VIBRATOR_SERVICE);
mHasVibrator = mVibrator == null ? false : mVibrator.hasVibrator();
@@ -1372,8 +1377,8 @@
intentFilter.addAction(Intent.ACTION_CONFIGURATION_CHANGED);
if (mMonitorRotation) {
RotationHelper.init(mContext, mAudioHandler,
- rotationParam -> onRotationUpdate(rotationParam),
- foldParam -> onFoldUpdate(foldParam));
+ rotation -> onRotationUpdate(rotation),
+ foldState -> onFoldStateUpdate(foldState));
}
intentFilter.addAction(AudioEffect.ACTION_OPEN_AUDIO_EFFECT_CONTROL_SESSION);
@@ -1515,16 +1520,20 @@
//-----------------------------------------------------------------
// rotation/fold updates coming from RotationHelper
- void onRotationUpdate(String rotationParameter) {
+ void onRotationUpdate(Integer rotation) {
+ mSpatializerHelper.setDisplayOrientation((float) (rotation * Math.PI / 180.));
// use REPLACE as only the last rotation matters
+ final String rotationParameter = "rotation=" + rotation;
sendMsg(mAudioHandler, MSG_ROTATION_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
/*obj*/ rotationParameter, /*delay*/ 0);
}
- void onFoldUpdate(String foldParameter) {
+ void onFoldStateUpdate(Boolean foldState) {
+ mSpatializerHelper.setFoldState(foldState);
// use REPLACE as only the last fold state matters
+ final String foldStateParameter = "device_folded=" + (foldState ? "on" : "off");
sendMsg(mAudioHandler, MSG_FOLD_UPDATE, SENDMSG_REPLACE, /*arg1*/ 0, /*arg2*/ 0,
- /*obj*/ foldParameter, /*delay*/ 0);
+ /*obj*/ foldStateParameter, /*delay*/ 0);
}
//-----------------------------------------------------------------
@@ -1740,6 +1749,11 @@
mSpatializerHelper.reset(/* featureEnabled */ mHasSpatializerEffect);
mSoundDoseHelper.reset();
+ // Restore rotation information.
+ if (mMonitorRotation) {
+ RotationHelper.forceUpdate();
+ }
+
onIndicateSystemReady();
// indicate the end of reconfiguration phase to audio HAL
AudioSystem.setParameters("restarting=false");
@@ -2449,13 +2463,11 @@
return true;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_SETTINGS)
/** @see AudioManager#setEncodedSurroundMode(int) */
@Override
public boolean setEncodedSurroundMode(@AudioManager.EncodedSurroundOutputMode int mode) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.WRITE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Missing WRITE_SETTINGS permission");
- }
+ setEncodedSurroundMode_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
@@ -7466,15 +7478,13 @@
public @interface BtProfile {}
+ @android.annotation.EnforcePermission(android.Manifest.permission.BLUETOOTH_STACK)
/**
* See AudioManager.handleBluetoothActiveDeviceChanged(...)
*/
public void handleBluetoothActiveDeviceChanged(BluetoothDevice newDevice,
BluetoothDevice previousDevice, @NonNull BluetoothProfileConnectionInfo info) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.BLUETOOTH_STACK)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Bluetooth is the only caller allowed");
- }
+ handleBluetoothActiveDeviceChanged_enforcePermission();
if (info == null) {
throw new IllegalArgumentException("Illegal null BluetoothProfileConnectionInfo for"
+ " device " + previousDevice + " -> " + newDevice);
@@ -10408,9 +10418,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.REMOTE_AUDIO_PLAYBACK)
@Override
public void setRingtonePlayer(IRingtonePlayer player) {
- mContext.enforceCallingOrSelfPermission(REMOTE_AUDIO_PLAYBACK, null);
+ setRingtonePlayer_enforcePermission();
mRingtonePlayer = player;
}
@@ -10464,16 +10475,16 @@
@Override
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
- public float getRs2Value() {
- super.getRs2Value_enforcePermission();
- return mSoundDoseHelper.getRs2Value();
+ public float getOutputRs2UpperBound() {
+ super.getOutputRs2UpperBound_enforcePermission();
+ return mSoundDoseHelper.getOutputRs2UpperBound();
}
@Override
@android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_AUDIO_SETTINGS_PRIVILEGED)
- public void setRs2Value(float rs2Value) {
- super.setRs2Value_enforcePermission();
- mSoundDoseHelper.setRs2Value(rs2Value);
+ public void setOutputRs2UpperBound(float rs2Value) {
+ super.setOutputRs2UpperBound_enforcePermission();
+ mSoundDoseHelper.setOutputRs2UpperBound(rs2Value);
}
@Override
diff --git a/services/core/java/com/android/server/audio/RotationHelper.java b/services/core/java/com/android/server/audio/RotationHelper.java
index 5cdf58b..394e4af 100644
--- a/services/core/java/com/android/server/audio/RotationHelper.java
+++ b/services/core/java/com/android/server/audio/RotationHelper.java
@@ -55,14 +55,14 @@
private static AudioDisplayListener sDisplayListener;
private static FoldStateListener sFoldStateListener;
/** callback to send rotation updates to AudioSystem */
- private static Consumer<String> sRotationUpdateCb;
+ private static Consumer<Integer> sRotationCallback;
/** callback to send folded state updates to AudioSystem */
- private static Consumer<String> sFoldUpdateCb;
+ private static Consumer<Boolean> sFoldStateCallback;
private static final Object sRotationLock = new Object();
private static final Object sFoldStateLock = new Object();
- private static int sDeviceRotation = Surface.ROTATION_0; // R/W synchronized on sRotationLock
- private static boolean sDeviceFold = true; // R/W synchronized on sFoldStateLock
+ private static Integer sRotation = null; // R/W synchronized on sRotationLock
+ private static Boolean sFoldState = null; // R/W synchronized on sFoldStateLock
private static Context sContext;
private static Handler sHandler;
@@ -73,15 +73,15 @@
* - sContext != null
*/
static void init(Context context, Handler handler,
- Consumer<String> rotationUpdateCb, Consumer<String> foldUpdateCb) {
+ Consumer<Integer> rotationCallback, Consumer<Boolean> foldStateCallback) {
if (context == null) {
throw new IllegalArgumentException("Invalid null context");
}
sContext = context;
sHandler = handler;
sDisplayListener = new AudioDisplayListener();
- sRotationUpdateCb = rotationUpdateCb;
- sFoldUpdateCb = foldUpdateCb;
+ sRotationCallback = rotationCallback;
+ sFoldStateCallback = foldStateCallback;
enable();
}
@@ -112,9 +112,9 @@
int newRotation = DisplayManagerGlobal.getInstance()
.getDisplayInfo(Display.DEFAULT_DISPLAY).rotation;
synchronized(sRotationLock) {
- if (newRotation != sDeviceRotation) {
- sDeviceRotation = newRotation;
- publishRotation(sDeviceRotation);
+ if (sRotation == null || sRotation != newRotation) {
+ sRotation = newRotation;
+ publishRotation(sRotation);
}
}
}
@@ -123,43 +123,52 @@
if (DEBUG_ROTATION) {
Log.i(TAG, "publishing device rotation =" + rotation + " (x90deg)");
}
- String rotationParam;
+ int rotationDegrees;
switch (rotation) {
case Surface.ROTATION_0:
- rotationParam = "rotation=0";
+ rotationDegrees = 0;
break;
case Surface.ROTATION_90:
- rotationParam = "rotation=90";
+ rotationDegrees = 90;
break;
case Surface.ROTATION_180:
- rotationParam = "rotation=180";
+ rotationDegrees = 180;
break;
case Surface.ROTATION_270:
- rotationParam = "rotation=270";
+ rotationDegrees = 270;
break;
default:
Log.e(TAG, "Unknown device rotation");
- rotationParam = null;
+ rotationDegrees = -1;
}
- if (rotationParam != null) {
- sRotationUpdateCb.accept(rotationParam);
+ if (rotationDegrees != -1) {
+ sRotationCallback.accept(rotationDegrees);
}
}
/**
* publish the change of device folded state if any.
*/
- static void updateFoldState(boolean newFolded) {
+ static void updateFoldState(boolean foldState) {
synchronized (sFoldStateLock) {
- if (sDeviceFold != newFolded) {
- sDeviceFold = newFolded;
- String foldParam;
- if (newFolded) {
- foldParam = "device_folded=on";
- } else {
- foldParam = "device_folded=off";
- }
- sFoldUpdateCb.accept(foldParam);
+ if (sFoldState == null || sFoldState != foldState) {
+ sFoldState = foldState;
+ sFoldStateCallback.accept(foldState);
+ }
+ }
+ }
+
+ /**
+ * forceUpdate is called when audioserver restarts.
+ */
+ static void forceUpdate() {
+ synchronized (sRotationLock) {
+ sRotation = null;
+ }
+ updateOrientation(); // We will get at least one orientation update now.
+ synchronized (sFoldStateLock) {
+ if (sFoldState != null) {
+ sFoldStateCallback.accept(sFoldState);
}
}
}
@@ -185,4 +194,4 @@
updateOrientation();
}
}
-}
\ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/audio/SoundDoseHelper.java b/services/core/java/com/android/server/audio/SoundDoseHelper.java
index 3dac04c..bb49a18 100644
--- a/services/core/java/com/android/server/audio/SoundDoseHelper.java
+++ b/services/core/java/com/android/server/audio/SoundDoseHelper.java
@@ -41,6 +41,7 @@
import android.text.TextUtils;
import android.util.Log;
import android.util.MathUtils;
+import android.util.SparseIntArray;
import com.android.internal.R;
import com.android.internal.annotations.GuardedBy;
@@ -52,7 +53,6 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
-import java.util.HashMap;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicReference;
@@ -112,6 +112,8 @@
private static final long GLOBAL_TIME_OFFSET_UNINITIALIZED = -1;
+ private static final int SAFE_MEDIA_VOLUME_UNINITIALIZED = -1;
+
private final EventLogger mLogger = new EventLogger(AudioService.LOG_NB_EVENTS_SOUND_DOSE,
"CSD updates");
@@ -132,15 +134,6 @@
// For now using the same value for CSD supported devices
private float mSafeMediaVolumeDbfs;
- private static class SafeDeviceVolumeInfo {
- int mDeviceType;
- int mSafeVolumeIndex = -1;
-
- SafeDeviceVolumeInfo(int deviceType) {
- mDeviceType = deviceType;
- }
- }
-
/**
* mSafeMediaVolumeDevices lists the devices for which safe media volume is enforced.
* Contains a safe volume index for a given device type.
@@ -152,25 +145,7 @@
* This level corresponds to a loudness of 85 dB SPL for the warning to be displayed when
* the headset is compliant to EN 60950 with a max loudness of 100dB SPL.
*/
- private final HashMap<Integer, SafeDeviceVolumeInfo> mSafeMediaVolumeDevices =
- new HashMap<>() {{
- put(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
- new SafeDeviceVolumeInfo(AudioSystem.DEVICE_OUT_WIRED_HEADSET));
- put(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
- new SafeDeviceVolumeInfo(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE));
- put(AudioSystem.DEVICE_OUT_USB_HEADSET,
- new SafeDeviceVolumeInfo(AudioSystem.DEVICE_OUT_USB_HEADSET));
- put(AudioSystem.DEVICE_OUT_BLE_HEADSET,
- new SafeDeviceVolumeInfo(AudioSystem.DEVICE_OUT_BLE_HEADSET));
- put(AudioSystem.DEVICE_OUT_BLE_BROADCAST,
- new SafeDeviceVolumeInfo(AudioSystem.DEVICE_OUT_BLE_BROADCAST));
- put(AudioSystem.DEVICE_OUT_HEARING_AID,
- new SafeDeviceVolumeInfo(AudioSystem.DEVICE_OUT_HEARING_AID));
- put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,
- new SafeDeviceVolumeInfo(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES));
- put(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
- new SafeDeviceVolumeInfo(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP));
- }};
+ private final SparseIntArray mSafeMediaVolumeDevices = new SparseIntArray();
// mMusicActiveMs is the cumulative time of music activity since safe volume was disabled.
// When this time reaches UNSAFE_VOLUME_MUSIC_ACTIVE_MS_MAX, the safe media volume is re-enabled
@@ -291,6 +266,7 @@
mEnableCsd = mContext.getResources().getBoolean(R.bool.config_audio_csd_enabled_default);
initCsd();
+ initSafeVolumes();
mSafeMediaVolumeState = mSettings.getGlobalInt(audioService.getContentResolver(),
Settings.Global.AUDIO_SAFE_VOLUME_STATE, SAFE_MEDIA_VOLUME_NOT_CONFIGURED);
@@ -305,7 +281,26 @@
Context.ALARM_SERVICE);
}
- float getRs2Value() {
+ void initSafeVolumes() {
+ mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_WIRED_HEADSET,
+ SAFE_MEDIA_VOLUME_UNINITIALIZED);
+ mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_WIRED_HEADPHONE,
+ SAFE_MEDIA_VOLUME_UNINITIALIZED);
+ mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_USB_HEADSET,
+ SAFE_MEDIA_VOLUME_UNINITIALIZED);
+ mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_BLE_HEADSET,
+ SAFE_MEDIA_VOLUME_UNINITIALIZED);
+ mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_BLE_BROADCAST,
+ SAFE_MEDIA_VOLUME_UNINITIALIZED);
+ mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_HEARING_AID,
+ SAFE_MEDIA_VOLUME_UNINITIALIZED);
+ mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP_HEADPHONES,
+ SAFE_MEDIA_VOLUME_UNINITIALIZED);
+ mSafeMediaVolumeDevices.append(AudioSystem.DEVICE_OUT_BLUETOOTH_A2DP,
+ SAFE_MEDIA_VOLUME_UNINITIALIZED);
+ }
+
+ float getOutputRs2UpperBound() {
if (!mEnableCsd) {
return 0.f;
}
@@ -317,14 +312,14 @@
}
try {
- return soundDose.getOutputRs2();
+ return soundDose.getOutputRs2UpperBound();
} catch (RemoteException e) {
Log.e(TAG, "Exception while getting the RS2 exposure value", e);
return 0.f;
}
}
- void setRs2Value(float rs2Value) {
+ void setOutputRs2UpperBound(float rs2Value) {
if (!mEnableCsd) {
return;
}
@@ -336,7 +331,7 @@
}
try {
- soundDose.setOutputRs2(rs2Value);
+ soundDose.setOutputRs2UpperBound(rs2Value);
} catch (RemoteException e) {
Log.e(TAG, "Exception while setting the RS2 exposure value", e);
}
@@ -435,12 +430,12 @@
}
/*package*/ int safeMediaVolumeIndex(int device) {
- final SafeDeviceVolumeInfo vi = mSafeMediaVolumeDevices.get(device);
- if (vi == null) {
+ final int vol = mSafeMediaVolumeDevices.get(device);
+ if (vol == SAFE_MEDIA_VOLUME_UNINITIALIZED) {
return MAX_STREAM_VOLUME[AudioSystem.STREAM_MUSIC];
}
- return vi.mSafeVolumeIndex;
+ return vol;
}
/*package*/ void restoreMusicActiveMs() {
@@ -465,14 +460,15 @@
AudioService.VolumeStreamState streamState = mAudioService.getVssVolumeForStream(
AudioSystem.STREAM_MUSIC);
- for (SafeDeviceVolumeInfo vi : mSafeMediaVolumeDevices.values()) {
- int index = streamState.getIndex(vi.mDeviceType);
- int safeIndex = safeMediaVolumeIndex(vi.mDeviceType);
+ for (int i = 0; i < mSafeMediaVolumeDevices.size(); ++i) {
+ int deviceType = mSafeMediaVolumeDevices.keyAt(i);
+ int index = streamState.getIndex(deviceType);
+ int safeIndex = safeMediaVolumeIndex(deviceType);
if (index > safeIndex) {
- streamState.setIndex(safeIndex, vi.mDeviceType, caller,
+ streamState.setIndex(safeIndex, deviceType, caller,
true /*hasModifyAudioSettings*/);
mAudioHandler.sendMessageAtTime(
- mAudioHandler.obtainMessage(MSG_SET_DEVICE_VOLUME, vi.mDeviceType,
+ mAudioHandler.obtainMessage(MSG_SET_DEVICE_VOLUME, deviceType,
/*arg2=*/0, streamState), /*delay=*/0);
}
}
@@ -494,7 +490,7 @@
private boolean checkSafeMediaVolume_l(int streamType, int index, int device) {
return (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE)
&& (AudioService.mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC)
- && (mSafeMediaVolumeDevices.containsKey(device))
+ && safeDevicesContains(device)
&& (index > safeMediaVolumeIndex(device));
}
@@ -546,7 +542,7 @@
synchronized (mSafeMediaVolumeStateLock) {
if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_INACTIVE) {
int device = mAudioService.getDeviceForStream(AudioSystem.STREAM_MUSIC);
- if (mSafeMediaVolumeDevices.containsKey(device) && isStreamActive) {
+ if (safeDevicesContains(device) && isStreamActive) {
scheduleMusicActiveCheck();
int index = mAudioService.getVssVolumeForDevice(AudioSystem.STREAM_MUSIC,
device);
@@ -589,14 +585,15 @@
}
/*package*/ void initSafeMediaVolumeIndex() {
- for (SafeDeviceVolumeInfo vi : mSafeMediaVolumeDevices.values()) {
- vi.mSafeVolumeIndex = getSafeDeviceMediaVolumeIndex(vi.mDeviceType);
+ for (int i = 0; i < mSafeMediaVolumeDevices.size(); ++i) {
+ int deviceType = mSafeMediaVolumeDevices.keyAt(i);
+ mSafeMediaVolumeDevices.put(deviceType, getSafeDeviceMediaVolumeIndex(deviceType));
}
}
/*package*/ int getSafeMediaVolumeIndex(int device) {
if (mSafeMediaVolumeState == SAFE_MEDIA_VOLUME_ACTIVE
- && mSafeMediaVolumeDevices.containsKey(device)) {
+ && safeDevicesContains(device)) {
return safeMediaVolumeIndex(device);
} else {
return -1;
@@ -614,7 +611,7 @@
}
/*package*/ boolean safeDevicesContains(int device) {
- return mSafeMediaVolumeDevices.containsKey(device);
+ return mSafeMediaVolumeDevices.indexOfKey(device) >= 0;
}
/*package*/ void invalidatPendingVolumeCommand() {
@@ -665,9 +662,9 @@
pw.print(" mSafeMediaVolumeState=");
pw.println(safeMediaVolumeStateToString(mSafeMediaVolumeState));
pw.print(" mSafeMediaVolumeIndex="); pw.println(mSafeMediaVolumeIndex);
- for (SafeDeviceVolumeInfo vi : mSafeMediaVolumeDevices.values()) {
- pw.print(" mSafeMediaVolumeIndex["); pw.print(vi.mDeviceType);
- pw.print("]="); pw.println(vi.mSafeVolumeIndex);
+ for (int i = 0; i < mSafeMediaVolumeDevices.size(); ++i) {
+ pw.print(" mSafeMediaVolumeIndex["); pw.print(mSafeMediaVolumeDevices.keyAt(i));
+ pw.print("]="); pw.println(mSafeMediaVolumeDevices.valueAt(i));
}
pw.print(" mSafeMediaVolumeDbfs="); pw.println(mSafeMediaVolumeDbfs);
pw.print(" mMusicActiveMs="); pw.println(mMusicActiveMs);
@@ -721,7 +718,7 @@
}
if (AudioService.mStreamVolumeAlias[streamType] == AudioSystem.STREAM_MUSIC
- && mSafeMediaVolumeDevices.containsKey(device)) {
+ && safeDevicesContains(device)) {
soundDose.updateAttenuation(
AudioSystem.getStreamVolumeDB(AudioSystem.STREAM_MUSIC,
(newIndex + 5) / 10,
@@ -735,6 +732,16 @@
private void initCsd() {
if (!mEnableCsd) {
+ final ISoundDose soundDose = AudioSystem.getSoundDoseInterface(mSoundDoseCallback);
+ if (soundDose == null) {
+ Log.w(TAG, "ISoundDose instance is null.");
+ return;
+ }
+ try {
+ soundDose.disableCsd();
+ } catch (RemoteException e) {
+ Log.e(TAG, "Cannot disable CSD", e);
+ }
return;
}
diff --git a/services/core/java/com/android/server/audio/SpatializerHelper.java b/services/core/java/com/android/server/audio/SpatializerHelper.java
index 3ea4f4f..5edd434 100644
--- a/services/core/java/com/android/server/audio/SpatializerHelper.java
+++ b/services/core/java/com/android/server/audio/SpatializerHelper.java
@@ -172,13 +172,17 @@
// initialization
@SuppressWarnings("StaticAssignmentInConstructor")
SpatializerHelper(@NonNull AudioService mother, @NonNull AudioSystemAdapter asa,
- boolean headTrackingEnabledByDefault) {
+ boolean binauralEnabledDefault,
+ boolean transauralEnabledDefault,
+ boolean headTrackingEnabledDefault) {
mAudioService = mother;
mASA = asa;
// "StaticAssignmentInConstructor" warning is suppressed as the SpatializerHelper being
// constructed here is the factory for SADeviceState, thus SADeviceState and its
// private static field sHeadTrackingEnabledDefault should never be accessed directly.
- SADeviceState.sHeadTrackingEnabledDefault = headTrackingEnabledByDefault;
+ SADeviceState.sBinauralEnabledDefault = binauralEnabledDefault;
+ SADeviceState.sTransauralEnabledDefault = transauralEnabledDefault;
+ SADeviceState.sHeadTrackingEnabledDefault = headTrackingEnabledDefault;
}
synchronized void init(boolean effectExpected, @Nullable String settings) {
@@ -1066,7 +1070,7 @@
if (transform.length != 6) {
throw new IllegalArgumentException("invalid array size" + transform.length);
}
- if (!checkSpatForHeadTracking("setGlobalTransform")) {
+ if (!checkSpatializerForHeadTracking("setGlobalTransform")) {
return;
}
try {
@@ -1077,7 +1081,7 @@
}
synchronized void recenterHeadTracker() {
- if (!checkSpatForHeadTracking("recenterHeadTracker")) {
+ if (!checkSpatializerForHeadTracking("recenterHeadTracker")) {
return;
}
try {
@@ -1087,8 +1091,30 @@
}
}
+ synchronized void setDisplayOrientation(float displayOrientation) {
+ if (!checkSpatializer("setDisplayOrientation")) {
+ return;
+ }
+ try {
+ mSpat.setDisplayOrientation(displayOrientation);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling setDisplayOrientation", e);
+ }
+ }
+
+ synchronized void setFoldState(boolean folded) {
+ if (!checkSpatializer("setFoldState")) {
+ return;
+ }
+ try {
+ mSpat.setFoldState(folded);
+ } catch (RemoteException e) {
+ Log.e(TAG, "Error calling setFoldState", e);
+ }
+ }
+
synchronized void setDesiredHeadTrackingMode(@Spatializer.HeadTrackingModeSet int mode) {
- if (!checkSpatForHeadTracking("setDesiredHeadTrackingMode")) {
+ if (!checkSpatializerForHeadTracking("setDesiredHeadTrackingMode")) {
return;
}
if (mode != Spatializer.HEAD_TRACKING_MODE_DISABLED) {
@@ -1186,7 +1212,7 @@
return mHeadTrackerAvailable;
}
- private boolean checkSpatForHeadTracking(String funcName) {
+ private boolean checkSpatializer(String funcName) {
switch (mState) {
case STATE_UNINITIALIZED:
case STATE_NOT_SUPPORTED:
@@ -1197,14 +1223,18 @@
case STATE_ENABLED_AVAILABLE:
if (mSpat == null) {
// try to recover by resetting the native spatializer state
- Log.e(TAG, "checkSpatForHeadTracking(): "
- + "native spatializer should not be null in state: " + mState);
+ Log.e(TAG, "checkSpatializer(): called from " + funcName
+ + "(), native spatializer should not be null in state: " + mState);
postReset();
return false;
}
break;
}
- return mIsHeadTrackingSupported;
+ return true;
+ }
+
+ private boolean checkSpatializerForHeadTracking(String funcName) {
+ return checkSpatializer(funcName) && mIsHeadTrackingSupported;
}
private void dispatchActualHeadTrackingMode(int newMode) {
@@ -1521,10 +1551,12 @@
}
/*package*/ static final class SADeviceState {
+ private static boolean sBinauralEnabledDefault = true;
+ private static boolean sTransauralEnabledDefault = true;
private static boolean sHeadTrackingEnabledDefault = false;
final @AudioDeviceInfo.AudioDeviceType int mDeviceType;
final @NonNull String mDeviceAddress;
- boolean mEnabled = true; // by default, SA is enabled on any device
+ boolean mEnabled;
boolean mHasHeadTracker = false;
boolean mHeadTrackerEnabled;
static final String SETTING_FIELD_SEPARATOR = ",";
@@ -1540,6 +1572,12 @@
SADeviceState(@AudioDeviceInfo.AudioDeviceType int deviceType, @Nullable String address) {
mDeviceType = deviceType;
mDeviceAddress = isWireless(deviceType) ? Objects.requireNonNull(address) : "";
+ final int spatMode = SPAT_MODE_FOR_DEVICE_TYPE.get(deviceType, Integer.MIN_VALUE);
+ mEnabled = spatMode == SpatializationMode.SPATIALIZER_BINAURAL
+ ? sBinauralEnabledDefault
+ : spatMode == SpatializationMode.SPATIALIZER_TRANSAURAL
+ ? sTransauralEnabledDefault
+ : false;
mHeadTrackerEnabled = sHeadTrackingEnabledDefault;
}
diff --git a/services/core/java/com/android/server/biometrics/TEST_MAPPING b/services/core/java/com/android/server/biometrics/TEST_MAPPING
index 8b80674..daca00b 100644
--- a/services/core/java/com/android/server/biometrics/TEST_MAPPING
+++ b/services/core/java/com/android/server/biometrics/TEST_MAPPING
@@ -6,5 +6,24 @@
{
"name": "CtsBiometricsHostTestCases"
}
- ]
-}
\ No newline at end of file
+ ],
+ "ironwood-postsubmit": [
+ {
+ "name": "BiometricsE2eTests",
+ "options": [
+ {
+ "include-annotation": "android.platform.test.annotations.IwTest"
+ },
+ {
+ "exclude-annotation": "org.junit.Ignore"
+ },
+ {
+ "include-filter": "android.platform.test.scenario.biometrics"
+ },
+ {
+ "exclude-annotation": "android.platform.test.annotations.FlakyTest"
+ }
+ ]
+ }
+ ]
+}
diff --git a/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java b/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java
index 82444f0..6bd4880 100644
--- a/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java
+++ b/services/core/java/com/android/server/biometrics/log/BiometricFrameworkStatsLogger.java
@@ -16,14 +16,22 @@
package com.android.server.biometrics.log;
+import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.hardware.biometrics.BiometricsProtoEnums;
import android.hardware.biometrics.IBiometricContextListener;
+import android.hardware.biometrics.common.AuthenticateReason;
+import android.hardware.biometrics.common.OperationContext;
import android.hardware.biometrics.common.OperationReason;
+import android.hardware.biometrics.common.WakeReason;
import android.util.Slog;
import android.view.Surface;
+import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.FrameworkStatsLog;
+import java.util.stream.Stream;
+
/**
* Wrapper for {@link FrameworkStatsLog} to isolate the testable parts.
*/
@@ -63,7 +71,7 @@
orientationType(operationContext.getOrientation()),
foldType(operationContext.getFoldState()),
operationContext.getOrderAndIncrement(),
- BiometricsProtoEnums.WAKE_REASON_UNKNOWN);
+ toProtoWakeReason(operationContext));
}
/** {@see FrameworkStatsLog.BIOMETRIC_AUTHENTICATED}. */
@@ -89,7 +97,8 @@
orientationType(operationContext.getOrientation()),
foldType(operationContext.getFoldState()),
operationContext.getOrderAndIncrement(),
- BiometricsProtoEnums.WAKE_REASON_UNKNOWN);
+ toProtoWakeReason(operationContext),
+ toProtoWakeReasonDetails(operationContext));
}
/** {@see FrameworkStatsLog.BIOMETRIC_AUTHENTICATED}. */
@@ -137,7 +146,81 @@
orientationType(operationContext.getOrientation()),
foldType(operationContext.getFoldState()),
operationContext.getOrderAndIncrement(),
- BiometricsProtoEnums.WAKE_REASON_UNKNOWN);
+ toProtoWakeReason(operationContext),
+ toProtoWakeReasonDetails(operationContext));
+ }
+
+ @VisibleForTesting
+ static int[] toProtoWakeReasonDetails(@NonNull OperationContextExt operationContext) {
+ final OperationContext ctx = operationContext.toAidlContext();
+ return Stream.of(toProtoWakeReasonDetails(ctx.authenticateReason))
+ .mapToInt(i -> i)
+ .filter(i -> i != BiometricsProtoEnums.DETAILS_UNKNOWN)
+ .toArray();
+ }
+
+ @VisibleForTesting
+ static int toProtoWakeReason(@NonNull OperationContextExt operationContext) {
+ @WakeReason final int reason = operationContext.getWakeReason();
+ switch (reason) {
+ case WakeReason.POWER_BUTTON:
+ return BiometricsProtoEnums.WAKE_REASON_POWER_BUTTON;
+ case WakeReason.GESTURE:
+ return BiometricsProtoEnums.WAKE_REASON_GESTURE;
+ case WakeReason.WAKE_KEY:
+ return BiometricsProtoEnums.WAKE_REASON_WAKE_KEY;
+ case WakeReason.WAKE_MOTION:
+ return BiometricsProtoEnums.WAKE_REASON_WAKE_MOTION;
+ case WakeReason.LID:
+ return BiometricsProtoEnums.WAKE_REASON_LID;
+ case WakeReason.DISPLAY_GROUP_ADDED:
+ return BiometricsProtoEnums.WAKE_REASON_DISPLAY_GROUP_ADDED;
+ case WakeReason.TAP:
+ return BiometricsProtoEnums.WAKE_REASON_TAP;
+ case WakeReason.LIFT:
+ return BiometricsProtoEnums.WAKE_REASON_LIFT;
+ case WakeReason.BIOMETRIC:
+ return BiometricsProtoEnums.WAKE_REASON_BIOMETRIC;
+ default:
+ return BiometricsProtoEnums.WAKE_REASON_UNKNOWN;
+ }
+ }
+
+ private static int toProtoWakeReasonDetails(@Nullable AuthenticateReason reason) {
+ if (reason != null) {
+ switch (reason.getTag()) {
+ case AuthenticateReason.faceAuthenticateReason:
+ return toProtoWakeReasonDetailsFromFace(reason.getFaceAuthenticateReason());
+ }
+ }
+ return BiometricsProtoEnums.DETAILS_UNKNOWN;
+ }
+
+ private static int toProtoWakeReasonDetailsFromFace(@AuthenticateReason.Face int reason) {
+ switch (reason) {
+ case AuthenticateReason.Face.STARTED_WAKING_UP:
+ return BiometricsProtoEnums.DETAILS_FACE_STARTED_WAKING_UP;
+ case AuthenticateReason.Face.PRIMARY_BOUNCER_SHOWN:
+ return BiometricsProtoEnums.DETAILS_FACE_PRIMARY_BOUNCER_SHOWN;
+ case AuthenticateReason.Face.ASSISTANT_VISIBLE:
+ return BiometricsProtoEnums.DETAILS_FACE_ASSISTANT_VISIBLE;
+ case AuthenticateReason.Face.ALTERNATE_BIOMETRIC_BOUNCER_SHOWN:
+ return BiometricsProtoEnums.DETAILS_FACE_ALTERNATE_BIOMETRIC_BOUNCER_SHOWN;
+ case AuthenticateReason.Face.NOTIFICATION_PANEL_CLICKED:
+ return BiometricsProtoEnums.DETAILS_FACE_NOTIFICATION_PANEL_CLICKED;
+ case AuthenticateReason.Face.OCCLUDING_APP_REQUESTED:
+ return BiometricsProtoEnums.DETAILS_FACE_OCCLUDING_APP_REQUESTED;
+ case AuthenticateReason.Face.PICK_UP_GESTURE_TRIGGERED:
+ return BiometricsProtoEnums.DETAILS_FACE_PICK_UP_GESTURE_TRIGGERED;
+ case AuthenticateReason.Face.QS_EXPANDED:
+ return BiometricsProtoEnums.DETAILS_FACE_QS_EXPANDED;
+ case AuthenticateReason.Face.SWIPE_UP_ON_BOUNCER:
+ return BiometricsProtoEnums.DETAILS_FACE_SWIPE_UP_ON_BOUNCER;
+ case AuthenticateReason.Face.UDFPS_POINTER_DOWN:
+ return BiometricsProtoEnums.DETAILS_FACE_UDFPS_POINTER_DOWN;
+ default:
+ return BiometricsProtoEnums.DETAILS_UNKNOWN;
+ }
}
/** {@see FrameworkStatsLog.BIOMETRIC_SYSTEM_HEALTH_ISSUE_DETECTED}. */
diff --git a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
index ecb7e7c..2934339 100644
--- a/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
+++ b/services/core/java/com/android/server/biometrics/log/OperationContextExt.java
@@ -188,10 +188,17 @@
}
/** {@link OperationContext#reason}. */
+ @OperationReason
public byte getReason() {
return mAidlContext.reason;
}
+ /** {@link OperationContext#wakeReason}. */
+ @WakeReason
+ public int getWakeReason() {
+ return mAidlContext.wakeReason;
+ }
+
/** If the screen is currently on. */
public boolean isDisplayOn() {
return mIsDisplayOn;
diff --git a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
index dc00ffc..01ffc7e 100644
--- a/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
+++ b/services/core/java/com/android/server/biometrics/sensors/fingerprint/FingerprintService.java
@@ -314,7 +314,8 @@
final FingerprintSensorPropertiesInternal sensorProps =
provider.second.getSensorProperties(options.getSensorId());
if (!isKeyguard && !Utils.isSettings(getContext(), opPackageName)
- && sensorProps != null && sensorProps.isAnyUdfpsType()) {
+ && sensorProps != null && (sensorProps.isAnyUdfpsType()
+ || sensorProps.isAnySidefpsType())) {
try {
return authenticateWithPrompt(operationId, sensorProps, callingUid,
callingUserId, receiver, opPackageName,
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
index b66120d..6a01042 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceAidlImpl.java
@@ -86,8 +86,7 @@
@Override
public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig,
- boolean withAudio, ITunerCallback callback, int targetSdkVersion)
- throws RemoteException {
+ boolean withAudio, ITunerCallback callback) throws RemoteException {
if (isDebugEnabled()) {
Slogf.d(TAG, "Opening module %d", moduleId);
}
@@ -95,7 +94,7 @@
if (callback == null) {
throw new IllegalArgumentException("Callback must not be null");
}
- return mHalAidl.openSession(moduleId, bandConfig, withAudio, callback, targetSdkVersion);
+ return mHalAidl.openSession(moduleId, bandConfig, withAudio, callback);
}
@Override
diff --git a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
index 8a1ba19..408fba1 100644
--- a/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/IRadioServiceHidlImpl.java
@@ -92,8 +92,7 @@
@Override
public ITuner openTuner(int moduleId, RadioManager.BandConfig bandConfig,
- boolean withAudio, ITunerCallback callback, int targetSdkVersion)
- throws RemoteException {
+ boolean withAudio, ITunerCallback callback) throws RemoteException {
if (isDebugEnabled()) {
Slog.d(TAG, "Opening module " + moduleId);
}
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
index 772cd41..03acf72 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/BroadcastRadioServiceImpl.java
@@ -199,8 +199,7 @@
*/
@Nullable
public ITuner openSession(int moduleId, @Nullable RadioManager.BandConfig legacyConfig,
- boolean withAudio, ITunerCallback callback, int targetSdkVersion)
- throws RemoteException {
+ boolean withAudio, ITunerCallback callback) throws RemoteException {
if (DEBUG) {
Slogf.d(TAG, "Open AIDL radio session");
}
@@ -223,7 +222,7 @@
}
}
- TunerSession tunerSession = radioModule.openSession(callback, targetSdkVersion);
+ TunerSession tunerSession = radioModule.openSession(callback);
if (legacyConfig != null) {
tunerSession.setConfiguration(legacyConfig);
}
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
index c0a238f..4f2bfd1 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/ConversionUtils.java
@@ -17,6 +17,10 @@
package com.android.server.broadcastradio.aidl;
import android.annotation.Nullable;
+import android.annotation.SuppressLint;
+import android.app.compat.CompatChanges;
+import android.compat.annotation.ChangeId;
+import android.compat.annotation.EnabledSince;
import android.hardware.broadcastradio.AmFmRegionConfig;
import android.hardware.broadcastradio.Announcement;
import android.hardware.broadcastradio.DabTableEntry;
@@ -57,16 +61,24 @@
* {@link android.hardware.radio}
*/
final class ConversionUtils {
- // TODO(b/241118988): Add unit test for ConversionUtils class
private static final String TAG = "BcRadioAidlSrv.convert";
+ /**
+ * With RADIO_U_VERSION_REQUIRED enabled, 44-bit DAB identifier
+ * {@link IdentifierType#DAB_SID_EXT} from broadcast radio HAL can be passed as
+ * {@link ProgramSelector#IDENTIFIER_TYPE_DAB_DMB_SID_EXT} to {@link RadioTuner}.
+ */
+ @ChangeId
+ @EnabledSince(targetSdkVersion = Build.VERSION_CODES.UPSIDE_DOWN_CAKE)
+ public static final long RADIO_U_VERSION_REQUIRED = 261770108L;
+
private ConversionUtils() {
throw new UnsupportedOperationException("ConversionUtils class is noninstantiable");
}
- static boolean isAtLeastU(int targetSdkVersion) {
- // TODO(b/261770108): Use version code for U.
- return targetSdkVersion >= Build.VERSION_CODES.CUR_DEVELOPMENT;
+ @SuppressLint("AndroidFrameworkRequiresPermission")
+ static boolean isAtLeastU(int uid) {
+ return CompatChanges.isChangeEnabled(RADIO_U_VERSION_REQUIRED, uid);
}
static RuntimeException throwOnError(RuntimeException halException, String action) {
@@ -584,9 +596,8 @@
return id.getType() == ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT;
}
- static boolean programSelectorMeetsSdkVersionRequirement(ProgramSelector sel,
- int targetSdkVersion) {
- if (isAtLeastU(targetSdkVersion)) {
+ static boolean programSelectorMeetsSdkVersionRequirement(ProgramSelector sel, int uid) {
+ if (isAtLeastU(uid)) {
return true;
}
if (sel.getPrimaryId().getType() == ProgramSelector.IDENTIFIER_TYPE_DAB_DMB_SID_EXT) {
@@ -601,12 +612,11 @@
return true;
}
- static boolean programInfoMeetsSdkVersionRequirement(RadioManager.ProgramInfo info,
- int targetSdkVersion) {
- if (isAtLeastU(targetSdkVersion)) {
+ static boolean programInfoMeetsSdkVersionRequirement(RadioManager.ProgramInfo info, int uid) {
+ if (isAtLeastU(uid)) {
return true;
}
- if (!programSelectorMeetsSdkVersionRequirement(info.getSelector(), targetSdkVersion)) {
+ if (!programSelectorMeetsSdkVersionRequirement(info.getSelector(), uid)) {
return false;
}
if (isNewIdentifierInU(info.getLogicallyTunedTo())
@@ -622,16 +632,15 @@
return true;
}
- static ProgramList.Chunk convertChunkToTargetSdkVersion(ProgramList.Chunk chunk,
- int targetSdkVersion) {
- if (isAtLeastU(targetSdkVersion)) {
+ static ProgramList.Chunk convertChunkToTargetSdkVersion(ProgramList.Chunk chunk, int uid) {
+ if (isAtLeastU(uid)) {
return chunk;
}
Set<RadioManager.ProgramInfo> modified = new ArraySet<>();
Iterator<RadioManager.ProgramInfo> modifiedIterator = chunk.getModified().iterator();
while (modifiedIterator.hasNext()) {
RadioManager.ProgramInfo info = modifiedIterator.next();
- if (programInfoMeetsSdkVersionRequirement(info, targetSdkVersion)) {
+ if (programInfoMeetsSdkVersionRequirement(info, uid)) {
modified.add(info);
}
}
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
index f8c19ae..132fb8e 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/RadioModule.java
@@ -101,9 +101,9 @@
ConversionUtils.programSelectorFromHalProgramSelector(programSelector);
int tunerResult = ConversionUtils.halResultToTunerResult(result);
synchronized (mLock) {
- fanoutAidlCallbackLocked((cb, sdkVersion) -> {
+ fanoutAidlCallbackLocked((cb, uid) -> {
if (csel != null && !ConversionUtils
- .programSelectorMeetsSdkVersionRequirement(csel, sdkVersion)) {
+ .programSelectorMeetsSdkVersionRequirement(csel, uid)) {
Slogf.e(TAG, "onTuneFailed: cannot send program selector "
+ "requiring higher target SDK version");
return;
@@ -123,9 +123,9 @@
"Program info from AIDL HAL is invalid");
synchronized (mLock) {
mCurrentProgramInfo = currentProgramInfo;
- fanoutAidlCallbackLocked((cb, sdkVersion) -> {
+ fanoutAidlCallbackLocked((cb, uid) -> {
if (!ConversionUtils.programInfoMeetsSdkVersionRequirement(
- currentProgramInfo, sdkVersion)) {
+ currentProgramInfo, uid)) {
Slogf.e(TAG, "onCurrentProgramInfoChanged: cannot send "
+ "program info requiring higher target SDK version");
return;
@@ -156,7 +156,7 @@
fireLater(() -> {
synchronized (mLock) {
mAntennaConnected = connected;
- fanoutAidlCallbackLocked((cb, sdkVersion) -> cb.onAntennaState(connected));
+ fanoutAidlCallbackLocked((cb, uid) -> cb.onAntennaState(connected));
}
});
}
@@ -165,7 +165,7 @@
public void onConfigFlagUpdated(int flag, boolean value) {
fireLater(() -> {
synchronized (mLock) {
- fanoutAidlCallbackLocked((cb, sdkVersion) -> {
+ fanoutAidlCallbackLocked((cb, uid) -> {
cb.onConfigFlagUpdated(flag, value);
});
}
@@ -178,7 +178,7 @@
synchronized (mLock) {
Map<String, String> cparam =
ConversionUtils.vendorInfoFromHalVendorKeyValues(parameters);
- fanoutAidlCallbackLocked((cb, sdkVersion) -> {
+ fanoutAidlCallbackLocked((cb, uid) -> {
cb.onParametersUpdated(cparam);
});
}
@@ -244,14 +244,14 @@
mService.setTunerCallback(mHalTunerCallback);
}
- TunerSession openSession(android.hardware.radio.ITunerCallback userCb, int targetSdkVersion)
+ TunerSession openSession(android.hardware.radio.ITunerCallback userCb)
throws RemoteException {
mLogger.logRadioEvent("Open TunerSession");
TunerSession tunerSession;
Boolean antennaConnected;
RadioManager.ProgramInfo currentProgramInfo;
synchronized (mLock) {
- tunerSession = new TunerSession(this, mService, userCb, targetSdkVersion);
+ tunerSession = new TunerSession(this, mService, userCb);
mAidlTunerSessions.add(tunerSession);
antennaConnected = mAntennaConnected;
currentProgramInfo = mCurrentProgramInfo;
@@ -404,7 +404,7 @@
}
interface AidlCallbackRunnable {
- void run(android.hardware.radio.ITunerCallback callback, int targetSdkVersion)
+ void run(android.hardware.radio.ITunerCallback callback, int uid)
throws RemoteException;
}
@@ -423,7 +423,7 @@
for (int i = 0; i < mAidlTunerSessions.size(); i++) {
try {
runnable.run(mAidlTunerSessions.valueAt(i).mCallback,
- mAidlTunerSessions.valueAt(i).getTargetSdkVersion());
+ mAidlTunerSessions.valueAt(i).getUid());
} catch (DeadObjectException ex) {
// The other side died without calling close(), so just purge it from our records.
Slogf.e(TAG, "Removing dead TunerSession");
diff --git a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
index fe8c238..0a3823f 100644
--- a/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
+++ b/services/core/java/com/android/server/broadcastradio/aidl/TunerSession.java
@@ -24,6 +24,7 @@
import android.hardware.radio.ProgramList;
import android.hardware.radio.ProgramSelector;
import android.hardware.radio.RadioManager;
+import android.os.Binder;
import android.os.RemoteException;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -46,7 +47,7 @@
private final RadioLogger mLogger;
private final RadioModule mModule;
final android.hardware.radio.ITunerCallback mCallback;
- private final int mTargetSdkVersion;
+ private final int mUid;
private final IBroadcastRadio mService;
@GuardedBy("mLock")
@@ -61,11 +62,11 @@
private RadioManager.BandConfig mPlaceHolderConfig;
TunerSession(RadioModule radioModule, IBroadcastRadio service,
- android.hardware.radio.ITunerCallback callback, int targetSdkVersion) {
+ android.hardware.radio.ITunerCallback callback) {
mModule = Objects.requireNonNull(radioModule, "radioModule cannot be null");
mService = Objects.requireNonNull(service, "service cannot be null");
mCallback = Objects.requireNonNull(callback, "callback cannot be null");
- mTargetSdkVersion = targetSdkVersion;
+ mUid = Binder.getCallingUid();
mLogger = new RadioLogger(TAG, TUNER_EVENT_LOGGER_QUEUE_SIZE);
}
@@ -130,7 +131,7 @@
mPlaceHolderConfig = Objects.requireNonNull(config, "config cannot be null");
}
Slogf.i(TAG, "Ignoring setConfiguration - not applicable for broadcastradio HAL AIDL");
- mModule.fanoutAidlCallback((cb, sdkVersion) -> cb.onConfigurationChanged(config));
+ mModule.fanoutAidlCallback((cb, mUid) -> cb.onConfigurationChanged(config));
}
@Override
@@ -254,7 +255,7 @@
Slogf.w(TAG, "Cannot start background scan on AIDL HAL client from non-current user");
return false;
}
- mModule.fanoutAidlCallback((cb, sdkVersion) -> {
+ mModule.fanoutAidlCallback((cb, mUid) -> {
cb.onBackgroundScanComplete();
});
return true;
@@ -284,8 +285,8 @@
mModule.onTunerSessionProgramListFilterChanged(this);
}
- int getTargetSdkVersion() {
- return mTargetSdkVersion;
+ int getUid() {
+ return mUid;
}
ProgramList.Filter getProgramListFilter() {
@@ -323,10 +324,9 @@
}
for (int i = 0; i < chunks.size(); i++) {
try {
- if (!ConversionUtils.isAtLeastU(getTargetSdkVersion())) {
+ if (!ConversionUtils.isAtLeastU(getUid())) {
ProgramList.Chunk downgradedChunk =
- ConversionUtils.convertChunkToTargetSdkVersion(chunks.get(i),
- getTargetSdkVersion());
+ ConversionUtils.convertChunkToTargetSdkVersion(chunks.get(i), getUid());
mCallback.onProgramListUpdated(downgradedChunk);
} else {
mCallback.onProgramListUpdated(chunks.get(i));
diff --git a/services/core/java/com/android/server/camera/CameraServiceProxy.java b/services/core/java/com/android/server/camera/CameraServiceProxy.java
index 4e3de3c..e8af840 100644
--- a/services/core/java/com/android/server/camera/CameraServiceProxy.java
+++ b/services/core/java/com/android/server/camera/CameraServiceProxy.java
@@ -243,11 +243,13 @@
public List<CameraStreamStats> mStreamStats;
public String mUserTag;
public int mVideoStabilizationMode;
+ public final long mLogId;
private long mDurationOrStartTimeMs; // Either start time, or duration once completed
CameraUsageEvent(String cameraId, int facing, String clientName, int apiLevel,
- boolean isNdk, int action, int latencyMs, int operatingMode, boolean deviceError) {
+ boolean isNdk, int action, int latencyMs, int operatingMode, boolean deviceError,
+ long logId) {
mCameraId = cameraId;
mCameraFacing = facing;
mClientName = clientName;
@@ -259,6 +261,7 @@
mLatencyMs = latencyMs;
mOperatingMode = operatingMode;
mDeviceError = deviceError;
+ mLogId = logId;
}
public void markCompleted(int internalReconfigure, long requestCount,
@@ -840,7 +843,8 @@
+ ", deviceError " + e.mDeviceError
+ ", streamCount is " + streamCount
+ ", userTag is " + e.mUserTag
- + ", videoStabilizationMode " + e.mVideoStabilizationMode);
+ + ", videoStabilizationMode " + e.mVideoStabilizationMode
+ + ", logId " + e.mLogId);
}
// Convert from CameraStreamStats to CameraStreamProto
CameraStreamProto[] streamProtos = new CameraStreamProto[MAX_STREAM_STATISTICS];
@@ -900,7 +904,7 @@
MessageNano.toByteArray(streamProtos[2]),
MessageNano.toByteArray(streamProtos[3]),
MessageNano.toByteArray(streamProtos[4]),
- e.mUserTag, e.mVideoStabilizationMode);
+ e.mUserTag, e.mVideoStabilizationMode, e.mLogId);
}
}
@@ -1089,6 +1093,7 @@
List<CameraStreamStats> streamStats = cameraState.getStreamStats();
String userTag = cameraState.getUserTag();
int videoStabilizationMode = cameraState.getVideoStabilizationMode();
+ long logId = cameraState.getLogId();
synchronized(mLock) {
// Update active camera list and notify NFC if necessary
boolean wasEmpty = mActiveCameraUsage.isEmpty();
@@ -1110,7 +1115,7 @@
CameraUsageEvent openEvent = new CameraUsageEvent(
cameraId, facing, clientName, apiLevel, isNdk,
FrameworkStatsLog.CAMERA_ACTION_EVENT__ACTION__OPEN,
- latencyMs, sessionType, deviceError);
+ latencyMs, sessionType, deviceError, logId);
mCameraUsageHistory.add(openEvent);
break;
case CameraSessionStats.CAMERA_STATE_ACTIVE:
@@ -1137,7 +1142,7 @@
CameraUsageEvent newEvent = new CameraUsageEvent(
cameraId, facing, clientName, apiLevel, isNdk,
FrameworkStatsLog.CAMERA_ACTION_EVENT__ACTION__SESSION,
- latencyMs, sessionType, deviceError);
+ latencyMs, sessionType, deviceError, logId);
CameraUsageEvent oldEvent = mActiveCameraUsage.put(cameraId, newEvent);
if (oldEvent != null) {
Slog.w(TAG, "Camera " + cameraId + " was already marked as active");
@@ -1181,7 +1186,7 @@
CameraUsageEvent closeEvent = new CameraUsageEvent(
cameraId, facing, clientName, apiLevel, isNdk,
FrameworkStatsLog.CAMERA_ACTION_EVENT__ACTION__CLOSE,
- latencyMs, sessionType, deviceError);
+ latencyMs, sessionType, deviceError, logId);
mCameraUsageHistory.add(closeEvent);
}
diff --git a/services/core/java/com/android/server/clipboard/ClipboardService.java b/services/core/java/com/android/server/clipboard/ClipboardService.java
index fab138b..85b4f75 100644
--- a/services/core/java/com/android/server/clipboard/ClipboardService.java
+++ b/services/core/java/com/android/server/clipboard/ClipboardService.java
@@ -470,6 +470,7 @@
callingPackage);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.SET_CLIP_SOURCE)
@Override
public void setPrimaryClipAsPackage(
ClipData clip,
@@ -478,8 +479,7 @@
@UserIdInt int userId,
int deviceId,
String sourcePackage) {
- getContext().enforceCallingOrSelfPermission(Manifest.permission.SET_CLIP_SOURCE,
- "Requires SET_CLIP_SOURCE permission");
+ setPrimaryClipAsPackage_enforcePermission();
checkAndSetPrimaryClip(clip, callingPackage, attributionTag, userId, deviceId,
sourcePackage);
}
@@ -765,11 +765,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.SET_CLIP_SOURCE)
@Override
public String getPrimaryClipSource(
String callingPackage, String attributionTag, int userId, int deviceId) {
- getContext().enforceCallingOrSelfPermission(Manifest.permission.SET_CLIP_SOURCE,
- "Requires SET_CLIP_SOURCE permission");
+ getPrimaryClipSource_enforcePermission();
final int intendingUid = getIntendingUid(callingPackage, userId);
final int intendingUserId = UserHandle.getUserId(intendingUid);
final int intendingDeviceId = getIntendingDeviceId(deviceId, intendingUid);
diff --git a/services/core/java/com/android/server/connectivity/Vpn.java b/services/core/java/com/android/server/connectivity/Vpn.java
index 6d3f8fd..1e9352d1 100644
--- a/services/core/java/com/android/server/connectivity/Vpn.java
+++ b/services/core/java/com/android/server/connectivity/Vpn.java
@@ -31,6 +31,7 @@
import static android.os.PowerWhitelistManager.REASON_VPN;
import static android.os.UserHandle.PER_USER_RANGE;
import static android.telephony.CarrierConfigManager.KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT;
+import static android.telephony.CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT;
import static com.android.net.module.util.NetworkStackConstants.IPV6_MIN_MTU;
import static com.android.server.vcn.util.PersistableBundleUtils.STRING_DESERIALIZER;
@@ -269,6 +270,42 @@
@VisibleForTesting
static final int DEFAULT_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT = 5 * 60;
+ /**
+ * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_AUTO} and
+ * {@link IkeSessionParams.ESP_ENCAP_TYPE_AUTO} for ESP packets.
+ *
+ * This is one of the possible customization values for
+ * CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT.
+ */
+ @VisibleForTesting
+ public static final int PREFERRED_IKE_PROTOCOL_AUTO = 0;
+ /**
+ * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_IPV4} and
+ * {@link IkeSessionParams.ESP_ENCAP_TYPE_UDP} for ESP packets.
+ *
+ * This is one of the possible customization values for
+ * CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT.
+ */
+ @VisibleForTesting
+ public static final int PREFERRED_IKE_PROTOCOL_IPV4_UDP = 40;
+ /**
+ * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_IPV6} and
+ * {@link IkeSessionParams.ESP_ENCAP_TYPE_UDP} for ESP packets.
+ *
+ * Do not use this value for production code. Its numeric value will change in future versions.
+ */
+ @VisibleForTesting
+ public static final int PREFERRED_IKE_PROTOCOL_IPV6_UDP = 60;
+ /**
+ * Prefer using {@link IkeSessionParams.ESP_IP_VERSION_IPV6} and
+ * {@link IkeSessionParams.ESP_ENCAP_TYPE_NONE} for ESP packets.
+ *
+ * This is one of the possible customization values for
+ * CarrierConfigManager.KEY_PREFERRED_IKE_PROTOCOL_INT.
+ */
+ @VisibleForTesting
+ public static final int PREFERRED_IKE_PROTOCOL_IPV6_ESP = 61;
+
// TODO: create separate trackers for each unique VPN to support
// automated reconnection
@@ -326,12 +363,13 @@
private final LocalLog mVpnManagerEvents = new LocalLog(MAX_EVENTS_LOGS);
/**
- * Cached Map of <subscription ID, keepalive delay ms> since retrieving the PersistableBundle
+ * Cached Map of <subscription ID, CarrierConfigInfo> since retrieving the PersistableBundle
* and the target value from CarrierConfigManager is somewhat expensive as it has hundreds of
* fields. This cache is cleared when the carrier config changes to ensure data freshness.
*/
@GuardedBy("this")
- private final SparseArray<Integer> mCachedKeepalivePerSubId = new SparseArray<>();
+ private final SparseArray<CarrierConfigInfo> mCachedCarrierConfigInfoPerSubId =
+ new SparseArray<>();
/**
* Whether to keep the connection active after rebooting, or upgrading or reinstalling. This
@@ -378,6 +416,28 @@
void checkInterruptAndDelay(boolean sleepLonger) throws InterruptedException;
}
+ private static class CarrierConfigInfo {
+ public final String mccMnc;
+ public final int keepaliveDelayMs;
+ public final int encapType;
+ public final int ipVersion;
+
+ CarrierConfigInfo(String mccMnc, int keepaliveDelayMs,
+ int encapType,
+ int ipVersion) {
+ this.mccMnc = mccMnc;
+ this.keepaliveDelayMs = keepaliveDelayMs;
+ this.encapType = encapType;
+ this.ipVersion = ipVersion;
+ }
+
+ @Override
+ public String toString() {
+ return "CarrierConfigInfo(" + mccMnc + ") [keepaliveDelayMs=" + keepaliveDelayMs
+ + ", encapType=" + encapType + ", ipVersion=" + ipVersion + "]";
+ }
+ }
+
@VisibleForTesting
public static class Dependencies {
public boolean isCallerSystem() {
@@ -2923,7 +2983,7 @@
public void onCarrierConfigChanged(int slotIndex, int subId, int carrierId,
int specificCarrierId) {
synchronized (Vpn.this) {
- mCachedKeepalivePerSubId.remove(subId);
+ mCachedCarrierConfigInfoPerSubId.remove(subId);
// Ignore stale runner.
if (mVpnRunner != Vpn.IkeV2VpnRunner.this) return;
@@ -3388,47 +3448,105 @@
}
private int guessEspIpVersionForNetwork() {
- // TODO : guess the IP version based on carrier if auto IP version selection is enabled
- return ESP_IP_VERSION_AUTO;
+ final CarrierConfigInfo carrierconfig = getCarrierConfig();
+ final int ipVersion = (carrierconfig != null)
+ ? carrierconfig.ipVersion : ESP_IP_VERSION_AUTO;
+ if (carrierconfig != null) {
+ Log.d(TAG, "Get customized IP version(" + ipVersion + ") on SIM("
+ + carrierconfig.mccMnc + ")");
+ }
+ return ipVersion;
}
private int guessEspEncapTypeForNetwork() {
- // TODO : guess the ESP encap type based on carrier if auto IP version selection is
- // enabled
- return ESP_ENCAP_TYPE_AUTO;
+ final CarrierConfigInfo carrierconfig = getCarrierConfig();
+ final int encapType = (carrierconfig != null)
+ ? carrierconfig.encapType : ESP_ENCAP_TYPE_AUTO;
+ if (carrierconfig != null) {
+ Log.d(TAG, "Get customized encap type(" + encapType + ") on SIM("
+ + carrierconfig.mccMnc + ")");
+ }
+ return encapType;
}
private int guessNattKeepaliveTimerForNetwork() {
+ final CarrierConfigInfo carrierconfig = getCarrierConfig();
+ final int natKeepalive = (carrierconfig != null)
+ ? carrierconfig.keepaliveDelayMs : AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
+ if (carrierconfig != null) {
+ Log.d(TAG, "Get customized keepalive(" + natKeepalive + ") on SIM("
+ + carrierconfig.mccMnc + ")");
+ }
+ return natKeepalive;
+ }
+
+ private CarrierConfigInfo getCarrierConfig() {
final int subId = getCellSubIdForNetworkCapabilities(mUnderlyingNetworkCapabilities);
if (subId == SubscriptionManager.INVALID_SUBSCRIPTION_ID) {
Log.d(TAG, "Underlying network is not a cellular network");
- return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
+ return null;
}
synchronized (Vpn.this) {
- if (mCachedKeepalivePerSubId.contains(subId)) {
- Log.d(TAG, "Get cached keepalive config");
- return mCachedKeepalivePerSubId.get(subId);
+ if (mCachedCarrierConfigInfoPerSubId.contains(subId)) {
+ Log.d(TAG, "Get cached config");
+ return mCachedCarrierConfigInfoPerSubId.get(subId);
}
-
- final TelephonyManager perSubTm = mTelephonyManager.createForSubscriptionId(subId);
- if (perSubTm.getSimApplicationState() != TelephonyManager.SIM_STATE_LOADED) {
- Log.d(TAG, "SIM card is not ready on sub " + subId);
- return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
- }
-
- final PersistableBundle carrierConfig =
- mCarrierConfigManager.getConfigForSubId(subId);
- if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
- return AUTOMATIC_KEEPALIVE_DELAY_SECONDS;
- }
-
- final int natKeepalive =
- carrierConfig.getInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT);
- mCachedKeepalivePerSubId.put(subId, natKeepalive);
- Log.d(TAG, "Get customized keepalive=" + natKeepalive);
- return natKeepalive;
}
+
+ final TelephonyManager perSubTm = mTelephonyManager.createForSubscriptionId(subId);
+ if (perSubTm.getSimApplicationState() != TelephonyManager.SIM_STATE_LOADED) {
+ Log.d(TAG, "SIM card is not ready on sub " + subId);
+ return null;
+ }
+
+ final PersistableBundle carrierConfig =
+ mCarrierConfigManager.getConfigForSubId(subId);
+ if (!CarrierConfigManager.isConfigForIdentifiedCarrier(carrierConfig)) {
+ return null;
+ }
+
+ final int natKeepalive =
+ carrierConfig.getInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT);
+ final int preferredIpPortocol =
+ carrierConfig.getInt(KEY_PREFERRED_IKE_PROTOCOL_INT);
+ final String mccMnc = perSubTm.getSimOperator(subId);
+ final CarrierConfigInfo info =
+ buildCarrierConfigInfo(mccMnc, natKeepalive, preferredIpPortocol);
+ synchronized (Vpn.this) {
+ mCachedCarrierConfigInfoPerSubId.put(subId, info);
+ }
+
+ return info;
+ }
+
+ private CarrierConfigInfo buildCarrierConfigInfo(String mccMnc,
+ int natKeepalive, int preferredIpPortocol) {
+ final int ipVersion;
+ final int encapType;
+ switch (preferredIpPortocol) {
+ case PREFERRED_IKE_PROTOCOL_AUTO:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_AUTO;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_AUTO;
+ break;
+ case PREFERRED_IKE_PROTOCOL_IPV4_UDP:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_IPV4;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_UDP;
+ break;
+ case PREFERRED_IKE_PROTOCOL_IPV6_UDP:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_IPV6;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_UDP;
+ break;
+ case PREFERRED_IKE_PROTOCOL_IPV6_ESP:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_IPV6;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_NONE;
+ break;
+ default:
+ ipVersion = IkeSessionParams.ESP_IP_VERSION_AUTO;
+ encapType = IkeSessionParams.ESP_ENCAP_TYPE_AUTO;
+ break;
+ }
+ return new CarrierConfigInfo(mccMnc, natKeepalive, encapType, ipVersion);
}
boolean maybeMigrateIkeSession(@NonNull Network underlyingNetwork) {
@@ -3440,10 +3558,22 @@
+ mCurrentToken
+ " to network "
+ underlyingNetwork);
- final int ipVersion = mProfile.isAutomaticIpVersionSelectionEnabled()
- ? guessEspIpVersionForNetwork() : ESP_IP_VERSION_AUTO;
- final int encapType = mProfile.isAutomaticIpVersionSelectionEnabled()
- ? guessEspEncapTypeForNetwork() : ESP_ENCAP_TYPE_AUTO;
+
+ final int ipVersion;
+ final int encapType;
+ if (mProfile.isAutomaticIpVersionSelectionEnabled()) {
+ ipVersion = guessEspIpVersionForNetwork();
+ encapType = guessEspEncapTypeForNetwork();
+ } else if (mProfile.getIkeTunnelConnectionParams() != null) {
+ ipVersion = mProfile.getIkeTunnelConnectionParams()
+ .getIkeSessionParams().getIpVersion();
+ encapType = mProfile.getIkeTunnelConnectionParams()
+ .getIkeSessionParams().getEncapType();
+ } else {
+ ipVersion = ESP_IP_VERSION_AUTO;
+ encapType = ESP_ENCAP_TYPE_AUTO;
+ }
+
final int keepaliveDelaySeconds;
if (mProfile.isAutomaticNattKeepaliveTimerEnabled()) {
keepaliveDelaySeconds = guessNattKeepaliveTimerForNetwork();
@@ -4884,7 +5014,7 @@
pw.println("Reset session scheduled");
}
}
- pw.println("mCachedKeepalivePerSubId=" + mCachedKeepalivePerSubId);
+ pw.println("mCachedCarrierConfigInfoPerSubId=" + mCachedCarrierConfigInfoPerSubId);
pw.println("mUnderlyNetworkChanges (most recent first):");
pw.increaseIndent();
diff --git a/services/core/java/com/android/server/content/ContentService.java b/services/core/java/com/android/server/content/ContentService.java
index 781920c..1b48e3c 100644
--- a/services/core/java/com/android/server/content/ContentService.java
+++ b/services/core/java/com/android/server/content/ContentService.java
@@ -1150,10 +1150,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.READ_SYNC_STATS)
@Override
public boolean isSyncActive(Account account, String authority, ComponentName cname) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
- "no permission to read the sync stats");
+ isSyncActive_enforcePermission();
final int callingUid = Binder.getCallingUid();
final int userId = UserHandle.getCallingUserId();
@@ -1254,11 +1254,11 @@
return isSyncPendingAsUser(account, authority, cname, UserHandle.getCallingUserId());
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.READ_SYNC_STATS)
@Override
public boolean isSyncPendingAsUser(Account account, String authority, ComponentName cname,
int userId) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.READ_SYNC_STATS,
- "no permission to read the sync stats");
+ isSyncPendingAsUser_enforcePermission();
enforceCrossUserPermission(userId,
"no permission to retrieve the sync settings for user " + userId);
diff --git a/services/core/java/com/android/server/cpu/CpuInfoReader.java b/services/core/java/com/android/server/cpu/CpuInfoReader.java
index ce68edbb..70d7bde 100644
--- a/services/core/java/com/android/server/cpu/CpuInfoReader.java
+++ b/services/core/java/com/android/server/cpu/CpuInfoReader.java
@@ -52,11 +52,6 @@
private static final String POLICY_DIR_PREFIX = "policy";
private static final String RELATED_CPUS_FILE = "related_cpus";
private static final String AFFECTED_CPUS_FILE = "affected_cpus";
- // TODO(b/263154344): Avoid reading from cpuinfo_cur_freq because non-root users don't have
- // read permission for this file. The file permissions are set by the Kernel. Instead, read
- // the current frequency only from scaling_cur_freq.
- private static final String CUR_CPUFREQ_FILE = "cpuinfo_cur_freq";
- private static final String MAX_CPUFREQ_FILE = "cpuinfo_max_freq";
private static final String CUR_SCALING_FREQ_FILE = "scaling_cur_freq";
private static final String MAX_SCALING_FREQ_FILE = "scaling_max_freq";
private static final String TIME_IN_STATE_FILE = "stats/time_in_state";
@@ -207,26 +202,16 @@
Slogf.w(TAG, "Missing dynamic policy info for policy ID %d", policyId);
continue;
}
- long curFreqKHz = CpuInfo.MISSING_FREQUENCY;
- long maxFreqKHz = CpuInfo.MISSING_FREQUENCY;
- if (dynamicPolicyInfo.curCpuFreqPair.cpuFreqKHz != CpuInfo.MISSING_FREQUENCY
- && staticPolicyInfo.maxCpuFreqPair.cpuFreqKHz != CpuInfo.MISSING_FREQUENCY) {
- curFreqKHz = dynamicPolicyInfo.curCpuFreqPair.cpuFreqKHz;
- maxFreqKHz = staticPolicyInfo.maxCpuFreqPair.cpuFreqKHz;
- } else if (dynamicPolicyInfo.curCpuFreqPair.scalingFreqKHz != CpuInfo.MISSING_FREQUENCY
- && staticPolicyInfo.maxCpuFreqPair.scalingFreqKHz
- != CpuInfo.MISSING_FREQUENCY) {
- curFreqKHz = dynamicPolicyInfo.curCpuFreqPair.scalingFreqKHz;
- maxFreqKHz = staticPolicyInfo.maxCpuFreqPair.scalingFreqKHz;
- } else {
+ if (dynamicPolicyInfo.curCpuFreqKHz == CpuInfo.MISSING_FREQUENCY
+ || staticPolicyInfo.maxCpuFreqKHz == CpuInfo.MISSING_FREQUENCY) {
Slogf.w(TAG, "Current and maximum CPU frequency information mismatch/missing for"
+ " policy ID %d", policyId);
continue;
}
- if (curFreqKHz > maxFreqKHz) {
+ if (dynamicPolicyInfo.curCpuFreqKHz > staticPolicyInfo.maxCpuFreqKHz) {
Slogf.w(TAG, "Current CPU frequency (%d) is greater than maximum CPU frequency"
- + " (%d) for policy ID (%d). Skipping CPU frequency policy", curFreqKHz,
- maxFreqKHz, policyId);
+ + " (%d) for policy ID (%d). Skipping CPU frequency policy",
+ dynamicPolicyInfo.curCpuFreqKHz, staticPolicyInfo.maxCpuFreqKHz, policyId);
continue;
}
for (int coreIdx = 0; coreIdx < staticPolicyInfo.relatedCpuCores.size(); coreIdx++) {
@@ -249,7 +234,7 @@
if (dynamicPolicyInfo.affectedCpuCores.indexOf(relatedCpuCore) < 0) {
cpuInfoByCpus.append(relatedCpuCore, new CpuInfo(relatedCpuCore,
cpusetCategories, /* isOnline= */false, CpuInfo.MISSING_FREQUENCY,
- maxFreqKHz, CpuInfo.MISSING_FREQUENCY, usageStats));
+ staticPolicyInfo.maxCpuFreqKHz, CpuInfo.MISSING_FREQUENCY, usageStats));
continue;
}
// If a CPU core is online, it must have the usage stats. When the usage stats is
@@ -260,8 +245,8 @@
continue;
}
CpuInfo cpuInfo = new CpuInfo(relatedCpuCore, cpusetCategories, /* isOnline= */true,
- curFreqKHz, maxFreqKHz, dynamicPolicyInfo.avgTimeInStateCpuFreqKHz,
- usageStats);
+ dynamicPolicyInfo.curCpuFreqKHz, staticPolicyInfo.maxCpuFreqKHz,
+ dynamicPolicyInfo.avgTimeInStateCpuFreqKHz, usageStats);
cpuInfoByCpus.append(relatedCpuCore, cpuInfo);
if (DEBUG) {
Slogf.d(TAG, "Added %s for CPU core %d", cpuInfo, relatedCpuCore);
@@ -438,8 +423,8 @@
for (int i = 0; i < mCpuFreqPolicyDirsById.size(); i++) {
int policyId = mCpuFreqPolicyDirsById.keyAt(i);
File policyDir = mCpuFreqPolicyDirsById.valueAt(i);
- FrequencyPair maxCpuFreqPair = readMaxCpuFrequency(policyDir);
- if (maxCpuFreqPair.isEmpty()) {
+ long maxCpuFreqKHz = readCpuFreqKHz(new File(policyDir, MAX_SCALING_FREQ_FILE));
+ if (maxCpuFreqKHz == CpuInfo.MISSING_FREQUENCY) {
Slogf.w(TAG, "Missing max CPU frequency information at %s",
policyDir.getAbsolutePath());
continue;
@@ -451,7 +436,7 @@
cpuCoresFile.getAbsolutePath());
continue;
}
- StaticPolicyInfo staticPolicyInfo = new StaticPolicyInfo(maxCpuFreqPair,
+ StaticPolicyInfo staticPolicyInfo = new StaticPolicyInfo(maxCpuFreqKHz,
relatedCpuCores);
mStaticPolicyInfoById.append(policyId, staticPolicyInfo);
if (DEBUG) {
@@ -461,18 +446,13 @@
}
}
- private FrequencyPair readMaxCpuFrequency(File policyDir) {
- return new FrequencyPair(readCpuFreqKHz(new File(policyDir, MAX_CPUFREQ_FILE)),
- readCpuFreqKHz(new File(policyDir, MAX_SCALING_FREQ_FILE)));
- }
-
private SparseArray<DynamicPolicyInfo> readDynamicPolicyInfo() {
SparseArray<DynamicPolicyInfo> dynamicPolicyInfoById = new SparseArray<>();
for (int i = 0; i < mCpuFreqPolicyDirsById.size(); i++) {
int policyId = mCpuFreqPolicyDirsById.keyAt(i);
File policyDir = mCpuFreqPolicyDirsById.valueAt(i);
- FrequencyPair curCpuFreqPair = readCurrentCpuFrequency(policyDir);
- if (curCpuFreqPair.isEmpty()) {
+ long curCpuFreqKHz = readCpuFreqKHz(new File(policyDir, CUR_SCALING_FREQ_FILE));
+ if (curCpuFreqKHz == CpuInfo.MISSING_FREQUENCY) {
Slogf.w(TAG, "Missing current frequency information at %s",
policyDir.getAbsolutePath());
continue;
@@ -484,7 +464,7 @@
Slogf.e(TAG, "Failed to read CPU cores from %s", cpuCoresFile.getAbsolutePath());
continue;
}
- DynamicPolicyInfo dynamicPolicyInfo = new DynamicPolicyInfo(curCpuFreqPair,
+ DynamicPolicyInfo dynamicPolicyInfo = new DynamicPolicyInfo(curCpuFreqKHz,
avgTimeInStateCpuFreqKHz, affectedCpuCores);
dynamicPolicyInfoById.append(policyId, dynamicPolicyInfo);
if (DEBUG) {
@@ -495,11 +475,6 @@
return dynamicPolicyInfoById;
}
- private FrequencyPair readCurrentCpuFrequency(File policyDir) {
- return new FrequencyPair(readCpuFreqKHz(new File(policyDir, CUR_CPUFREQ_FILE)),
- readCpuFreqKHz(new File(policyDir, CUR_SCALING_FREQ_FILE)));
- }
-
private long readAvgTimeInStateCpuFrequency(int policyId, File policyDir) {
LongSparseLongArray latestTimeInState = readTimeInState(policyDir);
if (latestTimeInState == null || latestTimeInState.size() == 0) {
@@ -913,58 +888,37 @@
}
}
- private static final class FrequencyPair {
- public final long cpuFreqKHz;
- public final long scalingFreqKHz;
-
- FrequencyPair(long cpuFreqKHz, long scalingFreqKHz) {
- this.cpuFreqKHz = cpuFreqKHz;
- this.scalingFreqKHz = scalingFreqKHz;
- }
-
- boolean isEmpty() {
- return cpuFreqKHz == CpuInfo.MISSING_FREQUENCY
- && scalingFreqKHz == CpuInfo.MISSING_FREQUENCY;
- }
-
- @Override
- public String toString() {
- return "FrequencyPair{cpuFreqKHz = " + cpuFreqKHz + ", scalingFreqKHz = "
- + scalingFreqKHz + '}';
- }
- }
-
private static final class StaticPolicyInfo {
- public final FrequencyPair maxCpuFreqPair;
+ public final long maxCpuFreqKHz;
public final IntArray relatedCpuCores;
- StaticPolicyInfo(FrequencyPair maxCpuFreqPair, IntArray relatedCpuCores) {
- this.maxCpuFreqPair = maxCpuFreqPair;
+ StaticPolicyInfo(long maxCpuFreqKHz, IntArray relatedCpuCores) {
+ this.maxCpuFreqKHz = maxCpuFreqKHz;
this.relatedCpuCores = relatedCpuCores;
}
@Override
public String toString() {
- return "StaticPolicyInfo{maxCpuFreqPair = " + maxCpuFreqPair + ", relatedCpuCores = "
+ return "StaticPolicyInfo{maxCpuFreqKHz = " + maxCpuFreqKHz + ", relatedCpuCores = "
+ relatedCpuCores + '}';
}
}
private static final class DynamicPolicyInfo {
- public final FrequencyPair curCpuFreqPair;
+ public final long curCpuFreqKHz;
public final long avgTimeInStateCpuFreqKHz;
public final IntArray affectedCpuCores;
- DynamicPolicyInfo(FrequencyPair curCpuFreqPair, long avgTimeInStateCpuFreqKHz,
+ DynamicPolicyInfo(long curCpuFreqKHz, long avgTimeInStateCpuFreqKHz,
IntArray affectedCpuCores) {
- this.curCpuFreqPair = curCpuFreqPair;
+ this.curCpuFreqKHz = curCpuFreqKHz;
this.avgTimeInStateCpuFreqKHz = avgTimeInStateCpuFreqKHz;
this.affectedCpuCores = affectedCpuCores;
}
@Override
public String toString() {
- return "DynamicPolicyInfo{curCpuFreqPair = " + curCpuFreqPair
+ return "DynamicPolicyInfo{curCpuFreqKHz = " + curCpuFreqKHz
+ ", avgTimeInStateCpuFreqKHz = " + avgTimeInStateCpuFreqKHz
+ ", affectedCpuCores = " + affectedCpuCores + '}';
}
diff --git a/services/core/java/com/android/server/devicestate/DeviceState.java b/services/core/java/com/android/server/devicestate/DeviceState.java
index a589313..00af224 100644
--- a/services/core/java/com/android/server/devicestate/DeviceState.java
+++ b/services/core/java/com/android/server/devicestate/DeviceState.java
@@ -76,7 +76,13 @@
* This flag indicates that the corresponding state should be disabled when the device is
* overheating and reaching the critical status.
*/
- public static final int FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL = 1 << 4;
+ public static final int FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL = 1 << 4;
+
+ /**
+ * This flag indicates that the corresponding state should be disabled when power save mode
+ * is enabled.
+ */
+ public static final int FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE = 1 << 5;
/** @hide */
@IntDef(prefix = {"FLAG_"}, flag = true, value = {
@@ -84,7 +90,8 @@
FLAG_APP_INACCESSIBLE,
FLAG_EMULATED_ONLY,
FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP,
- FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL
+ FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL,
+ FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE
})
@Retention(RetentionPolicy.SOURCE)
public @interface DeviceStateFlags {}
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
index 43ee5e2..8f9a1fd 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateManagerService.java
@@ -25,6 +25,7 @@
import static com.android.server.devicestate.DeviceState.FLAG_CANCEL_OVERRIDE_REQUESTS;
import static com.android.server.devicestate.OverrideRequest.OVERRIDE_REQUEST_TYPE_BASE_STATE;
import static com.android.server.devicestate.OverrideRequest.OVERRIDE_REQUEST_TYPE_EMULATED_STATE;
+import static com.android.server.devicestate.OverrideRequestController.FLAG_POWER_SAVE_ENABLED;
import static com.android.server.devicestate.OverrideRequestController.FLAG_THERMAL_CRITICAL;
import static com.android.server.devicestate.OverrideRequestController.STATUS_ACTIVE;
import static com.android.server.devicestate.OverrideRequestController.STATUS_CANCELED;
@@ -609,7 +610,8 @@
@GuardedBy("mLock")
private void onOverrideRequestStatusChangedLocked(@NonNull OverrideRequest request,
- @OverrideRequestController.RequestStatus int status, int flags) {
+ @OverrideRequestController.RequestStatus int status,
+ @OverrideRequestController.StatusChangedFlag int flags) {
if (request.getRequestType() == OVERRIDE_REQUEST_TYPE_BASE_STATE) {
switch (status) {
case STATUS_ACTIVE:
@@ -641,6 +643,10 @@
mDeviceStateNotificationController
.showThermalCriticalNotificationIfNeeded(
request.getRequestedState());
+ } else if ((flags & FLAG_POWER_SAVE_ENABLED) == FLAG_POWER_SAVE_ENABLED) {
+ mDeviceStateNotificationController
+ .showPowerSaveNotificationIfNeeded(
+ request.getRequestedState());
}
}
break;
@@ -1179,12 +1185,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DEVICE_STATE)
@Override // Binder call
public void onStateRequestOverlayDismissed(boolean shouldCancelRequest) {
- getContext().enforceCallingOrSelfPermission(CONTROL_DEVICE_STATE,
- "CONTROL_DEVICE_STATE permission required to control the state request "
- + "overlay");
+ onStateRequestOverlayDismissed_enforcePermission();
final long callingIdentity = Binder.clearCallingIdentity();
try {
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java
index 9008740..ab261ac 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateNotificationController.java
@@ -16,6 +16,8 @@
package com.android.server.devicestate;
+import static android.provider.Settings.ACTION_BATTERY_SAVER_SETTINGS;
+
import android.annotation.DrawableRes;
import android.annotation.NonNull;
import android.annotation.Nullable;
@@ -101,10 +103,16 @@
}
String requesterApplicationLabel = getApplicationLabel(requestingAppUid);
if (requesterApplicationLabel != null) {
+ final Intent intent = new Intent(INTENT_ACTION_CANCEL_STATE)
+ .setPackage(mContext.getPackageName());
+ final PendingIntent pendingIntent = PendingIntent.getBroadcast(
+ mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE);
showNotification(
info.name, info.activeNotificationTitle,
String.format(info.activeNotificationContent, requesterApplicationLabel),
- true /* ongoing */, R.drawable.ic_dual_screen
+ true /* ongoing */, R.drawable.ic_dual_screen,
+ pendingIntent,
+ mContext.getString(R.string.device_state_notification_turn_off_button)
);
} else {
Slog.e(TAG, "Cannot determine the requesting app name when showing state active "
@@ -126,7 +134,33 @@
showNotification(
info.name, info.thermalCriticalNotificationTitle,
info.thermalCriticalNotificationContent, false /* ongoing */,
- R.drawable.ic_thermostat
+ R.drawable.ic_thermostat,
+ null /* pendingIntent */,
+ null /* actionText */
+ );
+ }
+
+ /**
+ * Displays the notification indicating that the device state is canceled due to power
+ * save mode being enabled. Does nothing if the state does not have a power save mode
+ * notification.
+ *
+ * @param state the identifier of the device state being canceled.
+ */
+ void showPowerSaveNotificationIfNeeded(int state) {
+ NotificationInfo info = mNotificationInfos.get(state);
+ if (info == null || !info.hasPowerSaveModeNotification()) {
+ return;
+ }
+ final Intent intent = new Intent(ACTION_BATTERY_SAVER_SETTINGS);
+ final PendingIntent pendingIntent = PendingIntent.getActivity(
+ mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE);
+ showNotification(
+ info.name, info.powerSaveModeNotificationTitle,
+ info.powerSaveModeNotificationContent, false /* ongoing */,
+ R.drawable.ic_thermostat,
+ pendingIntent,
+ mContext.getString(R.string.device_state_notification_settings_button)
);
}
@@ -161,7 +195,8 @@
*/
private void showNotification(
@NonNull String name, @NonNull String title, @NonNull String content, boolean ongoing,
- @DrawableRes int iconRes) {
+ @DrawableRes int iconRes,
+ @Nullable PendingIntent pendingIntent, @Nullable String actionText) {
final NotificationChannel channel = new NotificationChannel(
CHANNEL_ID, name, NotificationManager.IMPORTANCE_HIGH);
final Notification.Builder builder = new Notification.Builder(mContext, CHANNEL_ID)
@@ -173,14 +208,10 @@
.setOngoing(ongoing)
.setCategory(Notification.CATEGORY_SYSTEM);
- if (ongoing) {
- final Intent intent = new Intent(INTENT_ACTION_CANCEL_STATE)
- .setPackage(mContext.getPackageName());
- final PendingIntent pendingIntent = PendingIntent.getBroadcast(
- mContext, 0 /* requestCode */, intent, PendingIntent.FLAG_IMMUTABLE);
+ if (pendingIntent != null && actionText != null) {
final Notification.Action action = new Notification.Action.Builder(
null /* icon */,
- mContext.getString(R.string.device_state_notification_turn_off_button),
+ actionText,
pendingIntent)
.build();
builder.addAction(action);
@@ -215,12 +246,21 @@
final String[] thermalCriticalNotificationContents =
context.getResources().getStringArray(
R.array.device_state_notification_thermal_contents);
+ final String[] powerSaveModeNotificationTitles =
+ context.getResources().getStringArray(
+ R.array.device_state_notification_power_save_titles);
+ final String[] powerSaveModeNotificationContents =
+ context.getResources().getStringArray(
+ R.array.device_state_notification_power_save_contents);
+
if (stateIdentifiers.length != names.length
|| stateIdentifiers.length != activeNotificationTitles.length
|| stateIdentifiers.length != activeNotificationContents.length
|| stateIdentifiers.length != thermalCriticalNotificationTitles.length
|| stateIdentifiers.length != thermalCriticalNotificationContents.length
+ || stateIdentifiers.length != powerSaveModeNotificationTitles.length
+ || stateIdentifiers.length != powerSaveModeNotificationContents.length
) {
throw new IllegalStateException(
"The length of state identifiers and notification texts must match!");
@@ -237,7 +277,9 @@
new NotificationInfo(
names[i], activeNotificationTitles[i], activeNotificationContents[i],
thermalCriticalNotificationTitles[i],
- thermalCriticalNotificationContents[i])
+ thermalCriticalNotificationContents[i],
+ powerSaveModeNotificationTitles[i],
+ powerSaveModeNotificationContents[i])
);
}
@@ -272,16 +314,21 @@
public final String activeNotificationContent;
public final String thermalCriticalNotificationTitle;
public final String thermalCriticalNotificationContent;
+ public final String powerSaveModeNotificationTitle;
+ public final String powerSaveModeNotificationContent;
NotificationInfo(String name, String activeNotificationTitle,
String activeNotificationContent, String thermalCriticalNotificationTitle,
- String thermalCriticalNotificationContent) {
+ String thermalCriticalNotificationContent, String powerSaveModeNotificationTitle,
+ String powerSaveModeNotificationContent) {
this.name = name;
this.activeNotificationTitle = activeNotificationTitle;
this.activeNotificationContent = activeNotificationContent;
this.thermalCriticalNotificationTitle = thermalCriticalNotificationTitle;
this.thermalCriticalNotificationContent = thermalCriticalNotificationContent;
+ this.powerSaveModeNotificationTitle = powerSaveModeNotificationTitle;
+ this.powerSaveModeNotificationContent = powerSaveModeNotificationContent;
}
boolean hasActiveNotification() {
@@ -292,5 +339,10 @@
return thermalCriticalNotificationTitle != null
&& thermalCriticalNotificationTitle.length() > 0;
}
+
+ boolean hasPowerSaveModeNotification() {
+ return powerSaveModeNotificationTitle != null
+ && powerSaveModeNotificationTitle.length() > 0;
+ }
}
}
diff --git a/services/core/java/com/android/server/devicestate/DeviceStateProvider.java b/services/core/java/com/android/server/devicestate/DeviceStateProvider.java
index fecc13f..af33de0 100644
--- a/services/core/java/com/android/server/devicestate/DeviceStateProvider.java
+++ b/services/core/java/com/android/server/devicestate/DeviceStateProvider.java
@@ -52,11 +52,24 @@
*/
int SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_CRITICAL = 3;
+ /**
+ * Indicating that the supported device states have changed because power save mode was enabled.
+ */
+ int SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_ENABLED = 4;
+
+ /**
+ * Indicating that the supported device states have changed because power save mode was
+ * disabled.
+ */
+ int SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_DISABLED = 5;
+
@IntDef(prefix = { "SUPPORTED_DEVICE_STATES_CHANGED_" }, value = {
SUPPORTED_DEVICE_STATES_CHANGED_DEFAULT,
SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED,
SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_NORMAL,
- SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_CRITICAL
+ SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_CRITICAL,
+ SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_ENABLED,
+ SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_DISABLED
})
@Retention(RetentionPolicy.SOURCE)
@interface SupportedStatesUpdatedReason {}
diff --git a/services/core/java/com/android/server/devicestate/OverrideRequestController.java b/services/core/java/com/android/server/devicestate/OverrideRequestController.java
index 2ed4765..46f0bc0 100644
--- a/services/core/java/com/android/server/devicestate/OverrideRequestController.java
+++ b/services/core/java/com/android/server/devicestate/OverrideRequestController.java
@@ -64,6 +64,18 @@
*/
static final int FLAG_THERMAL_CRITICAL = 1 << 0;
+ /**
+ * A flag indicating that the status change was triggered by power save mode.
+ */
+ static final int FLAG_POWER_SAVE_ENABLED = 1 << 1;
+
+ @IntDef(flag = true, prefix = {"FLAG_"}, value = {
+ FLAG_THERMAL_CRITICAL,
+ FLAG_POWER_SAVE_ENABLED
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface StatusChangedFlag {}
+
static String statusToString(@RequestStatus int status) {
switch (status) {
case STATUS_ACTIVE:
@@ -228,13 +240,18 @@
@DeviceStateProvider.SupportedStatesUpdatedReason int reason) {
boolean isThermalCritical =
reason == DeviceStateProvider.SUPPORTED_DEVICE_STATES_CHANGED_THERMAL_CRITICAL;
+ boolean isPowerSaveEnabled =
+ reason == DeviceStateProvider.SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_ENABLED;
+ @StatusChangedFlag int flags = 0;
+ flags |= isThermalCritical ? FLAG_THERMAL_CRITICAL : 0;
+ flags |= isPowerSaveEnabled ? FLAG_POWER_SAVE_ENABLED : 0;
if (mBaseStateRequest != null && !contains(newSupportedStates,
mBaseStateRequest.getRequestedState())) {
- cancelCurrentBaseStateRequestLocked(isThermalCritical ? FLAG_THERMAL_CRITICAL : 0);
+ cancelCurrentBaseStateRequestLocked(flags);
}
if (mRequest != null && !contains(newSupportedStates, mRequest.getRequestedState())) {
- cancelCurrentRequestLocked(isThermalCritical ? FLAG_THERMAL_CRITICAL : 0);
+ cancelCurrentRequestLocked(flags);
}
}
@@ -255,7 +272,8 @@
cancelRequestLocked(requestToCancel, 0 /* flags */);
}
- private void cancelRequestLocked(@NonNull OverrideRequest requestToCancel, int flags) {
+ private void cancelRequestLocked(@NonNull OverrideRequest requestToCancel,
+ @StatusChangedFlag int flags) {
mListener.onStatusChanged(requestToCancel, STATUS_CANCELED, flags);
}
@@ -267,7 +285,7 @@
cancelCurrentRequestLocked(0 /* flags */);
}
- private void cancelCurrentRequestLocked(int flags) {
+ private void cancelCurrentRequestLocked(@StatusChangedFlag int flags) {
if (mRequest == null) {
Slog.w(TAG, "Attempted to cancel a null OverrideRequest");
return;
@@ -285,7 +303,7 @@
cancelCurrentBaseStateRequestLocked(0 /* flags */);
}
- private void cancelCurrentBaseStateRequestLocked(int flags) {
+ private void cancelCurrentBaseStateRequestLocked(@StatusChangedFlag int flags) {
if (mBaseStateRequest == null) {
Slog.w(TAG, "Attempted to cancel a null OverrideRequest");
return;
@@ -312,6 +330,6 @@
* cancelled request.
*/
void onStatusChanged(@NonNull OverrideRequest request, @RequestStatus int newStatus,
- int flags);
+ @StatusChangedFlag int flags);
}
}
diff --git a/services/core/java/com/android/server/display/DisplayManagerService.java b/services/core/java/com/android/server/display/DisplayManagerService.java
index ea157c8..26e1eb6 100644
--- a/services/core/java/com/android/server/display/DisplayManagerService.java
+++ b/services/core/java/com/android/server/display/DisplayManagerService.java
@@ -1514,14 +1514,17 @@
}
}
- // When calling setContentRecordingSession into the WindowManagerService, the WMS
+ // When calling WindowManagerService#setContentRecordingSession, WindowManagerService
// attempts to acquire a lock before executing its main body. Due to this, we need
// to be sure that it isn't called while the DisplayManagerService is also holding
// a lock, to avoid a deadlock scenario.
final ContentRecordingSession session =
virtualDisplayConfig.getContentRecordingSession();
-
- if (displayId != Display.INVALID_DISPLAY && session != null) {
+ // Ensure session details are only set when mirroring (through VirtualDisplay flags or
+ // MediaProjection).
+ final boolean shouldMirror =
+ projection != null || (flags & VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR) != 0;
+ if (shouldMirror && displayId != Display.INVALID_DISPLAY && session != null) {
// Only attempt to set content recording session if there are details to set and a
// VirtualDisplay has been successfully constructed.
session.setDisplayId(displayId);
@@ -1529,8 +1532,8 @@
// We set the content recording session here on the server side instead of using
// a second AIDL call in MediaProjection. By ensuring that a virtual display has
// been constructed before calling setContentRecordingSession, we avoid a race
- // condition between the DMS & WMS which could lead to the MediaProjection
- // being pre-emptively torn down.
+ // condition between the DisplayManagerService & WindowManagerService which could
+ // lead to the MediaProjection being pre-emptively torn down.
if (!mWindowManagerInternal.setContentRecordingSession(session)) {
// Unable to start mirroring, so tear down projection & release VirtualDisplay.
try {
@@ -3417,10 +3420,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
@Override // Binder call
public void startWifiDisplayScan() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to start wifi display scans");
+ startWifiDisplayScan_enforcePermission();
final int callingPid = Binder.getCallingPid();
final long token = Binder.clearCallingIdentity();
@@ -3431,10 +3434,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
@Override // Binder call
public void stopWifiDisplayScan() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to stop wifi display scans");
+ stopWifiDisplayScan_enforcePermission();
final int callingPid = Binder.getCallingPid();
final long token = Binder.clearCallingIdentity();
@@ -3508,10 +3511,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
@Override // Binder call
public void pauseWifiDisplay() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to pause a wifi display session");
+ pauseWifiDisplay_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
@@ -3521,10 +3524,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONFIGURE_WIFI_DISPLAY)
@Override // Binder call
public void resumeWifiDisplay() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.CONFIGURE_WIFI_DISPLAY,
- "Permission required to resume a wifi display session");
+ resumeWifiDisplay_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
@@ -3547,11 +3550,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@Override // Binder call
public void setUserDisabledHdrTypes(int[] userDisabledFormats) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.WRITE_SECURE_SETTINGS,
- "Permission required to write the user settings.");
+ setUserDisabledHdrTypes_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
@@ -3574,11 +3576,10 @@
DisplayControl.overrideHdrTypes(displayToken, modes);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@Override // Binder call
public void setAreUserDisabledHdrTypesAllowed(boolean areUserDisabledHdrTypesAllowed) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.WRITE_SECURE_SETTINGS,
- "Permission required to write the user settings.");
+ setAreUserDisabledHdrTypesAllowed_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
setAreUserDisabledHdrTypesAllowedInternal(areUserDisabledHdrTypesAllowed);
@@ -3601,11 +3602,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE)
@Override // Binder call
public void requestColorMode(int displayId, int colorMode) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.CONFIGURE_DISPLAY_COLOR_MODE,
- "Permission required to change the display color mode");
+ requestColorMode_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
requestColorModeInternal(displayId, colorMode);
@@ -3682,11 +3682,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.BRIGHTNESS_SLIDER_USAGE)
@Override // Binder call
public ParceledListSlice<BrightnessChangeEvent> getBrightnessEvents(String callingPackage) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.BRIGHTNESS_SLIDER_USAGE,
- "Permission to read brightness events.");
+ getBrightnessEvents_enforcePermission();
final int callingUid = Binder.getCallingUid();
AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
@@ -3715,11 +3714,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS)
@Override // Binder call
public ParceledListSlice<AmbientBrightnessDayStats> getAmbientBrightnessStats() {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.ACCESS_AMBIENT_LIGHT_STATS,
- "Permission required to to access ambient light stats.");
+ getAmbientBrightnessStats_enforcePermission();
final int callingUid = Binder.getCallingUid();
final int userId = UserHandle.getUserId(callingUid);
final long token = Binder.clearCallingIdentity();
@@ -3733,12 +3731,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
@Override // Binder call
public void setBrightnessConfigurationForUser(
BrightnessConfiguration c, @UserIdInt int userId, String packageName) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
- "Permission required to change the display's brightness configuration");
+ setBrightnessConfigurationForUser_enforcePermission();
if (userId != UserHandle.getCallingUserId()) {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS,
@@ -3763,12 +3760,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
@Override // Binder call
public void setBrightnessConfigurationForDisplay(BrightnessConfiguration c,
String uniqueId, int userId, String packageName) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
- "Permission required to change the display's brightness configuration");
+ setBrightnessConfigurationForDisplay_enforcePermission();
if (userId != UserHandle.getCallingUserId()) {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS,
@@ -3783,12 +3779,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
@Override // Binder call
public BrightnessConfiguration getBrightnessConfigurationForDisplay(String uniqueId,
int userId) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
- "Permission required to read the display's brightness configuration");
+ getBrightnessConfigurationForDisplay_enforcePermission();
if (userId != UserHandle.getCallingUserId()) {
mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS,
@@ -3832,11 +3827,10 @@
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS)
@Override // Binder call
public BrightnessConfiguration getDefaultBrightnessConfiguration() {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.CONFIGURE_DISPLAY_BRIGHTNESS,
- "Permission required to read the display's default brightness configuration");
+ getDefaultBrightnessConfiguration_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
synchronized (mSyncRoot) {
@@ -3848,11 +3842,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
@Override
public BrightnessInfo getBrightnessInfo(int displayId) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
- "Permission required to read the display's brightness info.");
+ getBrightnessInfo_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
synchronized (mSyncRoot) {
@@ -3880,11 +3873,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
@Override // Binder call
public void setTemporaryBrightness(int displayId, float brightness) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
- "Permission required to set the display's brightness");
+ setTemporaryBrightness_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
synchronized (mSyncRoot) {
@@ -3896,11 +3888,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
@Override // Binder call
public void setBrightness(int displayId, float brightness) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
- "Permission required to set the display's brightness");
+ setBrightness_enforcePermission();
if (!isValidBrightness(brightness)) {
Slog.w(TAG, "Attempted to set invalid brightness" + brightness);
return;
@@ -3939,11 +3930,10 @@
return brightness;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS)
@Override // Binder call
public void setTemporaryAutoBrightnessAdjustment(float adjustment) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_BRIGHTNESS,
- "Permission required to set the display's auto brightness adjustment");
+ setTemporaryAutoBrightnessAdjustment_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
synchronized (mSyncRoot) {
@@ -3983,11 +3973,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE)
@Override // Binder call
public void setUserPreferredDisplayMode(int displayId, Display.Mode mode) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.MODIFY_USER_PREFERRED_DISPLAY_MODE,
- "Permission required to set the user preferred display mode.");
+ setUserPreferredDisplayMode_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
setUserPreferredDisplayModeInternal(displayId, mode);
@@ -4072,11 +4061,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS)
@Override // Binder call
public void setShouldAlwaysRespectAppRequestedMode(boolean enabled) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS,
- "Permission required to override display mode requests.");
+ setShouldAlwaysRespectAppRequestedMode_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
setShouldAlwaysRespectAppRequestedModeInternal(enabled);
@@ -4085,11 +4073,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS)
@Override // Binder call
public boolean shouldAlwaysRespectAppRequestedMode() {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.OVERRIDE_DISPLAY_MODE_REQUESTS,
- "Permission required to override display mode requests.");
+ shouldAlwaysRespectAppRequestedMode_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
return shouldAlwaysRespectAppRequestedModeInternal();
@@ -4098,11 +4085,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE)
@Override // Binder call
public void setRefreshRateSwitchingType(int newValue) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.MODIFY_REFRESH_RATE_SWITCHING_TYPE,
- "Permission required to modify refresh rate switching type.");
+ setRefreshRateSwitchingType_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
setRefreshRateSwitchingTypeInternal(newValue);
diff --git a/services/core/java/com/android/server/display/color/ColorDisplayService.java b/services/core/java/com/android/server/display/color/ColorDisplayService.java
index 0284d9c..a1a10eb 100644
--- a/services/core/java/com/android/server/display/color/ColorDisplayService.java
+++ b/services/core/java/com/android/server/display/color/ColorDisplayService.java
@@ -1621,11 +1621,10 @@
@VisibleForTesting
final class BinderService extends IColorDisplayManager.Stub {
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public void setColorMode(int colorMode) {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set display color mode");
+ setColorMode_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
setColorModeInternal(colorMode);
@@ -1715,11 +1714,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean setNightDisplayActivated(boolean activated) {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set night display activated");
+ setNightDisplayActivated_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
mNightDisplayTintController.setActivated(activated);
@@ -1739,11 +1737,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean setNightDisplayColorTemperature(int temperature) {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set night display temperature");
+ setNightDisplayColorTemperature_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
return mNightDisplayTintController.setColorTemperature(temperature);
@@ -1762,11 +1759,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean setNightDisplayAutoMode(int autoMode) {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set night display auto mode");
+ setNightDisplayAutoMode_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
return setNightDisplayAutoModeInternal(autoMode);
@@ -1775,11 +1771,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public int getNightDisplayAutoMode() {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to get night display auto mode");
+ getNightDisplayAutoMode_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
return getNightDisplayAutoModeInternal();
@@ -1798,11 +1793,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean setNightDisplayCustomStartTime(Time startTime) {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set night display custom start time");
+ setNightDisplayCustomStartTime_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
return setNightDisplayCustomStartTimeInternal(startTime);
@@ -1821,11 +1815,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean setNightDisplayCustomEndTime(Time endTime) {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set night display custom end time");
+ setNightDisplayCustomEndTime_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
return setNightDisplayCustomEndTimeInternal(endTime);
@@ -1844,11 +1837,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean setDisplayWhiteBalanceEnabled(boolean enabled) {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set night display activated");
+ setDisplayWhiteBalanceEnabled_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
return setDisplayWhiteBalanceSettingEnabled(enabled);
@@ -1877,11 +1869,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean setReduceBrightColorsActivated(boolean activated) {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set reduce bright colors activation state");
+ setReduceBrightColorsActivated_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
return setReduceBrightColorsActivatedInternal(activated);
@@ -1910,11 +1901,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS)
@Override
public boolean setReduceBrightColorsStrength(int strength) {
- getContext().enforceCallingOrSelfPermission(
- Manifest.permission.CONTROL_DISPLAY_COLOR_TRANSFORMS,
- "Permission required to set reduce bright colors strength");
+ setReduceBrightColorsStrength_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
return setReduceBrightColorsStrengthInternal(strength);
diff --git a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
index 3864200..13e29a3 100644
--- a/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
+++ b/services/core/java/com/android/server/display/mode/DisplayModeDirector.java
@@ -1444,13 +1444,12 @@
}
public void onDeviceConfigDefaultPeakRefreshRateChanged(Float defaultPeakRefreshRate) {
- if (defaultPeakRefreshRate == null) {
- defaultPeakRefreshRate = (float) mContext.getResources().getInteger(
- R.integer.config_defaultPeakRefreshRate);
- }
-
- if (mDefaultPeakRefreshRate != defaultPeakRefreshRate) {
- synchronized (mLock) {
+ synchronized (mLock) {
+ if (defaultPeakRefreshRate == null) {
+ setDefaultPeakRefreshRate(mDefaultDisplayDeviceConfig,
+ /* attemptLoadingFromDeviceConfig= */ false);
+ updateRefreshRateSettingLocked();
+ } else if (mDefaultPeakRefreshRate != defaultPeakRefreshRate) {
mDefaultPeakRefreshRate = defaultPeakRefreshRate;
updateRefreshRateSettingLocked();
}
@@ -2115,11 +2114,20 @@
mLowDisplayBrightnessThresholds = displayThresholds;
mLowAmbientBrightnessThresholds = ambientThresholds;
} else {
- // Invalid or empty. Use device default.
- mLowDisplayBrightnessThresholds = mContext.getResources().getIntArray(
- R.array.config_brightnessThresholdsOfPeakRefreshRate);
- mLowAmbientBrightnessThresholds = mContext.getResources().getIntArray(
- R.array.config_ambientThresholdsOfPeakRefreshRate);
+ DisplayDeviceConfig displayDeviceConfig;
+ synchronized (mLock) {
+ displayDeviceConfig = mDefaultDisplayDeviceConfig;
+ }
+ mLowDisplayBrightnessThresholds = loadBrightnessThresholds(
+ () -> mDeviceConfigDisplaySettings.getLowDisplayBrightnessThresholds(),
+ () -> displayDeviceConfig.getLowDisplayBrightnessThresholds(),
+ R.array.config_brightnessThresholdsOfPeakRefreshRate,
+ displayDeviceConfig, /* attemptLoadingFromDeviceConfig= */ false);
+ mLowAmbientBrightnessThresholds = loadBrightnessThresholds(
+ () -> mDeviceConfigDisplaySettings.getLowAmbientBrightnessThresholds(),
+ () -> displayDeviceConfig.getLowAmbientBrightnessThresholds(),
+ R.array.config_ambientThresholdsOfPeakRefreshRate,
+ displayDeviceConfig, /* attemptLoadingFromDeviceConfig= */ false);
}
restartObserver();
}
@@ -2129,7 +2137,15 @@
* DeviceConfig properties.
*/
public void onDeviceConfigRefreshRateInLowZoneChanged(int refreshRate) {
- if (refreshRate != mRefreshRateInLowZone) {
+ if (refreshRate == -1) {
+ // Given there is no value available in DeviceConfig, lets not attempt loading it
+ // from there.
+ synchronized (mLock) {
+ loadRefreshRateInLowZone(mDefaultDisplayDeviceConfig,
+ /* attemptLoadingFromDeviceConfig= */ false);
+ }
+ restartObserver();
+ } else if (refreshRate != mRefreshRateInLowZone) {
mRefreshRateInLowZone = refreshRate;
restartObserver();
}
@@ -2142,11 +2158,20 @@
mHighDisplayBrightnessThresholds = displayThresholds;
mHighAmbientBrightnessThresholds = ambientThresholds;
} else {
- // Invalid or empty. Use device default.
- mHighDisplayBrightnessThresholds = mContext.getResources().getIntArray(
- R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate);
- mHighAmbientBrightnessThresholds = mContext.getResources().getIntArray(
- R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate);
+ DisplayDeviceConfig displayDeviceConfig;
+ synchronized (mLock) {
+ displayDeviceConfig = mDefaultDisplayDeviceConfig;
+ }
+ mHighDisplayBrightnessThresholds = loadBrightnessThresholds(
+ () -> mDeviceConfigDisplaySettings.getHighDisplayBrightnessThresholds(),
+ () -> displayDeviceConfig.getHighDisplayBrightnessThresholds(),
+ R.array.config_highDisplayBrightnessThresholdsOfFixedRefreshRate,
+ displayDeviceConfig, /* attemptLoadingFromDeviceConfig= */ false);
+ mHighAmbientBrightnessThresholds = loadBrightnessThresholds(
+ () -> mDeviceConfigDisplaySettings.getHighAmbientBrightnessThresholds(),
+ () -> displayDeviceConfig.getHighAmbientBrightnessThresholds(),
+ R.array.config_highAmbientBrightnessThresholdsOfFixedRefreshRate,
+ displayDeviceConfig, /* attemptLoadingFromDeviceConfig= */ false);
}
restartObserver();
}
@@ -2156,7 +2181,15 @@
* DeviceConfig properties.
*/
public void onDeviceConfigRefreshRateInHighZoneChanged(int refreshRate) {
- if (refreshRate != mRefreshRateInHighZone) {
+ if (refreshRate == -1) {
+ // Given there is no value available in DeviceConfig, lets not attempt loading it
+ // from there.
+ synchronized (mLock) {
+ loadRefreshRateInHighZone(mDefaultDisplayDeviceConfig,
+ /* attemptLoadingFromDeviceConfig= */ false);
+ }
+ restartObserver();
+ } else if (refreshRate != mRefreshRateInHighZone) {
mRefreshRateInHighZone = refreshRate;
restartObserver();
}
@@ -3067,10 +3100,8 @@
new Pair<>(lowDisplayBrightnessThresholds, lowAmbientBrightnessThresholds))
.sendToTarget();
- if (refreshRateInLowZone != -1) {
- mHandler.obtainMessage(MSG_REFRESH_RATE_IN_LOW_ZONE_CHANGED, refreshRateInLowZone,
- 0).sendToTarget();
- }
+ mHandler.obtainMessage(MSG_REFRESH_RATE_IN_LOW_ZONE_CHANGED, refreshRateInLowZone,
+ 0).sendToTarget();
int[] highDisplayBrightnessThresholds = getHighDisplayBrightnessThresholds();
int[] highAmbientBrightnessThresholds = getHighAmbientBrightnessThresholds();
@@ -3080,10 +3111,8 @@
new Pair<>(highDisplayBrightnessThresholds, highAmbientBrightnessThresholds))
.sendToTarget();
- if (refreshRateInHighZone != -1) {
- mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HIGH_ZONE_CHANGED, refreshRateInHighZone,
- 0).sendToTarget();
- }
+ mHandler.obtainMessage(MSG_REFRESH_RATE_IN_HIGH_ZONE_CHANGED, refreshRateInHighZone,
+ 0).sendToTarget();
synchronized (mLock) {
final int refreshRateInHbmSunlight =
diff --git a/services/core/java/com/android/server/input/KeyboardLayoutManager.java b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
index f873a1b..4d4a87e 100644
--- a/services/core/java/com/android/server/input/KeyboardLayoutManager.java
+++ b/services/core/java/com/android/server/input/KeyboardLayoutManager.java
@@ -65,6 +65,7 @@
import com.android.internal.messages.nano.SystemMessageProto;
import com.android.internal.notification.SystemNotificationChannels;
import com.android.internal.util.XmlUtils;
+import com.android.server.inputmethod.InputMethodManagerInternal;
import libcore.io.Streams;
@@ -1226,9 +1227,15 @@
mContext.getSystemService(UserManager.class));
InputMethodManager inputMethodManager = Objects.requireNonNull(
mContext.getSystemService(InputMethodManager.class));
+ // Need to use InputMethodManagerInternal to call getEnabledInputMethodListAsUser()
+ // instead of using InputMethodManager which uses enforceCallingPermissions() that
+ // breaks when we are calling the method for work profile user ID since it doesn't check
+ // self permissions.
+ InputMethodManagerInternal inputMethodManagerInternal = InputMethodManagerInternal.get();
for (UserHandle userHandle : userManager.getUserHandles(true /* excludeDying */)) {
int userId = userHandle.getIdentifier();
- for (InputMethodInfo imeInfo : inputMethodManager.getEnabledInputMethodListAsUser(
+ for (InputMethodInfo imeInfo :
+ inputMethodManagerInternal.getEnabledInputMethodListAsUser(
userId)) {
for (InputMethodSubtype imeSubtype :
inputMethodManager.getEnabledInputMethodSubtypeList(
diff --git a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
index 9f7ff31..0ae1e80 100644
--- a/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
+++ b/services/core/java/com/android/server/inputmethod/DefaultImeVisibilityApplier.java
@@ -136,17 +136,16 @@
mWindowManagerInternal.showImePostLayout(windowToken, statsToken);
break;
case STATE_HIDE_IME:
- if (mService.mCurFocusedWindowClient != null) {
+ if (mService.hasAttachedClient()) {
ImeTracker.forLogging().onProgress(statsToken,
ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
// IMMS only knows of focused window, not the actual IME target.
// e.g. it isn't aware of any window that has both
// NOT_FOCUSABLE, ALT_FOCUSABLE_IM flags set and can the IME target.
- // Send it to window manager to hide IME from IME target window.
- // TODO(b/139861270): send to mCurClient.client once IMMS is aware of
- // actual IME target.
+ // Send it to window manager to hide IME from the actual IME control target
+ // of the target display.
mWindowManagerInternal.hideIme(windowToken,
- mService.mCurFocusedWindowClient.mSelfReportedDisplayId, statsToken);
+ mService.getDisplayIdToShowImeLocked(), statsToken);
} else {
ImeTracker.forLogging().onFailed(statsToken,
ImeTracker.PHASE_SERVER_APPLY_IME_VISIBILITY);
diff --git a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
index e32bf1b..7a0bf0c 100644
--- a/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
+++ b/services/core/java/com/android/server/inputmethod/InputMethodManagerService.java
@@ -2003,7 +2003,7 @@
@Override
public InputMethodInfo getCurrentInputMethodInfoAsUser(@UserIdInt int userId) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(
+ mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
synchronized (ImfLock.class) {
@@ -2017,7 +2017,7 @@
public List<InputMethodInfo> getInputMethodList(@UserIdInt int userId,
@DirectBootAwareness int directBootAwareness) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(
+ mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
synchronized (ImfLock.class) {
@@ -2040,7 +2040,7 @@
@Override
public List<InputMethodInfo> getEnabledInputMethodList(@UserIdInt int userId) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(
+ mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
synchronized (ImfLock.class) {
@@ -2062,7 +2062,7 @@
@Override
public boolean isStylusHandwritingAvailableAsUser(@UserIdInt int userId) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(
+ mContext.enforceCallingOrSelfPermission(
Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
@@ -2158,7 +2158,8 @@
public List<InputMethodSubtype> getEnabledInputMethodSubtypeList(String imiId,
boolean allowsImplicitlyEnabledSubtypes, @UserIdInt int userId) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
synchronized (ImfLock.class) {
@@ -2339,6 +2340,19 @@
}
}
+ /** {@code true} when a {@link ClientState} has attached from starting the input connection. */
+ @GuardedBy("ImfLock.class")
+ boolean hasAttachedClient() {
+ return mCurClient != null;
+ }
+
+ @VisibleForTesting
+ void setAttachedClientForTesting(@NonNull ClientState cs) {
+ synchronized (ImfLock.class) {
+ mCurClient = cs;
+ }
+ }
+
@GuardedBy("ImfLock.class")
void clearInputShownLocked() {
mVisibilityStateComputer.setInputShown(false);
@@ -3621,7 +3635,8 @@
int unverifiedTargetSdkVersion, @UserIdInt int userId,
@NonNull ImeOnBackInvokedDispatcher imeDispatcher) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
if (editorInfo == null || editorInfo.targetInputMethodUser == null
|| editorInfo.targetInputMethodUser.getIdentifier() != userId) {
@@ -4102,7 +4117,8 @@
@Override
public InputMethodSubtype getLastInputMethodSubtype(@UserIdInt int userId) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
synchronized (ImfLock.class) {
if (mSettings.getCurrentUserId() == userId) {
@@ -4120,7 +4136,8 @@
public void setAdditionalInputMethodSubtypes(String imiId, InputMethodSubtype[] subtypes,
@UserIdInt int userId) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
final int callingUid = Binder.getCallingUid();
@@ -4173,7 +4190,8 @@
public void setExplicitlyEnabledInputMethodSubtypes(String imeId,
@NonNull int[] subtypeHashCodes, @UserIdInt int userId) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
final int callingUid = Binder.getCallingUid();
final ComponentName imeComponentName =
@@ -5399,7 +5417,8 @@
@Override
public InputMethodSubtype getCurrentInputMethodSubtype(@UserIdInt int userId) {
if (UserHandle.getCallingUserId() != userId) {
- mContext.enforceCallingPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ mContext.enforceCallingOrSelfPermission(
+ Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
}
synchronized (ImfLock.class) {
if (mSettings.getCurrentUserId() == userId) {
diff --git a/services/core/java/com/android/server/location/LocationManagerService.java b/services/core/java/com/android/server/location/LocationManagerService.java
index fa2ba21..2b20060 100644
--- a/services/core/java/com/android/server/location/LocationManagerService.java
+++ b/services/core/java/com/android/server/location/LocationManagerService.java
@@ -604,10 +604,11 @@
return mGnssManagerService == null ? 0 : mGnssManagerService.getGnssBatchSize();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
@Override
public void startGnssBatch(long periodNanos, ILocationListener listener, String packageName,
@Nullable String attributionTag, String listenerId) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE, null);
+ startGnssBatch_enforcePermission();
if (mGnssManagerService == null) {
return;
@@ -633,9 +634,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
@Override
public void flushGnssBatch() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE, null);
+ flushGnssBatch_enforcePermission();
if (mGnssManagerService == null) {
return;
@@ -648,9 +650,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.LOCATION_HARDWARE)
@Override
public void stopGnssBatch() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.LOCATION_HARDWARE, null);
+ stopGnssBatch_enforcePermission();
if (mGnssManagerService == null) {
return;
@@ -1104,10 +1107,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.INTERACT_ACROSS_USERS)
@Override
@RequiresPermission(INTERACT_ACROSS_USERS)
public void addProviderRequestListener(IProviderRequestListener listener) {
- mContext.enforceCallingOrSelfPermission(INTERACT_ACROSS_USERS, null);
+ addProviderRequestListener_enforcePermission();
for (LocationProviderManager manager : mProviderManagers) {
if (manager.isVisibleToCaller()) {
manager.addProviderRequestListener(listener);
@@ -1188,10 +1192,11 @@
return manager.getProperties();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.READ_DEVICE_CONFIG)
@Override
public boolean isProviderPackage(@Nullable String provider, String packageName,
@Nullable String attributionTag) {
- mContext.enforceCallingOrSelfPermission(permission.READ_DEVICE_CONFIG, null);
+ isProviderPackage_enforcePermission();
for (LocationProviderManager manager : mProviderManagers) {
if (provider != null && !provider.equals(manager.getName())) {
@@ -1210,9 +1215,10 @@
return false;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.READ_DEVICE_CONFIG)
@Override
public List<String> getProviderPackages(String provider) {
- mContext.enforceCallingOrSelfPermission(permission.READ_DEVICE_CONFIG, null);
+ getProviderPackages_enforcePermission();
LocationProviderManager manager = getLocationProviderManager(provider);
if (manager == null) {
diff --git a/services/core/java/com/android/server/media/MediaFeatureFlagManager.java b/services/core/java/com/android/server/media/MediaFeatureFlagManager.java
index 70ee38f..f555505 100644
--- a/services/core/java/com/android/server/media/MediaFeatureFlagManager.java
+++ b/services/core/java/com/android/server/media/MediaFeatureFlagManager.java
@@ -17,6 +17,8 @@
package com.android.server.media;
import android.annotation.StringDef;
+import android.app.ActivityThread;
+import android.app.Application;
import android.provider.DeviceConfig;
import java.lang.annotation.ElementType;
@@ -31,10 +33,13 @@
*/
private static final String NAMESPACE_MEDIA_BETTER_TOGETHER = "media_better_together";
- @StringDef(prefix = "FEATURE_", value = {
- FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER
- })
- @Target({ ElementType.TYPE_USE, ElementType.TYPE_PARAMETER })
+ @StringDef(
+ prefix = "FEATURE_",
+ value = {
+ FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER,
+ FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE
+ })
+ @Target({ElementType.TYPE_USE, ElementType.TYPE_PARAMETER})
@Retention(RetentionPolicy.SOURCE)
/* package */ @interface MediaFeatureFlag {}
@@ -46,6 +51,13 @@
FEATURE_AUDIO_STRATEGIES_IS_USING_LEGACY_CONTROLLER =
"BluetoothRouteController__enable_legacy_bluetooth_routes_controller";
+ /**
+ * Whether to use IMPORTANCE_FOREGROUND (i.e. 100) or IMPORTANCE_FOREGROUND_SERVICE (i.e. 125)
+ * as the minimum package importance for scanning.
+ */
+ /* package */ static final @MediaFeatureFlag String
+ FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE = "scanning_package_minimum_importance";
+
private static final MediaFeatureFlagManager sInstance = new MediaFeatureFlagManager();
private MediaFeatureFlagManager() {
@@ -63,4 +75,29 @@
public boolean getBoolean(@MediaFeatureFlag String key, boolean defaultValue) {
return DeviceConfig.getBoolean(NAMESPACE_MEDIA_BETTER_TOGETHER, key, defaultValue);
}
+
+ /**
+ * Returns an int value from {@link DeviceConfig} from the system_time namespace, or {@code
+ * defaultValue} if there is no explicit value set.
+ */
+ public int getInt(@MediaFeatureFlag String key, int defaultValue) {
+ return DeviceConfig.getInt(NAMESPACE_MEDIA_BETTER_TOGETHER, key, defaultValue);
+ }
+
+ /**
+ * Adds a listener to react for changes in media feature flags values. Future calls to this
+ * method with the same listener will replace the old namespace and executor.
+ *
+ * @param onPropertiesChangedListener The listener to add.
+ */
+ public void addOnPropertiesChangedListener(
+ DeviceConfig.OnPropertiesChangedListener onPropertiesChangedListener) {
+ Application currentApplication = ActivityThread.currentApplication();
+ if (currentApplication != null) {
+ DeviceConfig.addOnPropertiesChangedListener(
+ NAMESPACE_MEDIA_BETTER_TOGETHER,
+ currentApplication.getMainExecutor(),
+ onPropertiesChangedListener);
+ }
+ }
}
diff --git a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
index 3c97aaf8..087c5bb 100644
--- a/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
+++ b/services/core/java/com/android/server/media/MediaRouter2ServiceImpl.java
@@ -24,12 +24,12 @@
import static android.media.MediaRouter2Utils.getProviderId;
import static com.android.internal.util.function.pooled.PooledLambda.obtainMessage;
+import static com.android.server.media.MediaFeatureFlagManager.FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE;
import android.Manifest;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
-import android.app.ActivityThread;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
import android.content.Context;
@@ -92,15 +92,11 @@
// in MediaRouter2, remove this constant and replace the usages with the real request IDs.
private static final long DUMMY_REQUEST_ID = -1;
- private static final String MEDIA_BETTER_TOGETHER_NAMESPACE = "media_better_together";
-
- private static final String KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE =
- "scanning_package_minimum_importance";
-
- private static int sPackageImportanceForScanning = DeviceConfig.getInt(
- MEDIA_BETTER_TOGETHER_NAMESPACE,
- /* name */ KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE,
- /* defaultValue */ IMPORTANCE_FOREGROUND_SERVICE);
+ private static int sPackageImportanceForScanning =
+ MediaFeatureFlagManager.getInstance()
+ .getInt(
+ FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE,
+ IMPORTANCE_FOREGROUND_SERVICE);
private final Context mContext;
private final UserManagerInternal mUserManagerInternal;
@@ -156,9 +152,8 @@
mContext.registerReceiver(mScreenOnOffReceiver, screenOnOffIntentFilter);
- DeviceConfig.addOnPropertiesChangedListener(MEDIA_BETTER_TOGETHER_NAMESPACE,
- ActivityThread.currentApplication().getMainExecutor(),
- this::onDeviceConfigChange);
+ MediaFeatureFlagManager.getInstance()
+ .addOnPropertiesChangedListener(this::onDeviceConfigChange);
}
// Start of methods that implement MediaRouter2 operations.
@@ -1002,9 +997,11 @@
return;
}
- Slog.i(TAG, TextUtils.formatSimple(
- "setSessionVolumeWithRouter2 | router: %d, session: %s, volume: %d",
- routerRecord.mRouterId, uniqueSessionId, volume));
+ Slog.i(
+ TAG,
+ TextUtils.formatSimple(
+ "setSessionVolumeWithRouter2 | router: %d, session: %s, volume: %d",
+ routerRecord.mRouterId, uniqueSessionId, volume));
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::setSessionVolumeOnHandler,
@@ -1021,9 +1018,11 @@
return;
}
- Slog.i(TAG, TextUtils.formatSimple(
- "releaseSessionWithRouter2 | router: %d, session: %s",
- routerRecord.mRouterId, uniqueSessionId));
+ Slog.i(
+ TAG,
+ TextUtils.formatSimple(
+ "releaseSessionWithRouter2 | router: %d, session: %s",
+ routerRecord.mRouterId, uniqueSessionId));
routerRecord.mUserRecord.mHandler.sendMessage(
obtainMessage(UserHandler::releaseSessionOnHandler,
@@ -1100,8 +1099,11 @@
// TODO: UserRecord <-> routerRecord, why do they reference each other?
// How about removing mUserRecord from routerRecord?
routerRecord.mUserRecord.mHandler.sendMessage(
- obtainMessage(UserHandler::notifyDiscoveryPreferenceChangedToManager,
- routerRecord.mUserRecord.mHandler, routerRecord, manager));
+ obtainMessage(
+ UserHandler::notifyDiscoveryPreferenceChangedToManager,
+ routerRecord.mUserRecord.mHandler,
+ routerRecord,
+ manager));
}
userRecord.mHandler.sendMessage(
@@ -1381,9 +1383,10 @@
// End of locked methods that are used by both MediaRouter2 and MediaRouter2Manager.
private void onDeviceConfigChange(@NonNull DeviceConfig.Properties properties) {
- sPackageImportanceForScanning = properties.getInt(
- /* name */ KEY_SCANNING_PACKAGE_MINIMUM_IMPORTANCE,
- /* defaultValue */ IMPORTANCE_FOREGROUND_SERVICE);
+ sPackageImportanceForScanning =
+ properties.getInt(
+ /* name */ FEATURE_SCANNING_MINIMUM_PACKAGE_IMPORTANCE,
+ /* defaultValue */ IMPORTANCE_FOREGROUND_SERVICE);
}
static long toUniqueRequestId(int requesterId, int originalRequestId) {
@@ -1734,10 +1737,10 @@
}
boolean isUidRelevant;
synchronized (service.mLock) {
- isUidRelevant = mUserRecord.mRouterRecords.stream().anyMatch(
- router -> router.mUid == uid)
- | mUserRecord.mManagerRecords.stream().anyMatch(
- manager -> manager.mUid == uid);
+ isUidRelevant =
+ mUserRecord.mRouterRecords.stream().anyMatch(router -> router.mUid == uid)
+ | mUserRecord.mManagerRecords.stream()
+ .anyMatch(manager -> manager.mUid == uid);
}
if (isUidRelevant) {
sendMessage(PooledLambda.obtainMessage(
@@ -2400,7 +2403,7 @@
private static void notifyRoutesUpdatedToRouterRecords(
@NonNull List<RouterRecord> routerRecords,
@NonNull List<MediaRoute2Info> routes) {
- for (RouterRecord routerRecord: routerRecords) {
+ for (RouterRecord routerRecord : routerRecords) {
List<MediaRoute2Info> filteredRoutes = getFilteredRoutesForPackageName(routes,
routerRecord.mPackageName);
try {
@@ -2412,15 +2415,15 @@
}
/**
- * Filters list of routes to return only public routes or routes provided by
- * the same package name or routes containing this package name in its allow list.
+ * Filters list of routes to return only public routes or routes provided by the same
+ * package name or routes containing this package name in its allow list.
+ *
* @param routes initial list of routes to be filtered.
* @param packageName router's package name to filter routes for it.
* @return only the routes that this package name is allowed to see.
*/
private static List<MediaRoute2Info> getFilteredRoutesForPackageName(
- @NonNull List<MediaRoute2Info> routes,
- @NonNull String packageName) {
+ @NonNull List<MediaRoute2Info> routes, @NonNull String packageName) {
List<MediaRoute2Info> filteredRoutes = new ArrayList<>();
for (MediaRoute2Info route : routes) {
if (route.isVisibleTo(packageName)) {
@@ -2609,11 +2612,15 @@
.map(record -> record.mDiscoveryPreference)
.collect(Collectors.toList());
} else {
- discoveryPreferences = routerRecords.stream().filter(record ->
- service.mActivityManager.getPackageImportance(record.mPackageName)
- <= sPackageImportanceForScanning)
- .map(record -> record.mDiscoveryPreference)
- .collect(Collectors.toList());
+ discoveryPreferences =
+ routerRecords.stream()
+ .filter(
+ record ->
+ service.mActivityManager.getPackageImportance(
+ record.mPackageName)
+ <= sPackageImportanceForScanning)
+ .map(record -> record.mDiscoveryPreference)
+ .collect(Collectors.toList());
}
}
@@ -2658,6 +2665,7 @@
return null;
}
}
+
static final class SessionCreationRequest {
public final RouterRecord mRouterRecord;
public final long mUniqueRequestId;
diff --git a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
index 4832618..f6a4bf1a 100644
--- a/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
+++ b/services/core/java/com/android/server/media/projection/MediaProjectionManagerService.java
@@ -67,7 +67,7 @@
* The {@link MediaProjectionManagerService} manages the creation and lifetime of MediaProjections,
* as well as the capabilities they grant. Any service using MediaProjection tokens as permission
* grants <b>must</b> validate the token before use by calling {@link
- * IMediaProjectionService#isCurrentProjection}.
+ * IMediaProjectionManager#isCurrentProjection}.
*/
public final class MediaProjectionManagerService extends SystemService
implements Watchdog.Monitor {
@@ -333,13 +333,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
@Override // Binder call
public void stopActiveProjection() {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to add "
- + "projection callbacks");
- }
+ stopActiveProjection_enforcePermission();
final long token = Binder.clearCallingIdentity();
try {
if (mProjectionGrant != null) {
@@ -350,13 +347,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
@Override // Binder call
public void notifyActiveProjectionCapturedContentResized(int width, int height) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to notify "
- + "on captured content resize");
- }
+ notifyActiveProjectionCapturedContentResized_enforcePermission();
if (!isCurrentProjection(mProjectionGrant)) {
return;
}
@@ -370,13 +364,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_MEDIA_PROJECTION)
@Override
public void notifyActiveProjectionCapturedContentVisibilityChanged(boolean isVisible) {
- if (mContext.checkCallingOrSelfPermission(Manifest.permission.MANAGE_MEDIA_PROJECTION)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires MANAGE_MEDIA_PROJECTION in order to notify "
- + "on captured content resize");
- }
+ notifyActiveProjectionCapturedContentVisibilityChanged_enforcePermission();
if (!isCurrentProjection(mProjectionGrant)) {
return;
}
diff --git a/services/core/java/com/android/server/notification/NotificationComparator.java b/services/core/java/com/android/server/notification/NotificationComparator.java
index 647a89e..6f0903c 100644
--- a/services/core/java/com/android/server/notification/NotificationComparator.java
+++ b/services/core/java/com/android/server/notification/NotificationComparator.java
@@ -25,6 +25,7 @@
import android.content.IntentFilter;
import android.telecom.TelecomManager;
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
import com.android.internal.util.NotificationMessagingUtil;
import java.util.Comparator;
@@ -38,6 +39,7 @@
private final Context mContext;
private final NotificationMessagingUtil mMessagingUtil;
+ private final boolean mSortByInterruptiveness;
private String mDefaultPhoneApp;
public NotificationComparator(Context context) {
@@ -45,6 +47,8 @@
mContext.registerReceiver(mPhoneAppBroadcastReceiver,
new IntentFilter(TelecomManager.ACTION_DEFAULT_DIALER_CHANGED));
mMessagingUtil = new NotificationMessagingUtil(mContext);
+ mSortByInterruptiveness = !SystemUiSystemPropertiesFlags.getResolver().isEnabled(
+ SystemUiSystemPropertiesFlags.NotificationFlags.NO_SORT_BY_INTERRUPTIVENESS);
}
@Override
@@ -135,10 +139,12 @@
return -1 * Integer.compare(leftPriority, rightPriority);
}
- final boolean leftInterruptive = left.isInterruptive();
- final boolean rightInterruptive = right.isInterruptive();
- if (leftInterruptive != rightInterruptive) {
- return -1 * Boolean.compare(leftInterruptive, rightInterruptive);
+ if (mSortByInterruptiveness) {
+ final boolean leftInterruptive = left.isInterruptive();
+ final boolean rightInterruptive = right.isInterruptive();
+ if (leftInterruptive != rightInterruptive) {
+ return -1 * Boolean.compare(leftInterruptive, rightInterruptive);
+ }
}
// then break ties by time, most recent first
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index c2e8df1..f775f09 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2340,7 +2340,6 @@
mAppOps,
new SysUiStatsEvent.BuilderFactory(),
mShowReviewPermissionsNotification);
- mPreferencesHelper.updateFixedImportance(mUm.getUsers());
mRankingHelper = new RankingHelper(getContext(),
mRankingHandler,
mPreferencesHelper,
@@ -2771,6 +2770,9 @@
maybeShowInitialReviewPermissionsNotification();
} else if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mSnoozeHelper.scheduleRepostsForPersistedNotifications(System.currentTimeMillis());
+ } else if (phase == SystemService.PHASE_DEVICE_SPECIFIC_SERVICES_READY) {
+ mPreferencesHelper.updateFixedImportance(mUm.getUsers());
+ mPreferencesHelper.migrateNotificationPermissions(mUm.getUsers());
}
}
@@ -4259,6 +4261,7 @@
return getActiveNotificationsWithAttribution(callingPkg, null);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_NOTIFICATIONS)
/**
* System-only API for getting a list of current (i.e. not cleared) notifications.
*
@@ -4269,9 +4272,7 @@
public StatusBarNotification[] getActiveNotificationsWithAttribution(String callingPkg,
String callingAttributionTag) {
// enforce() will ensure the calling uid has the correct permission
- getContext().enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NOTIFICATIONS,
- "NotificationManagerService.getActiveNotifications");
+ getActiveNotificationsWithAttribution_enforcePermission();
ArrayList<StatusBarNotification> tmp = new ArrayList<>();
int uid = Binder.getCallingUid();
@@ -4387,6 +4388,7 @@
includeSnoozed);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_NOTIFICATIONS)
/**
* System-only API for getting a list of recent (cleared, no longer shown) notifications.
*/
@@ -4395,9 +4397,7 @@
public StatusBarNotification[] getHistoricalNotificationsWithAttribution(String callingPkg,
String callingAttributionTag, int count, boolean includeSnoozed) {
// enforce() will ensure the calling uid has the correct permission
- getContext().enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NOTIFICATIONS,
- "NotificationManagerService.getHistoricalNotifications");
+ getHistoricalNotificationsWithAttribution_enforcePermission();
StatusBarNotification[] tmp = null;
int uid = Binder.getCallingUid();
@@ -4413,6 +4413,7 @@
return tmp;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_NOTIFICATIONS)
/**
* System-only API for getting a list of historical notifications. May contain multiple days
* of notifications.
@@ -4423,9 +4424,7 @@
public NotificationHistory getNotificationHistory(String callingPkg,
String callingAttributionTag) {
// enforce() will ensure the calling uid has the correct permission
- getContext().enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_NOTIFICATIONS,
- "NotificationManagerService.getNotificationHistory");
+ getNotificationHistory_enforcePermission();
int uid = Binder.getCallingUid();
// noteOp will check to make sure the callingPkg matches the uid
@@ -6827,7 +6826,8 @@
}
// Ensure MediaStyle has correct permissions for remote device extras
- if (notification.isStyle(Notification.MediaStyle.class)) {
+ if (notification.isStyle(Notification.MediaStyle.class)
+ || notification.isStyle(Notification.DecoratedMediaCustomViewStyle.class)) {
int hasMediaContentControlPermission = getContext().checkPermission(
android.Manifest.permission.MEDIA_CONTENT_CONTROL, -1, notificationUid);
if (hasMediaContentControlPermission != PERMISSION_GRANTED) {
@@ -6864,7 +6864,8 @@
* A notification should be dismissible, unless it's exempted for some reason.
*/
private boolean canBeNonDismissible(ApplicationInfo ai, Notification notification) {
- return notification.isMediaNotification() || isEnterpriseExempted(ai);
+ return notification.isMediaNotification() || isEnterpriseExempted(ai)
+ || isCallNotification(ai.packageName, ai.uid, notification);
}
private boolean isEnterpriseExempted(ApplicationInfo ai) {
@@ -7799,7 +7800,8 @@
*/
@GuardedBy("mNotificationLock")
@VisibleForTesting
- protected boolean isVisuallyInterruptive(NotificationRecord old, NotificationRecord r) {
+ protected boolean isVisuallyInterruptive(@Nullable NotificationRecord old,
+ @NonNull NotificationRecord r) {
// Ignore summary updates because we don't display most of the information.
if (r.getSbn().isGroup() && r.getSbn().getNotification().isGroupSummary()) {
if (DEBUG_INTERRUPTIVENESS) {
@@ -7817,14 +7819,6 @@
return true;
}
- if (r == null) {
- if (DEBUG_INTERRUPTIVENESS) {
- Slog.v(TAG, "INTERRUPTIVENESS: "
- + r.getKey() + " is not interruptive: null");
- }
- return false;
- }
-
Notification oldN = old.getSbn().getNotification();
Notification newN = r.getSbn().getNotification();
if (oldN.extras == null || newN.extras == null) {
@@ -7882,6 +7876,14 @@
return true;
}
+ if (Notification.areIconsDifferent(oldN, newN)) {
+ if (DEBUG_INTERRUPTIVENESS) {
+ Slog.v(TAG, "INTERRUPTIVENESS: "
+ + r.getKey() + " is interruptive: icons differ");
+ }
+ return true;
+ }
+
// Fields below are invisible to bubbles.
if (r.canBubble()) {
if (DEBUG_INTERRUPTIVENESS) {
diff --git a/services/core/java/com/android/server/notification/PreferencesHelper.java b/services/core/java/com/android/server/notification/PreferencesHelper.java
index 4bafbc7..aa97aa3 100644
--- a/services/core/java/com/android/server/notification/PreferencesHelper.java
+++ b/services/core/java/com/android/server/notification/PreferencesHelper.java
@@ -237,7 +237,6 @@
Settings.Global.REVIEW_PERMISSIONS_NOTIFICATION_STATE,
NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW);
}
- ArrayList<PermissionHelper.PackagePermission> pkgPerms = new ArrayList<>();
synchronized (mPackagePreferences) {
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT) {
tag = parser.getName();
@@ -255,27 +254,18 @@
String name = parser.getAttributeValue(null, ATT_NAME);
if (!TextUtils.isEmpty(name)) {
restorePackage(parser, forRestore, userId, name, upgradeForBubbles,
- migrateToPermission, pkgPerms);
+ migrateToPermission);
}
}
}
}
}
- if (migrateToPermission) {
- for (PackagePermission p : pkgPerms) {
- try {
- mPermissionHelper.setNotificationPermission(p);
- } catch (Exception e) {
- Slog.e(TAG, "could not migrate setting for " + p.packageName, e);
- }
- }
- }
}
@GuardedBy("mPackagePreferences")
private void restorePackage(TypedXmlPullParser parser, boolean forRestore,
@UserIdInt int userId, String name, boolean upgradeForBubbles,
- boolean migrateToPermission, ArrayList<PermissionHelper.PackagePermission> pkgPerms) {
+ boolean migrateToPermission) {
try {
int uid = parser.getAttributeInt(null, ATT_UID, UNKNOWN_UID);
if (forRestore) {
@@ -379,14 +369,6 @@
if (migrateToPermission) {
r.importance = appImportance;
r.migrateToPm = true;
- if (r.uid != UNKNOWN_UID) {
- // Don't call into permission system until we have a valid uid
- PackagePermission pkgPerm = new PackagePermission(
- r.pkg, UserHandle.getUserId(r.uid),
- r.importance != IMPORTANCE_NONE,
- hasUserConfiguredSettings(r));
- pkgPerms.add(pkgPerm);
- }
}
} catch (Exception e) {
Slog.w(TAG, "Failed to restore pkg", e);
@@ -2663,6 +2645,31 @@
}
}
+ public void migrateNotificationPermissions(List<UserInfo> users) {
+ for (UserInfo user : users) {
+ List<PackageInfo> packages = mPm.getInstalledPackagesAsUser(
+ PackageManager.PackageInfoFlags.of(PackageManager.MATCH_ALL),
+ user.getUserHandle().getIdentifier());
+ for (PackageInfo pi : packages) {
+ synchronized (mPackagePreferences) {
+ PackagePreferences p = getOrCreatePackagePreferencesLocked(
+ pi.packageName, pi.applicationInfo.uid);
+ if (p.migrateToPm && p.uid != UNKNOWN_UID) {
+ try {
+ PackagePermission pkgPerm = new PackagePermission(
+ p.pkg, UserHandle.getUserId(p.uid),
+ p.importance != IMPORTANCE_NONE,
+ hasUserConfiguredSettings(p));
+ mPermissionHelper.setNotificationPermission(pkgPerm);
+ } catch (Exception e) {
+ Slog.e(TAG, "could not migrate setting for " + p.pkg, e);
+ }
+ }
+ }
+ }
+ }
+ }
+
private void updateConfig() {
mRankingHandler.requestSort();
}
diff --git a/services/core/java/com/android/server/pm/Computer.java b/services/core/java/com/android/server/pm/Computer.java
index 19575a3..1e9a15d 100644
--- a/services/core/java/com/android/server/pm/Computer.java
+++ b/services/core/java/com/android/server/pm/Computer.java
@@ -41,6 +41,7 @@
import android.content.pm.SigningDetails;
import android.content.pm.UserInfo;
import android.content.pm.VersionedPackage;
+import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Pair;
@@ -498,7 +499,7 @@
String getInstallerPackageName(@NonNull String packageName, @UserIdInt int userId);
@Nullable
- InstallSourceInfo getInstallSourceInfo(@NonNull String packageName);
+ InstallSourceInfo getInstallSourceInfo(@NonNull String packageName, @UserIdInt int userId);
@PackageManager.EnabledState
int getApplicationEnabledSetting(@NonNull String packageName, @UserIdInt int userId);
@@ -518,14 +519,15 @@
* returns false.
*/
boolean isComponentEffectivelyEnabled(@NonNull ComponentInfo componentInfo,
- @UserIdInt int userId);
+ @NonNull UserHandle userHandle);
/**
* @return true if the runtime app user enabled state and the install-time app manifest enabled
* state are both effectively enabled for the given app. Or if the app cannot be found,
* returns false.
*/
- boolean isApplicationEffectivelyEnabled(@NonNull String packageName, @UserIdInt int userId);
+ boolean isApplicationEffectivelyEnabled(@NonNull String packageName,
+ @NonNull UserHandle userHandle);
@Nullable
KeySet getKeySetByAlias(@NonNull String packageName, @NonNull String alias);
diff --git a/services/core/java/com/android/server/pm/ComputerEngine.java b/services/core/java/com/android/server/pm/ComputerEngine.java
index 14b72ff..2257c5e 100644
--- a/services/core/java/com/android/server/pm/ComputerEngine.java
+++ b/services/core/java/com/android/server/pm/ComputerEngine.java
@@ -4982,9 +4982,11 @@
@Override
@Nullable
- public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) {
+ public InstallSourceInfo getInstallSourceInfo(@NonNull String packageName,
+ @UserIdInt int userId) {
final int callingUid = Binder.getCallingUid();
- final int userId = UserHandle.getUserId(callingUid);
+ enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */,
+ false /* checkShell */, "getInstallSourceInfo");
String installerPackageName;
String initiatingPackageName;
@@ -5129,9 +5131,10 @@
@Override
public boolean isComponentEffectivelyEnabled(@NonNull ComponentInfo componentInfo,
- @UserIdInt int userId) {
+ @NonNull UserHandle userHandle) {
try {
String packageName = componentInfo.packageName;
+ int userId = userHandle.getIdentifier();
int appEnabledSetting =
mSettings.getApplicationEnabledSetting(packageName, userId);
if (appEnabledSetting == COMPONENT_ENABLED_STATE_DEFAULT) {
@@ -5154,9 +5157,10 @@
@Override
public boolean isApplicationEffectivelyEnabled(@NonNull String packageName,
- @UserIdInt int userId) {
+ @NonNull UserHandle userHandle) {
try {
- int appEnabledSetting = mSettings.getApplicationEnabledSetting(packageName, userId);
+ int appEnabledSetting = mSettings.getApplicationEnabledSetting(packageName,
+ userHandle.getIdentifier());
if (appEnabledSetting == COMPONENT_ENABLED_STATE_DEFAULT) {
final AndroidPackage pkg = getPackage(packageName);
if (pkg == null) {
diff --git a/services/core/java/com/android/server/pm/DeletePackageHelper.java b/services/core/java/com/android/server/pm/DeletePackageHelper.java
index a119a3c..9a5ee81 100644
--- a/services/core/java/com/android/server/pm/DeletePackageHelper.java
+++ b/services/core/java/com/android/server/pm/DeletePackageHelper.java
@@ -19,6 +19,7 @@
import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+import static android.content.pm.PackageManager.DELETE_SUCCEEDED;
import static android.content.pm.PackageManager.MATCH_KNOWN_PACKAGES;
import static android.content.pm.PackageManager.PERMISSION_GRANTED;
import static android.os.storage.StorageManager.FLAG_STORAGE_CE;
@@ -339,7 +340,7 @@
packageInstallerService.onInstallerPackageDeleted(uninstalledPs.getAppId(), removeUser);
}
- return res ? PackageManager.DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
+ return res ? DELETE_SUCCEEDED : PackageManager.DELETE_FAILED_INTERNAL_ERROR;
}
/*
@@ -777,21 +778,30 @@
returnCode = deletePackageX(internalPackageName, versionCode,
userId, deleteFlags, false /*removedBySystem*/);
- // Get a list of child user profiles and delete if package is
- // present in that profile.
- int[] childUserIds = mUserManagerInternal.getProfileIds(userId, true);
- int returnCodeOfChild;
- for (int childId : childUserIds) {
- if (childId == userId) continue;
- UserProperties userProperties = mUserManagerInternal
- .getUserProperties(childId);
- if (userProperties != null && userProperties.getDeleteAppWithParent()) {
- returnCodeOfChild = deletePackageX(internalPackageName, versionCode,
- childId, deleteFlags, false /*removedBySystem*/);
- if (returnCodeOfChild != PackageManager.DELETE_SUCCEEDED) {
- Slog.w(TAG, "Package delete failed for user " + childId
- + ", returnCode " + returnCodeOfChild);
- returnCode = PackageManager.DELETE_FAILED_FOR_CHILD_PROFILE;
+ // Delete package in child only if successfully deleted in parent.
+ if (returnCode == DELETE_SUCCEEDED && packageState != null) {
+ // Get a list of child user profiles and delete if package is
+ // present in that profile.
+ int[] childUserIds = mUserManagerInternal.getProfileIds(userId, true);
+ int returnCodeOfChild;
+ for (int childId : childUserIds) {
+ if (childId == userId) continue;
+
+ // If package is not present in child then don't attempt to delete.
+ if (!packageState.getUserStateOrDefault(childId).isInstalled()) {
+ continue;
+ }
+
+ UserProperties userProperties = mUserManagerInternal
+ .getUserProperties(childId);
+ if (userProperties != null && userProperties.getDeleteAppWithParent()) {
+ returnCodeOfChild = deletePackageX(internalPackageName, versionCode,
+ childId, deleteFlags, false /*removedBySystem*/);
+ if (returnCodeOfChild != DELETE_SUCCEEDED) {
+ Slog.w(TAG, "Package delete failed for user " + childId
+ + ", returnCode " + returnCodeOfChild);
+ returnCode = PackageManager.DELETE_FAILED_FOR_CHILD_PROFILE;
+ }
}
}
}
@@ -809,7 +819,7 @@
if (!ArrayUtils.contains(blockUninstallUserIds, userId1)) {
returnCode = deletePackageX(internalPackageName, versionCode,
userId1, userFlags, false /*removedBySystem*/);
- if (returnCode != PackageManager.DELETE_SUCCEEDED) {
+ if (returnCode != DELETE_SUCCEEDED) {
Slog.w(TAG, "Package delete failed for user " + userId1
+ ", returnCode " + returnCode);
}
diff --git a/services/core/java/com/android/server/pm/IPackageManagerBase.java b/services/core/java/com/android/server/pm/IPackageManagerBase.java
index d39cac0..c29e4d7 100644
--- a/services/core/java/com/android/server/pm/IPackageManagerBase.java
+++ b/services/core/java/com/android/server/pm/IPackageManagerBase.java
@@ -463,8 +463,9 @@
@Override
@Nullable
@Deprecated
- public final InstallSourceInfo getInstallSourceInfo(@NonNull String packageName) {
- return snapshot().getInstallSourceInfo(packageName);
+ public final InstallSourceInfo getInstallSourceInfo(@NonNull String packageName,
+ @UserIdInt int userId) {
+ return snapshot().getInstallSourceInfo(packageName, userId);
}
@Override
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 7fe6c7d..cd1ae74 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -3279,7 +3279,7 @@
final RemovePackageHelper removePackageHelper = new RemovePackageHelper(mPm);
removePackageHelper.removePackage(stubPkg, true /*chatty*/);
try {
- return scanSystemPackageTracedLI(scanFile, parseFlags, scanFlags, null);
+ return initPackageTracedLI(scanFile, parseFlags, scanFlags);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
e);
@@ -3410,8 +3410,7 @@
| ParsingPackageUtils.PARSE_MUST_BE_APK
| ParsingPackageUtils.PARSE_IS_SYSTEM_DIR;
@PackageManagerService.ScanFlags int scanFlags = mPm.getSystemPackageScanFlags(codePath);
- final AndroidPackage pkg = scanSystemPackageTracedLI(
- codePath, parseFlags, scanFlags, null);
+ final AndroidPackage pkg = initPackageTracedLI(codePath, parseFlags, scanFlags);
synchronized (mPm.mLock) {
PackageSetting pkgSetting = mPm.mSettings.getPackageLPr(pkg.getPackageName());
@@ -3591,7 +3590,7 @@
try {
final File codePath = new File(pkg.getPath());
synchronized (mPm.mInstallLock) {
- scanSystemPackageTracedLI(codePath, 0, scanFlags, null);
+ initPackageTracedLI(codePath, 0, scanFlags);
}
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse updated, ex-system package: "
@@ -3734,12 +3733,6 @@
String errorMsg = null;
if (throwable == null) {
- // TODO(b/194319951): move lower in the scan chain
- // Static shared libraries have synthetic package names
- if (parseResult.parsedPackage.isStaticSharedLibrary()) {
- PackageManagerService.renameStaticSharedLibraryPackage(
- parseResult.parsedPackage);
- }
try {
addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
new UserHandle(UserHandle.USER_SYSTEM), apexInfo);
@@ -3804,8 +3797,8 @@
try {
synchronized (mPm.mInstallLock) {
- final AndroidPackage newPkg = scanSystemPackageTracedLI(
- scanFile, reparseFlags, rescanFlags, null);
+ final AndroidPackage newPkg = initPackageTracedLI(
+ scanFile, reparseFlags, rescanFlags);
// We rescanned a stub, add it to the list of stubbed system packages
if (newPkg.isStub()) {
stubSystemApps.add(packageName);
@@ -3819,28 +3812,26 @@
}
/**
- * Traces a package scan.
- * @see #scanSystemPackageLI(File, int, int, UserHandle)
+ * Traces a package scan and registers it with the system.
+ * @see #initPackageLI(File, int, int)
*/
@GuardedBy("mPm.mInstallLock")
- public AndroidPackage scanSystemPackageTracedLI(File scanFile, final int parseFlags,
- int scanFlags, @Nullable ApexManager.ActiveApexInfo apexInfo)
+ public AndroidPackage initPackageTracedLI(File scanFile, final int parseFlags, int scanFlags)
throws PackageManagerException {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
try {
- return scanSystemPackageLI(scanFile, parseFlags, scanFlags, apexInfo);
+ return initPackageLI(scanFile, parseFlags, scanFlags);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
}
/**
- * Scans a package and returns the newly parsed package.
+ * Scans a package, registers it with the system and returns the newly parsed package.
* Returns {@code null} in case of errors and the error code is stored in mLastScanError
*/
@GuardedBy("mPm.mInstallLock")
- private AndroidPackage scanSystemPackageLI(File scanFile, int parseFlags, int scanFlags,
- @Nullable ApexManager.ActiveApexInfo apexInfo)
+ private AndroidPackage initPackageLI(File scanFile, int parseFlags, int scanFlags)
throws PackageManagerException {
if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
@@ -3852,13 +3843,8 @@
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- // Static shared libraries have synthetic package names
- if (parsedPackage.isStaticSharedLibrary()) {
- PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage);
- }
-
return addForInitLI(parsedPackage, parseFlags, scanFlags,
- new UserHandle(UserHandle.USER_SYSTEM), apexInfo);
+ new UserHandle(UserHandle.USER_SYSTEM), null);
}
/**
@@ -3882,6 +3868,10 @@
throws PackageManagerException {
PackageSetting disabledPkgSetting;
synchronized (mPm.mLock) {
+ // Static shared libraries have synthetic package names
+ if (activeApexInfo == null && parsedPackage.isStaticSharedLibrary()) {
+ PackageManagerService.renameStaticSharedLibraryPackage(parsedPackage);
+ }
disabledPkgSetting =
mPm.mSettings.getDisabledSystemPkgLPr(parsedPackage.getPackageName());
if (activeApexInfo != null && disabledPkgSetting != null) {
diff --git a/services/core/java/com/android/server/pm/PackageInstallerService.java b/services/core/java/com/android/server/pm/PackageInstallerService.java
index adc0b0b..75a8dc9 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerService.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerService.java
@@ -1294,9 +1294,10 @@
installReason, allowListedPermissions, statusReceiver);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.INSTALL_PACKAGES)
@Override
public void setPermissionsResult(int sessionId, boolean accepted) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.INSTALL_PACKAGES, TAG);
+ setPermissionsResult_enforcePermission();
synchronized (mSessions) {
PackageInstallerSession session = mSessions.get(sessionId);
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index fa535c3..682de0d 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -925,7 +925,7 @@
final int targetPackageUid = snapshot.getPackageUid(packageName, 0, userId);
final boolean isUpdate = targetPackageUid != -1 || isApexSession();
final InstallSourceInfo existingInstallSourceInfo = isUpdate
- ? snapshot.getInstallSourceInfo(packageName)
+ ? snapshot.getInstallSourceInfo(packageName, userId)
: null;
final String existingInstallerPackageName = existingInstallSourceInfo != null
? existingInstallSourceInfo.getInstallingPackageName()
@@ -1135,8 +1135,13 @@
info.userId = userId;
info.installerPackageName = mInstallSource.mInstallerPackageName;
info.installerAttributionTag = mInstallSource.mInstallerAttributionTag;
- info.resolvedBaseCodePath = (mResolvedBaseFile != null) ?
- mResolvedBaseFile.getAbsolutePath() : null;
+ if (mContext.checkCallingOrSelfPermission(
+ Manifest.permission.READ_INSTALLED_SESSION_PATHS)
+ == PackageManager.PERMISSION_GRANTED && mResolvedBaseFile != null) {
+ info.resolvedBaseCodePath = mResolvedBaseFile.getAbsolutePath();
+ } else {
+ info.resolvedBaseCodePath = null;
+ }
info.progress = progress;
info.sealed = mSealed;
info.isCommitted = isCommitted();
@@ -2763,11 +2768,6 @@
: PackageInstaller.ACTION_CONFIRM_INSTALL);
intent.setPackage(mPm.getPackageInstallerPackageName());
intent.putExtra(PackageInstaller.EXTRA_SESSION_ID, sessionId);
- synchronized (mLock) {
- intent.putExtra(PackageInstaller.EXTRA_RESOLVED_BASE_PATH,
- mResolvedBaseFile != null ? mResolvedBaseFile.getAbsolutePath() : null);
- }
-
sendOnUserActionRequired(mContext, target, sessionId, intent);
}
@@ -4093,16 +4093,18 @@
return params.installFlags;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_INSTALLER_V2)
@Override
public DataLoaderParamsParcel getDataLoaderParams() {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null);
+ getDataLoaderParams_enforcePermission();
return params.dataLoaderParams != null ? params.dataLoaderParams.getData() : null;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_INSTALLER_V2)
@Override
public void addFile(int location, String name, long lengthBytes, byte[] metadata,
byte[] signature) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null);
+ addFile_enforcePermission();
if (!isDataLoaderInstallation()) {
throw new IllegalStateException(
"Cannot add files to non-data loader installation session.");
@@ -4133,9 +4135,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.USE_INSTALLER_V2)
@Override
public void removeFile(int location, String name) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.USE_INSTALLER_V2, null);
+ removeFile_enforcePermission();
if (!isDataLoaderInstallation()) {
throw new IllegalStateException(
"Cannot add files to non-data loader installation session.");
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 55662927..659bb44 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -188,6 +188,7 @@
import com.android.modules.utils.TypedXmlPullParser;
import com.android.modules.utils.TypedXmlSerializer;
import com.android.permission.persistence.RuntimePermissionsPersistence;
+import com.android.permission.persistence.RuntimePermissionsState;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
import com.android.server.LocalManagerRegistry;
@@ -1329,7 +1330,8 @@
throw new ParcelableException(new PackageManager.NameNotFoundException(packageName));
}
- final InstallSourceInfo installSourceInfo = snapshot.getInstallSourceInfo(packageName);
+ final InstallSourceInfo installSourceInfo = snapshot.getInstallSourceInfo(packageName,
+ userId);
final String installerPackageName;
if (installSourceInfo != null) {
if (!TextUtils.isEmpty(installSourceInfo.getInitiatingPackageName())) {
@@ -2563,7 +2565,7 @@
if (best == null || cur.priority > best.priority) {
if (computer.isComponentEffectivelyEnabled(cur.getComponentInfo(),
- UserHandle.USER_SYSTEM)) {
+ UserHandle.SYSTEM)) {
best = cur;
} else {
Slog.w(TAG, "Domain verification agent found but not enabled");
@@ -4656,11 +4658,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CLEAR_APP_USER_DATA)
@Override
public void clearApplicationUserData(final String packageName,
final IPackageDataObserver observer, final int userId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CLEAR_APP_USER_DATA, null);
+ clearApplicationUserData_enforcePermission();
final int callingUid = Binder.getCallingUid();
final Computer snapshot = snapshotComputer();
@@ -4732,10 +4734,10 @@
});
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
@Override
public void clearCrossProfileIntentFilters(int sourceUserId, String ownerPackage) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ clearCrossProfileIntentFilters_enforcePermission();
final int callingUid = Binder.getCallingUid();
final Computer snapshot = snapshotComputer();
enforceOwnerRights(snapshot, ownerPackage, callingUid);
@@ -4747,13 +4749,13 @@
scheduleWritePackageRestrictions(sourceUserId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL)
@Override
public boolean removeCrossProfileIntentFilter(IntentFilter intentFilter,
String ownerPackage,
int sourceUserId,
int targetUserId, int flags) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, null);
+ removeCrossProfileIntentFilter_enforcePermission();
final int callingUid = Binder.getCallingUid();
enforceOwnerRights(snapshotComputer(), ownerPackage, callingUid);
mUserManager.enforceCrossProfileIntentFilterAccess(sourceUserId, targetUserId,
@@ -4924,11 +4926,11 @@
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CLEAR_APP_CACHE)
@Override
public void freeStorage(final String volumeUuid, final long freeStorageSize,
final @StorageManager.AllocateFlags int flags, final IntentSender pi) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CLEAR_APP_CACHE, TAG);
+ freeStorage_enforcePermission();
mHandler.post(() -> {
boolean success = false;
try {
@@ -4951,11 +4953,11 @@
});
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.CLEAR_APP_CACHE)
@Override
public void freeStorageAndNotify(final String volumeUuid, final long freeStorageSize,
final @StorageManager.AllocateFlags int flags, final IPackageDataObserver observer) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.CLEAR_APP_CACHE, null);
+ freeStorageAndNotify_enforcePermission();
mHandler.post(() -> {
boolean success = false;
try {
@@ -5040,10 +5042,10 @@
return token;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_INSTANT_APPS)
@Override
public String getInstantAppAndroidId(String packageName, int userId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_INSTANT_APPS, "getInstantAppAndroidId");
+ getInstantAppAndroidId_enforcePermission();
final Computer snapshot = snapshotComputer();
snapshot.enforceCrossUserPermission(Binder.getCallingUid(), userId,
true /* requireFullPermission */, false /* checkShell */,
@@ -5135,16 +5137,17 @@
return getMimeGroupInternal(snapshot, packageName, mimeGroup);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public int getMoveStatus(int moveId) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+ getMoveStatus_enforcePermission();
return mMoveCallbacks.mLastStatus.get(moveId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.GET_APP_METADATA)
@Override
public ParcelFileDescriptor getAppMetadataFd(String packageName, int userId) {
- mContext.enforceCallingOrSelfPermission(GET_APP_METADATA, "getAppMetadataFd");
+ getAppMetadataFd_enforcePermission();
final int callingUid = Binder.getCallingUid();
final Computer snapshot = snapshotComputer();
final PackageStateInternal ps = snapshot.getPackageStateForInstalledAndFiltered(
@@ -5241,11 +5244,10 @@
packageNames, userId, callingUid);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.PACKAGE_VERIFICATION_AGENT)
@Override
public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.PACKAGE_VERIFICATION_AGENT,
- "Only package verification agents can read the verifier device identity");
+ getVerifierDeviceIdentity_enforcePermission();
synchronized (mLock) {
return mSettings.getVerifierDeviceIdentityLPw(mLiveComputer);
@@ -5267,10 +5269,10 @@
false /*direct*/, false /* retainOnUpdate */);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MAKE_UID_VISIBLE)
@Override
public void makeUidVisible(int recipientUid, int visibleUid) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.MAKE_UID_VISIBLE, "makeUidVisible");
+ makeUidVisible_enforcePermission();
final int callingUid = Binder.getCallingUid();
final int recipientUserId = UserHandle.getUserId(recipientUid);
final int visibleUserId = UserHandle.getUserId(visibleUid);
@@ -5369,9 +5371,10 @@
processName, uid, seinfo, pid);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOVE_PACKAGE)
@Override
public int movePackage(final String packageName, final String volumeUuid) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.MOVE_PACKAGE, null);
+ movePackage_enforcePermission();
final int callingUid = Binder.getCallingUid();
final UserHandle user = new UserHandle(UserHandle.getUserId(callingUid));
@@ -5390,9 +5393,10 @@
return moveId;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOVE_PACKAGE)
@Override
public int movePrimaryStorage(String volumeUuid) throws RemoteException {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.MOVE_PACKAGE, null);
+ movePrimaryStorage_enforcePermission();
final int realMoveId = mNextMoveId.getAndIncrement();
final Bundle extras = new Bundle();
@@ -5594,10 +5598,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void registerMoveCallback(IPackageMoveObserver callback) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+ registerMoveCallback_enforcePermission();
mMoveCallbacks.register(callback);
}
@@ -5699,10 +5703,11 @@
userId, callingPackage);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_USERS)
@Override
public boolean setApplicationHiddenSettingAsUser(String packageName, boolean hidden,
int userId) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null);
+ setApplicationHiddenSettingAsUser_enforcePermission();
final int callingUid = Binder.getCallingUid();
final Computer snapshot = snapshotComputer();
snapshot.enforceCrossUserPermission(callingUid, userId, true /* requireFullPermission */,
@@ -5786,11 +5791,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.DELETE_PACKAGES)
@Override
public boolean setBlockUninstallForUser(String packageName, boolean blockUninstall,
int userId) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.DELETE_PACKAGES, null);
+ setBlockUninstallForUser_enforcePermission();
final Computer snapshot = snapshotComputer();
PackageStateInternal packageState = snapshot.getPackageStateInternal(packageName);
if (packageState != null && packageState.getPkg() != null) {
@@ -5875,10 +5880,10 @@
scheduleWritePackageRestrictions(userId);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@Override
public boolean setInstallLocation(int loc) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.WRITE_SECURE_SETTINGS,
- null);
+ setInstallLocation_enforcePermission();
if (getInstallLocation() == loc) {
return true;
}
@@ -6189,17 +6194,18 @@
state.userState(userId).setSplashScreenTheme(themeId));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.INSTALL_PACKAGES)
@Override
public void setUpdateAvailable(String packageName, boolean updateAvailable) {
- mContext.enforceCallingOrSelfPermission(Manifest.permission.INSTALL_PACKAGES, null);
+ setUpdateAvailable_enforcePermission();
commitPackageStateMutation(null, packageName, state ->
state.setUpdateAvailable(updateAvailable));
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS)
@Override
public void unregisterMoveCallback(IPackageMoveObserver callback) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS, null);
+ unregisterMoveCallback_enforcePermission();
mMoveCallbacks.unregister(callback);
}
@@ -6746,6 +6752,16 @@
}
}
+ /**
+ * Read legacy permission states for permissions migration to new permission subsystem.
+ */
+ @Override
+ public RuntimePermissionsState getLegacyPermissionsState(int userId) {
+ synchronized (mLock) {
+ return mSettings.getLegacyPermissionsState(userId);
+ }
+ }
+
@Override
@SuppressWarnings("GuardedBy")
public boolean isPermissionUpgradeNeeded(int userId) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 586e112..232ca45 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -4400,15 +4400,9 @@
pw.println(" -f: force compilation even if not needed");
pw.println(" -m: select compilation mode");
pw.println(" MODE is one of the dex2oat compiler filters:");
- pw.println(" assume-verified");
- pw.println(" extract");
pw.println(" verify");
- pw.println(" quicken");
- pw.println(" space-profile");
- pw.println(" space");
pw.println(" speed-profile");
pw.println(" speed");
- pw.println(" everything");
pw.println(" -r: select compilation reason");
pw.println(" REASON is one of:");
for (int i = 0; i < PackageManagerServiceCompilerMapping.REASON_STRINGS.length; i++) {
diff --git a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
index d160740..5312ae6 100644
--- a/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
+++ b/services/core/java/com/android/server/pm/ReconcilePackageUtils.java
@@ -69,7 +69,6 @@
for (InstallRequest installRequest : installRequests) {
installRequest.onReconcileStarted();
- final String installPackageName = installRequest.getParsedPackage().getPackageName();
// add / replace existing with incoming packages
combinedPackages.put(installRequest.getScannedPackageSetting().getPackageName(),
@@ -84,12 +83,17 @@
incomingSharedLibraries, info)) {
throw ReconcileFailure.ofInternalError(
"Shared Library " + info.getName()
- + " is being installed twice in this set!",
+ + " is being installed twice in this set!",
PackageManagerException.INTERNAL_ERROR_SHARED_LIB_INSTALLED_TWICE);
}
}
}
+ }
+ for (InstallRequest installRequest : installRequests) {
+ final String installPackageName = installRequest.getParsedPackage().getPackageName();
+ final List<SharedLibraryInfo> allowedSharedLibInfos =
+ sharedLibraries.getAllowedSharedLibInfos(installRequest);
final DeletePackageAction deletePackageAction;
// we only want to try to delete for non system apps
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 7703601..65e93fa 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -3292,6 +3292,11 @@
mPackages, mSharedUsers, getUserRuntimePermissionsFile(userId));
}
+ RuntimePermissionsState getLegacyPermissionsState(@UserIdInt int userId) {
+ return mRuntimePermissionsPersistence.getLegacyPermissionsState(
+ userId, mPackages, mSharedUsers);
+ }
+
void applyDefaultPreferredAppsLPw(int userId) {
// First pull data from any pre-installed apps.
final PackageManagerInternal pmInternal =
@@ -5726,44 +5731,16 @@
Runnable writer = () -> {
boolean isLegacyPermissionStateStale = mIsLegacyPermissionStateStale.getAndSet(
false);
+ Map<String, List<RuntimePermissionsState.PermissionState>> packagePermissions;
+ Map<String, List<RuntimePermissionsState.PermissionState>> sharedUserPermissions;
- final Map<String, List<RuntimePermissionsState.PermissionState>>
- packagePermissions = new ArrayMap<>();
- final Map<String, List<RuntimePermissionsState.PermissionState>>
- sharedUserPermissions = new ArrayMap<>();
synchronized (pmLock) {
if (sync || isLegacyPermissionStateStale) {
legacyPermissionDataProvider.writeLegacyPermissionStateTEMP();
}
- int packagesSize = packageStates.size();
- for (int i = 0; i < packagesSize; i++) {
- String packageName = packageStates.keyAt(i);
- PackageStateInternal packageState = packageStates.valueAt(i);
- if (!packageState.hasSharedUser()) {
- List<RuntimePermissionsState.PermissionState> permissions =
- getPermissionsFromPermissionsState(
- packageState.getLegacyPermissionState(), userId);
- if (permissions.isEmpty()
- && !packageState.isInstallPermissionsFixed()) {
- // Storing an empty state means the package is known to the
- // system and its install permissions have been granted and fixed.
- // If this is not the case, we should not store anything.
- continue;
- }
- packagePermissions.put(packageName, permissions);
- }
- }
-
- final int sharedUsersSize = sharedUsers.size();
- for (int i = 0; i < sharedUsersSize; i++) {
- String sharedUserName = sharedUsers.keyAt(i);
- SharedUserSetting sharedUserSetting = sharedUsers.valueAt(i);
- List<RuntimePermissionsState.PermissionState> permissions =
- getPermissionsFromPermissionsState(
- sharedUserSetting.getLegacyPermissionState(), userId);
- sharedUserPermissions.put(sharedUserName, permissions);
- }
+ packagePermissions = getPackagePermissions(userId, packageStates);
+ sharedUserPermissions = getShareUsersPermissions(userId, sharedUsers);
}
synchronized (mLock) {
int version = mVersions.get(userId, INITIAL_VERSION);
@@ -5791,6 +5768,68 @@
}
}
+ @NonNull
+ RuntimePermissionsState getLegacyPermissionsState(int userId,
+ @NonNull WatchedArrayMap<String, ? extends PackageStateInternal> packageStates,
+ @NonNull WatchedArrayMap<String, SharedUserSetting> sharedUsers) {
+ int version;
+ String fingerprint;
+ synchronized (mLock) {
+ version = mVersions.get(userId, INITIAL_VERSION);
+ fingerprint = mFingerprints.get(userId);
+ }
+
+ return new RuntimePermissionsState(
+ version, fingerprint, getPackagePermissions(userId, packageStates),
+ getShareUsersPermissions(userId, sharedUsers));
+ }
+
+ @NonNull
+ private Map<String, List<RuntimePermissionsState.PermissionState>> getPackagePermissions(
+ int userId,
+ @NonNull WatchedArrayMap<String, ? extends PackageStateInternal> packageStates) {
+ final Map<String, List<RuntimePermissionsState.PermissionState>>
+ packagePermissions = new ArrayMap<>();
+
+ final int packagesSize = packageStates.size();
+ for (int i = 0; i < packagesSize; i++) {
+ String packageName = packageStates.keyAt(i);
+ PackageStateInternal packageState = packageStates.valueAt(i);
+ if (!packageState.hasSharedUser()) {
+ List<RuntimePermissionsState.PermissionState> permissions =
+ getPermissionsFromPermissionsState(
+ packageState.getLegacyPermissionState(), userId);
+ if (permissions.isEmpty()
+ && !packageState.isInstallPermissionsFixed()) {
+ // Storing an empty state means the package is known to the
+ // system and its install permissions have been granted and fixed.
+ // If this is not the case, we should not store anything.
+ continue;
+ }
+ packagePermissions.put(packageName, permissions);
+ }
+ }
+ return packagePermissions;
+ }
+
+ @NonNull
+ private Map<String, List<RuntimePermissionsState.PermissionState>> getShareUsersPermissions(
+ int userId, @NonNull WatchedArrayMap<String, SharedUserSetting> sharedUsers) {
+ final Map<String, List<RuntimePermissionsState.PermissionState>>
+ sharedUserPermissions = new ArrayMap<>();
+
+ final int sharedUsersSize = sharedUsers.size();
+ for (int i = 0; i < sharedUsersSize; i++) {
+ String sharedUserName = sharedUsers.keyAt(i);
+ SharedUserSetting sharedUserSetting = sharedUsers.valueAt(i);
+ List<RuntimePermissionsState.PermissionState> permissions =
+ getPermissionsFromPermissionsState(
+ sharedUserSetting.getLegacyPermissionState(), userId);
+ sharedUserPermissions.put(sharedUserName, permissions);
+ }
+ return sharedUserPermissions;
+ }
+
private void writePendingStates() {
while (true) {
final RuntimePermissionsState runtimePermissions;
diff --git a/services/core/java/com/android/server/pm/StorageEventHelper.java b/services/core/java/com/android/server/pm/StorageEventHelper.java
index 7684a49..8f8f437 100644
--- a/services/core/java/com/android/server/pm/StorageEventHelper.java
+++ b/services/core/java/com/android/server/pm/StorageEventHelper.java
@@ -159,8 +159,8 @@
synchronized (mPm.mInstallLock) {
final AndroidPackage pkg;
try {
- pkg = installPackageHelper.scanSystemPackageTracedLI(
- ps.getPath(), parseFlags, SCAN_INITIAL, null);
+ pkg = installPackageHelper.initPackageTracedLI(
+ ps.getPath(), parseFlags, SCAN_INITIAL);
loaded.add(pkg);
} catch (PackageManagerException e) {
diff --git a/services/core/java/com/android/server/pm/SuspendPackageHelper.java b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
index 18eebe4..b4b8cb2 100644
--- a/services/core/java/com/android/server/pm/SuspendPackageHelper.java
+++ b/services/core/java/com/android/server/pm/SuspendPackageHelper.java
@@ -619,10 +619,10 @@
final Bundle extras = new Bundle(3);
extras.putStringArray(Intent.EXTRA_CHANGED_PACKAGE_LIST, pkgList);
extras.putIntArray(Intent.EXTRA_CHANGED_UID_LIST, uidList);
+ final int flags = Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND;
handler.post(() -> mBroadcastHelper.sendPackageBroadcast(intent, null /* pkg */,
- extras, Intent.FLAG_RECEIVER_REGISTERED_ONLY, null /* targetPkg */,
- null /* finishedReceiver */, new int[]{userId}, null /* instantUserIds */,
- null /* broadcastAllowList */,
+ extras, flags, null /* targetPkg */, null /* finishedReceiver */,
+ new int[]{userId}, null /* instantUserIds */, null /* broadcastAllowList */,
(callingUid, intentExtras) -> BroadcastHelper.filterExtrasChangedPackageList(
mPm.snapshotComputer(), callingUid, intentExtras),
null /* bOptions */));
diff --git a/services/core/java/com/android/server/pm/UserManagerInternal.java b/services/core/java/com/android/server/pm/UserManagerInternal.java
index 721ad88..194f237 100644
--- a/services/core/java/com/android/server/pm/UserManagerInternal.java
+++ b/services/core/java/com/android/server/pm/UserManagerInternal.java
@@ -506,15 +506,14 @@
*
* <p>If the user is a profile and is running, it's assigned to its parent display.
*/
- // TODO(b/272366483) rename this method to avoid confusion with getDisplaysAssignedTOUser().
- public abstract int getDisplayAssignedToUser(@UserIdInt int userId);
+ public abstract int getMainDisplayAssignedToUser(@UserIdInt int userId);
/**
* Returns all display ids assigned to the user including {@link
* #assignUserToExtraDisplay(int, int) extra displays}, or {@code null} if there is no display
* assigned to the specified user.
*
- * <p>Note that this method is different from {@link #getDisplayAssignedToUser(int)}, which
+ * <p>Note that this method is different from {@link #getMainDisplayAssignedToUser(int)}, which
* returns a main display only.
*/
public abstract @Nullable int[] getDisplaysAssignedToUser(@UserIdInt int userId);
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 1a3e1d4..c10820a 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1275,7 +1275,7 @@
intent.putExtra(Intent.EXTRA_USER_HANDLE, profileHandle.getIdentifier());
getDevicePolicyManagerInternal().broadcastIntentToManifestReceivers(
intent, parentHandle, /* requiresPermission= */ true);
- intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
+ intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY | Intent.FLAG_RECEIVER_FOREGROUND);
mContext.sendBroadcastAsUser(intent, parentHandle);
}
@@ -1996,10 +1996,10 @@
}
@Override
- public int getDisplayIdAssignedToUser() {
+ public int getMainDisplayIdAssignedToUser() {
// Not checking for any permission as it returns info about calling user
int userId = UserHandle.getUserId(Binder.getCallingUid());
- int displayId = mUserVisibilityMediator.getDisplayAssignedToUser(userId);
+ int displayId = mUserVisibilityMediator.getMainDisplayAssignedToUser(userId);
return displayId;
}
@@ -4754,9 +4754,9 @@
UserManager.USER_OPERATION_ERROR_MAX_USERS);
}
// Keep logic in sync with getRemainingCreatableUserCount()
- if (!isGuest && !isProfile && !isDemo && isUserLimitReached()) {
+ if (!isGuest && !isManagedProfile && !isDemo && isUserLimitReached()) {
// If the user limit has been reached, we cannot add a user (except guest/demo).
- // Note that profiles can bypass it in certain circumstances (taken
+ // Note that managed profiles can bypass it in certain circumstances (taken
// into account in the profile check below).
throwCheckedUserOperationException(
"Cannot add user. Maximum user limit is reached.",
@@ -7174,8 +7174,8 @@
}
@Override
- public int getDisplayAssignedToUser(@UserIdInt int userId) {
- return mUserVisibilityMediator.getDisplayAssignedToUser(userId);
+ public int getMainDisplayAssignedToUser(@UserIdInt int userId) {
+ return mUserVisibilityMediator.getMainDisplayAssignedToUser(userId);
}
@Override
diff --git a/services/core/java/com/android/server/pm/UserVisibilityMediator.java b/services/core/java/com/android/server/pm/UserVisibilityMediator.java
index 3710af6..cf82536 100644
--- a/services/core/java/com/android/server/pm/UserVisibilityMediator.java
+++ b/services/core/java/com/android/server/pm/UserVisibilityMediator.java
@@ -774,9 +774,9 @@
}
/**
- * See {@link UserManagerInternal#getDisplayAssignedToUser(int)}.
+ * See {@link UserManagerInternal#getMainDisplayAssignedToUser(int)}.
*/
- public int getDisplayAssignedToUser(@UserIdInt int userId) {
+ public int getMainDisplayAssignedToUser(@UserIdInt int userId) {
if (isCurrentUserOrRunningProfileOfCurrentUser(userId)) {
if (mVisibleBackgroundUserOnDefaultDisplayEnabled) {
// When device supports visible bg users on default display, the default display is
@@ -787,8 +787,8 @@
}
if (userStartedOnDefaultDisplay != USER_NULL) {
if (DBG) {
- Slogf.d(TAG, "getDisplayAssignedToUser(%d): returning INVALID_DISPLAY for "
- + "current user user %d was started on DEFAULT_DISPLAY",
+ Slogf.d(TAG, "getMainDisplayAssignedToUser(%d): returning INVALID_DISPLAY "
+ + "for current user user %d was started on DEFAULT_DISPLAY",
userId, userStartedOnDefaultDisplay);
}
return INVALID_DISPLAY;
@@ -809,7 +809,7 @@
/** See {@link UserManagerInternal#getDisplaysAssignedToUser(int)}. */
@Nullable
public int[] getDisplaysAssignedToUser(@UserIdInt int userId) {
- int mainDisplayId = getDisplayAssignedToUser(userId);
+ int mainDisplayId = getMainDisplayAssignedToUser(userId);
if (mainDisplayId == INVALID_DISPLAY) {
// The user will not have any extra displays if they have no main display.
// Return null if no display is assigned to the user.
diff --git a/services/core/java/com/android/server/pm/VerifyingSession.java b/services/core/java/com/android/server/pm/VerifyingSession.java
index 5b967ec..f340f93 100644
--- a/services/core/java/com/android/server/pm/VerifyingSession.java
+++ b/services/core/java/com/android/server/pm/VerifyingSession.java
@@ -26,7 +26,6 @@
import static android.content.pm.SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V4;
import static android.os.PowerWhitelistManager.REASON_PACKAGE_VERIFIER;
import static android.os.PowerWhitelistManager.TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED;
-import static android.os.Process.SYSTEM_UID;
import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
import static com.android.server.pm.PackageManagerService.CHECK_PENDING_INTEGRITY_VERIFICATION;
@@ -408,7 +407,7 @@
final int numRequiredVerifierPackages = requiredVerifierPackages.size();
for (int i = numRequiredVerifierPackages - 1; i >= 0; i--) {
if (!snapshot.isApplicationEffectivelyEnabled(requiredVerifierPackages.get(i),
- SYSTEM_UID)) {
+ verifierUser)) {
Slog.w(TAG,
"Required verifier: " + requiredVerifierPackages.get(i) + " is disabled");
requiredVerifierPackages.remove(i);
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index b56e5c9..572e13c 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -389,13 +389,11 @@
return oneTimePermissionUserManager;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS)
@Override
public void startOneTimePermissionSession(String packageName, @UserIdInt int userId,
long timeoutMillis, long revokeAfterKilledDelayMillis) {
- mContext.enforceCallingOrSelfPermission(
- Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS,
- "Must hold " + Manifest.permission.MANAGE_ONE_TIME_PERMISSION_SESSIONS
- + " to register permissions as one time.");
+ startOneTimePermissionSession_enforcePermission();
Objects.requireNonNull(packageName);
final long token = Binder.clearCallingIdentity();
diff --git a/services/core/java/com/android/server/pm/permission/PermissionMigrationHelperImpl.java b/services/core/java/com/android/server/pm/permission/PermissionMigrationHelperImpl.java
index 1282b6a..60ac0b0 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionMigrationHelperImpl.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionMigrationHelperImpl.java
@@ -18,11 +18,9 @@
import android.annotation.NonNull;
import android.content.pm.PackageManagerInternal;
-import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.Log;
-import com.android.permission.persistence.RuntimePermissionsPersistence;
import com.android.permission.persistence.RuntimePermissionsState;
import com.android.server.LocalManagerRegistry;
import com.android.server.LocalServices;
@@ -81,15 +79,12 @@
*/
@NonNull
public Map<Integer, Map<String, LegacyPermissionState>> getLegacyPermissionStates(int userId) {
- RuntimePermissionsPersistence legacyPersistence =
- RuntimePermissionsPersistence.createInstance();
+ PackageManagerInternal mPackageManagerInternal =
+ LocalServices.getService(PackageManagerInternal.class);
Map<Integer, Map<String, LegacyPermissionState>> appIdPermissionStates = new ArrayMap<>();
- RuntimePermissionsState legacyState = legacyPersistence.readForUser(UserHandle.of(userId));
- if (legacyState == null) {
- return appIdPermissionStates;
- }
-
+ RuntimePermissionsState legacyState =
+ mPackageManagerInternal.getLegacyPermissionsState(userId);
PackageManagerLocal packageManagerLocal =
LocalManagerRegistry.getManager(PackageManagerLocal.class);
diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
index c0d71ac..579d4e3 100644
--- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING
+++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING
@@ -26,10 +26,10 @@
]
},
{
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.RestrictedPermissionsTest"
+ "include-filter": "android.permissionpolicy.cts.RestrictedPermissionsTest"
},
{
"include-filter": "android.permission.cts.PermissionMaxSdkVersionTest"
diff --git a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
index 8d7f782..3644054 100644
--- a/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
+++ b/services/core/java/com/android/server/policy/DeviceStateProviderImpl.java
@@ -21,7 +21,10 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.BroadcastReceiver;
import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
@@ -101,8 +104,10 @@
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_DISABLE_WHEN_THERMAL_STATUS_CRITICAL =
- "FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL";
+ 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";
/** Interface that allows reading the device state configuration. */
interface ReadableConfig {
@@ -162,9 +167,12 @@
case FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP:
flags |= DeviceState.FLAG_CANCEL_WHEN_REQUESTER_NOT_ON_TOP;
break;
- case FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL:
- flags |= DeviceState.FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL;
+ 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);
@@ -210,6 +218,9 @@
@GuardedBy("mLock")
private @PowerManager.ThermalStatus int mThermalStatus = PowerManager.THERMAL_STATUS_NONE;
+ @GuardedBy("mLock")
+ private boolean mPowerSaveModeEnabled;
+
private DeviceStateProviderImpl(@NonNull Context context,
@NonNull List<DeviceState> deviceStates,
@NonNull List<Conditions> stateConditions) {
@@ -224,14 +235,32 @@
setStateConditions(deviceStates, stateConditions);
- // 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(deviceStates)) {
- PowerManager powerManager = context.getSystemService(PowerManager.class);
- if (powerManager != null) {
+ PowerManager powerManager = context.getSystemService(PowerManager.class);
+ if (powerManager != null) {
+ // 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(deviceStates)) {
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(deviceStates)) {
+ IntentFilter filter = new IntentFilter(
+ PowerManager.ACTION_POWER_SAVE_MODE_CHANGED_INTERNAL);
+ BroadcastReceiver receiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
+ if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED_INTERNAL.equals(
+ intent.getAction())) {
+ onPowerSaveModeChanged(powerManager.isPowerSaveMode());
+ }
+ }
+ };
+ mContext.registerReceiver(receiver, filter);
+ }
}
}
@@ -382,7 +411,11 @@
for (DeviceState deviceState : mOrderedStates) {
if (isThermalStatusCriticalOrAbove(mThermalStatus)
&& deviceState.hasFlag(
- DeviceState.FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL)) {
+ DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) {
+ continue;
+ }
+ if (mPowerSaveModeEnabled && deviceState.hasFlag(
+ DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE)) {
continue;
}
supportedStates.add(deviceState);
@@ -674,6 +707,18 @@
}
}
+ @VisibleForTesting
+ void onPowerSaveModeChanged(boolean isPowerSaveModeEnabled) {
+ synchronized (mLock) {
+ if (mPowerSaveModeEnabled != isPowerSaveModeEnabled) {
+ mPowerSaveModeEnabled = isPowerSaveModeEnabled;
+ notifySupportedStatesChanged(
+ isPowerSaveModeEnabled ? SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_ENABLED
+ : SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_DISABLED);
+ }
+ }
+ }
+
@Override
public void onThermalStatusChanged(@PowerManager.ThermalStatus int thermalStatus) {
int previousThermalStatus;
@@ -709,7 +754,16 @@
private static boolean hasThermalSensitiveState(List<DeviceState> deviceStates) {
for (DeviceState state : deviceStates) {
- if (state.hasFlag(DeviceState.FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL)) {
+ if (state.hasFlag(DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ 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)) {
return true;
}
}
diff --git a/services/core/java/com/android/server/policy/GlobalActions.java b/services/core/java/com/android/server/policy/GlobalActions.java
index e146135..76a714c 100644
--- a/services/core/java/com/android/server/policy/GlobalActions.java
+++ b/services/core/java/com/android/server/policy/GlobalActions.java
@@ -93,7 +93,8 @@
mGlobalActionsAvailable = available;
if (mShowing && !mGlobalActionsAvailable) {
// Global actions provider died but we need to be showing global actions still, show the
- // legacy global acrions provider.
+ // legacy global actions provider and remove timeout callbacks to avoid legacy re-show.
+ mHandler.removeCallbacks(mShowTimeout);
ensureLegacyCreated();
mLegacyGlobalActions.showDialog(mKeyguardShowing, mDeviceProvisioned);
}
diff --git a/services/core/java/com/android/server/policy/PhoneWindowManager.java b/services/core/java/com/android/server/policy/PhoneWindowManager.java
index 5ce3437..2598758 100644
--- a/services/core/java/com/android/server/policy/PhoneWindowManager.java
+++ b/services/core/java/com/android/server/policy/PhoneWindowManager.java
@@ -1572,7 +1572,9 @@
private void interceptScreenshotChord(int source, long pressDelay) {
mHandler.removeMessages(MSG_SCREENSHOT_CHORD);
- mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SCREENSHOT_CHORD, source),
+ // arg2 is unused, but necessary to insure we call the correct method signature
+ // since the screenshot source is read from message.arg1
+ mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_SCREENSHOT_CHORD, source, 0),
pressDelay);
}
@@ -3218,6 +3220,13 @@
}
}
break;
+ case KeyEvent.KEYCODE_LANGUAGE_SWITCH:
+ if (down && repeatCount == 0) {
+ int direction = (metaState & KeyEvent.META_SHIFT_MASK) != 0 ? -1 : 1;
+ sendSwitchKeyboardLayout(event, direction);
+ return key_consumed;
+ }
+ break;
case KeyEvent.KEYCODE_SPACE:
// Handle keyboard layout switching. (META + SPACE)
if ((metaState & KeyEvent.META_META_MASK) == 0) {
@@ -3285,6 +3294,12 @@
Slog.wtf(TAG, "KEYCODE_STYLUS_BUTTON_* should be handled in"
+ " interceptKeyBeforeQueueing");
return key_consumed;
+ case KeyEvent.KEYCODE_MACRO_1:
+ case KeyEvent.KEYCODE_MACRO_2:
+ case KeyEvent.KEYCODE_MACRO_3:
+ case KeyEvent.KEYCODE_MACRO_4:
+ Slog.wtf(TAG, "KEYCODE_MACRO_x should be handled in interceptKeyBeforeQueueing");
+ return key_consumed;
}
if (isValidGlobalKey(keyCode)
@@ -3583,16 +3598,16 @@
mPendingKeyguardOccluded = occluded;
mKeyguardOccludedChanged = true;
} else {
- setKeyguardOccludedLw(occluded, true /* notify */);
+ setKeyguardOccludedLw(occluded);
}
}
@Override
- public int applyKeyguardOcclusionChange(boolean notify) {
+ public int applyKeyguardOcclusionChange() {
if (mKeyguardOccludedChanged) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "transition/occluded changed occluded="
+ mPendingKeyguardOccluded);
- if (setKeyguardOccludedLw(mPendingKeyguardOccluded, notify)) {
+ if (setKeyguardOccludedLw(mPendingKeyguardOccluded)) {
return FINISH_LAYOUT_REDO_LAYOUT | FINISH_LAYOUT_REDO_WALLPAPER;
}
}
@@ -3611,8 +3626,10 @@
*/
private int handleTransitionForKeyguardLw(boolean startKeyguardExitAnimation,
boolean notifyOccluded) {
- final int redoLayout = applyKeyguardOcclusionChange(notifyOccluded);
- if (redoLayout != 0) return redoLayout;
+ if (notifyOccluded) {
+ final int redoLayout = applyKeyguardOcclusionChange();
+ if (redoLayout != 0) return redoLayout;
+ }
if (startKeyguardExitAnimation) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "Starting keyguard exit animation");
startKeyguardExitAnimation(SystemClock.uptimeMillis());
@@ -3863,20 +3880,16 @@
}
/**
- * Updates the occluded state of the Keyguard.
+ * Updates the occluded state of the Keyguard immediately via
+ * {@link com.android.internal.policy.IKeyguardService}.
*
* @param isOccluded Whether the Keyguard is occluded by another window.
- * @param notify Notify keyguard occlude status change immediately via
- * {@link com.android.internal.policy.IKeyguardService}.
* @return Whether the flags have changed and we have to redo the layout.
*/
- private boolean setKeyguardOccludedLw(boolean isOccluded, boolean notify) {
+ private boolean setKeyguardOccludedLw(boolean isOccluded) {
if (DEBUG_KEYGUARD) Slog.d(TAG, "setKeyguardOccluded occluded=" + isOccluded);
mKeyguardOccludedChanged = false;
- if (isKeyguardOccluded() == isOccluded) {
- return false;
- }
- mKeyguardDelegate.setOccluded(isOccluded, notify);
+ mKeyguardDelegate.setOccluded(isOccluded, true /* notify */);
return mKeyguardDelegate.isShowing();
}
@@ -4424,6 +4437,13 @@
result &= ~ACTION_PASS_TO_USER;
break;
}
+ case KeyEvent.KEYCODE_MACRO_1:
+ case KeyEvent.KEYCODE_MACRO_2:
+ case KeyEvent.KEYCODE_MACRO_3:
+ case KeyEvent.KEYCODE_MACRO_4:
+ // TODO(b/266098478): Add logic to handle KEYCODE_MACROx feature
+ result &= ~ACTION_PASS_TO_USER;
+ break;
}
if (useHapticFeedback) {
diff --git a/services/core/java/com/android/server/policy/TEST_MAPPING b/services/core/java/com/android/server/policy/TEST_MAPPING
index 094e70f..9f1cb1a 100644
--- a/services/core/java/com/android/server/policy/TEST_MAPPING
+++ b/services/core/java/com/android/server/policy/TEST_MAPPING
@@ -29,16 +29,16 @@
]
},
{
- "name": "CtsPermission2TestCases",
+ "name": "CtsPermissionPolicyTestCases",
"options": [
{
- "include-filter": "android.permission2.cts.RestrictedPermissionsTest"
+ "include-filter": "android.permissionpolicy.cts.RestrictedPermissionsTest"
},
{
- "include-filter": "android.permission2.cts.RestrictedStoragePermissionSharedUidTest"
+ "include-filter": "android.permissionpolicy.cts.RestrictedStoragePermissionSharedUidTest"
},
{
- "include-filter": "android.permission2.cts.RestrictedStoragePermissionTest"
+ "include-filter": "android.permissionpolicy.cts.RestrictedStoragePermissionTest"
}
]
},
diff --git a/services/core/java/com/android/server/policy/WindowManagerPolicy.java b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
index 3c4dbf2..5d558e9 100644
--- a/services/core/java/com/android/server/policy/WindowManagerPolicy.java
+++ b/services/core/java/com/android/server/policy/WindowManagerPolicy.java
@@ -170,10 +170,10 @@
void onKeyguardOccludedChangedLw(boolean occluded, boolean waitAppTransition);
/**
- * @param notify {@code true} if the status change should be immediately notified via
- * {@link com.android.internal.policy.IKeyguardService}
+ * Commit any queued changes to keyguard occlude status that had been deferred during the
+ * start of an animation or transition.
*/
- int applyKeyguardOcclusionChange(boolean notify);
+ int applyKeyguardOcclusionChange();
/**
* Interface to the Window Manager state associated with a particular
diff --git a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
index 9d5173a..86c4985 100644
--- a/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
+++ b/services/core/java/com/android/server/recoverysystem/RecoverySystemService.java
@@ -906,10 +906,11 @@
return RESUME_ON_REBOOT_REBOOT_ERROR_UNSPECIFIED;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.RECOVERY)
@Override // Binder call for the legacy rebootWithLskf
public @ResumeOnRebootRebootErrorCode int rebootWithLskfAssumeSlotSwitch(String packageName,
String reason) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
+ rebootWithLskfAssumeSlotSwitch_enforcePermission();
return rebootWithLskfImpl(packageName, reason, true);
}
@@ -970,9 +971,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.RECOVERY)
@Override
public boolean allocateSpaceForUpdate(String packageFile) {
- mContext.enforceCallingOrSelfPermission(android.Manifest.permission.RECOVERY, null);
+ allocateSpaceForUpdate_enforcePermission();
if (!isUpdatableApexSupported()) {
Log.i(TAG, "Updatable Apex not supported, "
+ "allocateSpaceForUpdate does nothing.");
diff --git a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
index 3d8f538..5340013 100644
--- a/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
+++ b/services/core/java/com/android/server/stats/pull/StatsPullAtomService.java
@@ -171,6 +171,8 @@
import android.util.SparseIntArray;
import android.util.StatsEvent;
import android.util.proto.ProtoOutputStream;
+import android.uwb.UwbActivityEnergyInfo;
+import android.uwb.UwbManager;
import android.view.Display;
import com.android.internal.annotations.GuardedBy;
@@ -346,6 +348,7 @@
private StorageManager mStorageManager;
private WifiManager mWifiManager;
private TelephonyManager mTelephony;
+ private UwbManager mUwbManager;
private SubscriptionManager mSubscriptionManager;
private NetworkStatsManager mNetworkStatsManager;
@@ -415,6 +418,7 @@
private final Object mWifiActivityInfoLock = new Object();
private final Object mModemActivityInfoLock = new Object();
private final Object mBluetoothActivityInfoLock = new Object();
+ private final Object mUwbActivityInfoLock = new Object();
private final Object mSystemElapsedRealtimeLock = new Object();
private final Object mSystemUptimeLock = new Object();
private final Object mProcessMemoryStateLock = new Object();
@@ -537,6 +541,10 @@
synchronized (mBluetoothActivityInfoLock) {
return pullBluetoothActivityInfoLocked(atomTag, data);
}
+ case FrameworkStatsLog.UWB_ACTIVITY_INFO:
+ synchronized (mUwbActivityInfoLock) {
+ return pullUwbActivityInfoLocked(atomTag, data);
+ }
case FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME:
synchronized (mSystemElapsedRealtimeLock) {
return pullSystemElapsedRealtimeLocked(atomTag, data);
@@ -777,8 +785,12 @@
registerEventListeners();
});
} else if (phase == PHASE_THIRD_PARTY_APPS_CAN_START) {
- // Network stats related pullers can only be initialized after service is ready.
- BackgroundThread.getHandler().post(() -> initAndRegisterNetworkStatsPullers());
+ BackgroundThread.getHandler().post(() -> {
+ // Network stats related pullers can only be initialized after service is ready.
+ initAndRegisterNetworkStatsPullers();
+ // For services that are not ready at boot phase PHASE_SYSTEM_SERVICES_READY
+ initAndRegisterDeferredPullers();
+ });
}
}
@@ -989,6 +1001,12 @@
registerOemManagedBytesTransfer();
}
+ private void initAndRegisterDeferredPullers() {
+ mUwbManager = mContext.getSystemService(UwbManager.class);
+
+ registerUwbActivityInfo();
+ }
+
private IThermalService getIThermalService() {
synchronized (mThermalLock) {
if (mThermalService == null) {
@@ -2151,6 +2169,46 @@
return StatsManager.PULL_SUCCESS;
}
+ private void registerUwbActivityInfo() {
+ int tagId = FrameworkStatsLog.UWB_ACTIVITY_INFO;
+ mStatsManager.setPullAtomCallback(
+ tagId,
+ null, // use default PullAtomMetadata values
+ DIRECT_EXECUTOR,
+ mStatsCallbackImpl
+ );
+ }
+
+ int pullUwbActivityInfoLocked(int atomTag, List<StatsEvent> pulledData) {
+ final long token = Binder.clearCallingIdentity();
+ try {
+ SynchronousResultReceiver uwbReceiver = new SynchronousResultReceiver("uwb");
+ mUwbManager.getUwbActivityEnergyInfoAsync(Runnable::run,
+ info -> {
+ Bundle bundle = new Bundle();
+ bundle.putParcelable(BatteryStats.RESULT_RECEIVER_CONTROLLER_KEY, info);
+ uwbReceiver.send(0, bundle);
+ }
+ );
+ final UwbActivityEnergyInfo uwbInfo = awaitControllerInfo(uwbReceiver);
+ if (uwbInfo == null) {
+ return StatsManager.PULL_SKIP;
+ }
+ pulledData.add(
+ FrameworkStatsLog.buildStatsEvent(atomTag,
+ uwbInfo.getControllerTxDurationMillis(),
+ uwbInfo.getControllerRxDurationMillis(),
+ uwbInfo.getControllerIdleDurationMillis(),
+ uwbInfo.getControllerWakeCount()));
+ } catch (RuntimeException e) {
+ Slog.e(TAG, "failed to getUwbActivityEnergyInfoAsync", e);
+ return StatsManager.PULL_SKIP;
+ } finally {
+ Binder.restoreCallingIdentity(token);
+ }
+ return StatsManager.PULL_SUCCESS;
+ }
+
private void registerSystemElapsedRealtime() {
int tagId = FrameworkStatsLog.SYSTEM_ELAPSED_REALTIME;
PullAtomMetadata metadata = new PullAtomMetadata.Builder()
diff --git a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
index e7c073c..965e8dd 100644
--- a/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
+++ b/services/core/java/com/android/server/timedetector/NetworkTimeUpdateService.java
@@ -21,13 +21,9 @@
import android.annotation.Nullable;
import android.annotation.RequiresPermission;
import android.app.AlarmManager;
-import android.app.PendingIntent;
import android.app.time.UnixEpochTime;
-import android.content.BroadcastReceiver;
import android.content.ContentResolver;
import android.content.Context;
-import android.content.Intent;
-import android.content.IntentFilter;
import android.database.ContentObserver;
import android.net.ConnectivityManager;
import android.net.Network;
@@ -73,10 +69,6 @@
private static final String TAG = "NetworkTimeUpdateService";
private static final boolean DBG = false;
- private static final String ACTION_POLL =
- "com.android.server.timedetector.NetworkTimeUpdateService.action.POLL";
- private static final int POLL_REQUEST = 0;
-
private final Object mLock = new Object();
private final Context mContext;
private final ConnectivityManager mCM;
@@ -113,16 +105,19 @@
AlarmManager alarmManager = mContext.getSystemService(AlarmManager.class);
TimeDetectorInternal timeDetectorInternal =
LocalServices.getService(TimeDetectorInternal.class);
- // Broadcast alarms sent by system are immutable
- Intent pollIntent = new Intent(ACTION_POLL, null).setPackage("android");
- PendingIntent pendingPollIntent = PendingIntent.getBroadcast(mContext, POLL_REQUEST,
- pollIntent, PendingIntent.FLAG_IMMUTABLE);
mRefreshCallbacks = new Engine.RefreshCallbacks() {
+ private final AlarmManager.OnAlarmListener mOnAlarmListener =
+ new ScheduledRefreshAlarmListener();
+
@Override
public void scheduleNextRefresh(@ElapsedRealtimeLong long elapsedRealtimeMillis) {
- alarmManager.cancel(pendingPollIntent);
+ alarmManager.cancel(mOnAlarmListener);
+
+ String alarmTag = "NetworkTimeUpdateService.POLL";
+ Handler handler = null; // Use the main thread
alarmManager.set(
- AlarmManager.ELAPSED_REALTIME, elapsedRealtimeMillis, pendingPollIntent);
+ AlarmManager.ELAPSED_REALTIME, elapsedRealtimeMillis, alarmTag,
+ mOnAlarmListener, handler);
}
@Override
@@ -138,10 +133,6 @@
/** Initialize the receivers and initiate the first NTP request */
public void systemRunning() {
- // Listen for scheduled refreshes.
- ScheduledRefreshBroadcastReceiver receiver = new ScheduledRefreshBroadcastReceiver();
- mContext.registerReceiver(receiver, new IntentFilter(ACTION_POLL));
-
// Listen for network connectivity changes.
NetworkConnectivityCallback networkConnectivityCallback = new NetworkConnectivityCallback();
mCM.registerDefaultNetworkCallback(networkConnectivityCallback, mHandler);
@@ -214,13 +205,13 @@
}
}
- private class ScheduledRefreshBroadcastReceiver extends BroadcastReceiver implements Runnable {
+ private class ScheduledRefreshAlarmListener implements AlarmManager.OnAlarmListener, Runnable {
@Override
- public void onReceive(Context context, Intent intent) {
- // The BroadcastReceiver has to complete quickly or an ANR will be triggered by the
+ public void onAlarm() {
+ // The OnAlarmListener has to complete quickly or an ANR will be triggered by the
// platform regardless of the receiver thread used. Instead of blocking the receiver
- // thread, the long-running / blocking work is posted to mHandler to allow onReceive()
+ // thread, the long-running / blocking work is posted to mHandler to allow onAlarm()
// to return immediately.
mHandler.post(this);
}
diff --git a/services/core/java/com/android/server/tv/TvInputManagerService.java b/services/core/java/com/android/server/tv/TvInputManagerService.java
index 5442b6d..ad789d8 100644
--- a/services/core/java/com/android/server/tv/TvInputManagerService.java
+++ b/services/core/java/com/android/server/tv/TvInputManagerService.java
@@ -2128,7 +2128,7 @@
public void notifyTvMessage(IBinder sessionToken, int type, Bundle data, int userId) {
final int callingUid = Binder.getCallingUid();
final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
- userId, "timeShiftEnablePositionTracking");
+ userId, "notifyTvmessage");
final long identity = Binder.clearCallingIdentity();
try {
synchronized (mLock) {
@@ -2136,7 +2136,28 @@
getSessionLocked(sessionToken, callingUid, resolvedUserId)
.notifyTvMessage(type, data);
} catch (RemoteException | SessionNotFoundException e) {
- Slog.e(TAG, "error in timeShiftEnablePositionTracking", e);
+ Slog.e(TAG, "error in notifyTvMessage", e);
+ }
+ }
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ }
+
+ @Override
+ public void setTvMessageEnabled(IBinder sessionToken, int type, boolean enabled,
+ int userId) {
+ final int callingUid = Binder.getCallingUid();
+ final int resolvedUserId = resolveCallingUserId(Binder.getCallingPid(), callingUid,
+ userId, "setTvMessageEnabled");
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ synchronized (mLock) {
+ try {
+ getSessionLocked(sessionToken, callingUid, resolvedUserId)
+ .setTvMessageEnabled(type, enabled);
+ } catch (RemoteException | SessionNotFoundException e) {
+ Slog.e(TAG, "error in setTvMessageEnabled", e);
}
}
} finally {
diff --git a/services/core/java/com/android/server/vibrator/VibratorManagerService.java b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
index bf99772..350a55d 100644
--- a/services/core/java/com/android/server/vibrator/VibratorManagerService.java
+++ b/services/core/java/com/android/server/vibrator/VibratorManagerService.java
@@ -298,20 +298,18 @@
return controller.isVibratorInfoLoadSuccessful() ? info : null;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)
@Override // Binder call
public boolean isVibrating(int vibratorId) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_VIBRATOR_STATE,
- "isVibrating");
+ isVibrating_enforcePermission();
VibratorController controller = mVibrators.get(vibratorId);
return controller != null && controller.isVibrating();
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)
@Override // Binder call
public boolean registerVibratorStateListener(int vibratorId, IVibratorStateListener listener) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_VIBRATOR_STATE,
- "registerVibratorStateListener");
+ registerVibratorStateListener_enforcePermission();
VibratorController controller = mVibrators.get(vibratorId);
if (controller == null) {
return false;
@@ -319,12 +317,11 @@
return controller.registerVibratorStateListener(listener);
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.ACCESS_VIBRATOR_STATE)
@Override // Binder call
public boolean unregisterVibratorStateListener(int vibratorId,
IVibratorStateListener listener) {
- mContext.enforceCallingOrSelfPermission(
- android.Manifest.permission.ACCESS_VIBRATOR_STATE,
- "unregisterVibratorStateListener");
+ unregisterVibratorStateListener_enforcePermission();
VibratorController controller = mVibrators.get(vibratorId);
if (controller == null) {
return false;
diff --git a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
index c9eef38..55060a6 100644
--- a/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
+++ b/services/core/java/com/android/server/wallpaper/WallpaperManagerService.java
@@ -90,7 +90,6 @@
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
-import android.os.storage.StorageManager;
import android.service.wallpaper.IWallpaperConnection;
import android.service.wallpaper.IWallpaperEngine;
import android.service.wallpaper.IWallpaperService;
@@ -2210,12 +2209,7 @@
public ParcelFileDescriptor getWallpaperWithFeature(String callingPkg, String callingFeatureId,
IWallpaperManagerCallback cb, final int which, Bundle outParams, int wallpaperUserId,
boolean getCropped) {
- final boolean hasPrivilege = hasPermission(READ_WALLPAPER_INTERNAL);
- if (!hasPrivilege) {
- mContext.getSystemService(StorageManager.class).checkPermissionReadImages(true,
- Binder.getCallingPid(), Binder.getCallingUid(), callingPkg, callingFeatureId);
- }
-
+ checkPermission(READ_WALLPAPER_INTERNAL);
wallpaperUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), wallpaperUserId, false, true, "getWallpaper", null);
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
index f215495..83804f7 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
+++ b/services/core/java/com/android/server/wm/AbsAppSnapshotController.java
@@ -55,8 +55,8 @@
* @param <CACHE> The basic cache for either Task or ActivityRecord
*/
abstract class AbsAppSnapshotController<TYPE extends WindowContainer,
- CACHE extends AbsAppSnapshotCache<TYPE>> {
- private static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotController" : TAG_WM;
+ CACHE extends SnapshotCache<TYPE>> {
+ static final String TAG = TAG_WITH_CLASS_NAME ? "SnapshotController" : TAG_WM;
/**
* Return value for {@link #getSnapshotMode}: We are allowed to take a real screenshot to be
* used as the snapshot.
@@ -76,7 +76,7 @@
static final int SNAPSHOT_MODE_NONE = 2;
protected final WindowManagerService mService;
- protected final float mHighResTaskSnapshotScale;
+ protected final float mHighResSnapshotScale;
private final Rect mTmpRect = new Rect();
/**
* Flag indicating whether we are running on an Android TV device.
@@ -99,12 +99,13 @@
PackageManager.FEATURE_LEANBACK);
mIsRunningOnIoT = mService.mContext.getPackageManager().hasSystemFeature(
PackageManager.FEATURE_EMBEDDED);
- mHighResTaskSnapshotScale = initSnapshotScale();
+ mHighResSnapshotScale = initSnapshotScale();
}
protected float initSnapshotScale() {
- return mService.mContext.getResources().getFloat(
+ final float config = mService.mContext.getResources().getFloat(
com.android.internal.R.dimen.config_highResTaskSnapshotScale);
+ return Math.max(Math.min(config, 1f), 0.1f);
}
/**
@@ -173,7 +174,7 @@
final HardwareBuffer buffer = snapshot.getHardwareBuffer();
if (buffer.getWidth() == 0 || buffer.getHeight() == 0) {
buffer.close();
- Slog.e(TAG, "Invalid task snapshot dimensions " + buffer.getWidth() + "x"
+ Slog.e(TAG, "Invalid snapshot dimensions " + buffer.getWidth() + "x"
+ buffer.getHeight());
return null;
} else {
@@ -223,7 +224,7 @@
Point taskSize = new Point();
Trace.traceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "createSnapshot");
final ScreenCapture.ScreenshotHardwareBuffer taskSnapshot = createSnapshot(source,
- mHighResTaskSnapshotScale, builder.getPixelFormat(), taskSize, builder);
+ mHighResSnapshotScale, builder.getPixelFormat(), taskSize, builder);
Trace.traceEnd(Trace.TRACE_TAG_WINDOW_MANAGER);
builder.setTaskSize(taskSize);
return taskSnapshot;
@@ -397,11 +398,11 @@
final SnapshotDrawerUtils.SystemBarBackgroundPainter
decorPainter = new SnapshotDrawerUtils.SystemBarBackgroundPainter(attrs.flags,
attrs.privateFlags, attrs.insetsFlags.appearance, taskDescription,
- mHighResTaskSnapshotScale, mainWindow.getRequestedVisibleTypes());
+ mHighResSnapshotScale, mainWindow.getRequestedVisibleTypes());
final int taskWidth = taskBounds.width();
final int taskHeight = taskBounds.height();
- final int width = (int) (taskWidth * mHighResTaskSnapshotScale);
- final int height = (int) (taskHeight * mHighResTaskSnapshotScale);
+ final int width = (int) (taskWidth * mHighResSnapshotScale);
+ final int height = (int) (taskHeight * mHighResSnapshotScale);
final RenderNode node = RenderNode.create("SnapshotController", null);
node.setLeftTopRightBottom(0, 0, width, height);
node.setClipToBounds(false);
@@ -450,9 +451,28 @@
return 0;
}
+ /**
+ * Called when an {@link ActivityRecord} has been removed.
+ */
+ void onAppRemoved(ActivityRecord activity) {
+ mCache.onAppRemoved(activity);
+ }
+
+ /**
+ * Called when the process of an {@link ActivityRecord} has died.
+ */
+ void onAppDied(ActivityRecord activity) {
+ mCache.onAppDied(activity);
+ }
+
+ boolean isAnimatingByRecents(@NonNull Task task) {
+ return task.isAnimatingByRecents()
+ || mService.mAtmService.getTransitionController().inRecentsTransition(task);
+ }
+
void dump(PrintWriter pw, String prefix) {
- pw.println(prefix + "mHighResTaskSnapshotScale=" + mHighResTaskSnapshotScale);
- pw.println(prefix + "mTaskSnapshotEnabled=" + mSnapshotEnabled);
+ pw.println(prefix + "mHighResSnapshotScale=" + mHighResSnapshotScale);
+ pw.println(prefix + "mSnapshotEnabled=" + mSnapshotEnabled);
mCache.dump(pw, prefix);
}
}
diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java
index 324a0ad..f5bc8ff 100644
--- a/services/core/java/com/android/server/wm/ActivityRecord.java
+++ b/services/core/java/com/android/server/wm/ActivityRecord.java
@@ -121,6 +121,7 @@
import static android.view.WindowManager.TRANSIT_CLOSE;
import static android.view.WindowManager.TRANSIT_FLAG_OPEN_BEHIND;
import static android.view.WindowManager.TRANSIT_OLD_UNSET;
+import static android.view.WindowManager.TRANSIT_RELAUNCH;
import static android.window.TransitionInfo.FLAG_IS_OCCLUDED;
import static android.window.TransitionInfo.FLAG_STARTING_WINDOW_TRANSFER_RECIPIENT;
@@ -465,7 +466,8 @@
final int launchedFromPid; // always the pid who started the activity.
final int launchedFromUid; // always the uid who started the activity.
final String launchedFromPackage; // always the package who started the activity.
- final @Nullable String launchedFromFeatureId; // always the feature in launchedFromPackage
+ @Nullable
+ final String launchedFromFeatureId; // always the feature in launchedFromPackage
private final int mLaunchSourceType; // original launch source type
final Intent intent; // the original intent that generated us
final String shortComponentName; // the short component name of the intent
@@ -731,7 +733,7 @@
/**
* Solely for reporting to ActivityMetricsLogger. Just tracks whether, the last time this
- * Actiivty was part of a syncset, all windows were ready by the time the sync was ready (vs.
+ * Activity was part of a syncset, all windows were ready by the time the sync was ready (vs.
* only the top-occluding ones). The assumption here is if some were not ready, they were
* covered with starting-window/splash-screen.
*/
@@ -4222,7 +4224,8 @@
getDisplayContent().mOpeningApps.remove(this);
getDisplayContent().mUnknownAppVisibilityController.appRemovedOrHidden(this);
- mWmService.mTaskSnapshotController.onAppRemoved(this);
+ mWmService.mSnapshotController.onAppRemoved(this);
+
mTaskSupervisor.getActivityMetricsLogger().notifyActivityRemoved(this);
mTaskSupervisor.mStoppingActivities.remove(this);
waitingToShow = false;
@@ -4357,17 +4360,6 @@
@Override
void addWindow(WindowState w) {
super.addWindow(w);
-
- boolean gotReplacementWindow = false;
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState candidate = mChildren.get(i);
- gotReplacementWindow |= candidate.setReplacementWindowIfNeeded(w);
- }
-
- // if we got a replacement window, reset the timeout to give drawing more time
- if (gotReplacementWindow) {
- mWmService.scheduleWindowReplacementTimeouts(this);
- }
checkKeyguardFlagsChanged();
}
@@ -4382,12 +4374,6 @@
updateLetterboxSurface(child);
}
- void onWindowReplacementTimeout() {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- (mChildren.get(i)).onWindowReplacementTimeout();
- }
- }
-
void setAppLayoutChanges(int changes, String reason) {
if (!mChildren.isEmpty()) {
final DisplayContent dc = getDisplayContent();
@@ -4398,15 +4384,6 @@
}
}
- void removeReplacedWindowIfNeeded(WindowState replacement) {
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState win = mChildren.get(i);
- if (win.removeReplacedWindowIfNeeded(replacement)) {
- return;
- }
- }
- }
-
private boolean transferStartingWindow(@NonNull ActivityRecord fromActivity) {
final WindowState tStartingWindow = fromActivity.mStartingWindow;
if (tStartingWindow != null && fromActivity.mStartingSurface != null) {
@@ -4769,6 +4746,10 @@
} catch (RemoteException e) {
Slog.w(TAG, "Exception thrown sending result to " + this, e);
}
+ // We return here to ensure that result for media projection setup is not stored as a
+ // pending result after being scheduled. This is to prevent this stored result being
+ // sent again when the destination component is resumed.
+ return;
}
addResultLocked(null /* from */, resultWho, requestCode, resultCode, data);
@@ -4776,7 +4757,7 @@
/**
* Provides a lifecycle item for the current stat. Only to be used when force sending an
- * activity result (as part of MeidaProjection setup). Does not support the following states:
+ * activity result (as part of MediaProjection setup). Does not support the following states:
* {@link State#INITIALIZING}, {@link State#RESTARTING_PROCESS},
* {@link State#FINISHING}, {@link State#DESTROYING}, {@link State#DESTROYED}. It does not make
* sense to force send a result to an activity in these states. Does not support
@@ -5225,7 +5206,7 @@
Slog.w(TAG_WM, "Attempted to set visibility of non-existing app token: " + token);
return;
}
- if (visible == mVisibleRequested && visible == mVisible
+ if (visible == mVisibleRequested && visible == mVisible && visible == isClientVisible()
&& mTransitionController.isShellTransitionsEnabled()) {
// For shell transition, it is no-op if there is no state change.
return;
@@ -5578,7 +5559,7 @@
&& !fromTransition) {
// Take the screenshot before possibly hiding the WSA, otherwise the screenshot
// will not be taken.
- mWmService.mTaskSnapshotController.notifyAppVisibilityChanged(this, visible);
+ mWmService.mSnapshotController.notifyAppVisibilityChanged(this, visible);
}
// If we are hidden but there is no delay needed we immediately
@@ -5633,10 +5614,7 @@
// * activity is transitioning visibility state
// * or the activity was marked as hidden and is exiting before we had a chance to play the
// transition animation
- // * or this is an opening app and windows are being replaced (e.g. freeform window to
- // normal window).
- return isVisible() != visible || mRequestForceTransition || (!isVisible() && mIsExiting)
- || (visible && forAllWindows(WindowState::waitingForReplacement, true));
+ return isVisible() != visible || mRequestForceTransition || (!isVisible() && mIsExiting);
}
/**
@@ -7380,35 +7358,6 @@
}
}
- void setWillReplaceWindows(boolean animate) {
- ProtoLog.d(WM_DEBUG_ADD_REMOVE,
- "Marking app token %s with replacing windows.", this);
-
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState w = mChildren.get(i);
- w.setWillReplaceWindow(animate);
- }
- }
-
- void setWillReplaceChildWindows() {
- ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Marking app token %s"
- + " with replacing child windows.", this);
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState w = mChildren.get(i);
- w.setWillReplaceChildWindows();
- }
- }
-
- void clearWillReplaceWindows() {
- ProtoLog.d(WM_DEBUG_ADD_REMOVE,
- "Resetting app token %s of replacing window marks.", this);
-
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState w = mChildren.get(i);
- w.clearWillReplaceWindow();
- }
- }
-
void requestUpdateWallpaperIfNeeded() {
for (int i = mChildren.size() - 1; i >= 0; i--) {
final WindowState w = mChildren.get(i);
@@ -8414,6 +8363,10 @@
* requested in the config or via an ADB command. For more context see {@link
* LetterboxUiController#getHorizontalPositionMultiplier(Configuration)} and
* {@link LetterboxUiController#getVerticalPositionMultiplier(Configuration)}
+ * <p>
+ * Note that this is the final step that can change the resolved bounds. After this method
+ * is called, the position of the bounds will be moved to app space as sandboxing if the
+ * activity has a size compat scale.
*/
private void updateResolvedBoundsPosition(Configuration newParentConfiguration) {
final Configuration resolvedConfig = getResolvedOverrideConfiguration();
@@ -8475,6 +8428,18 @@
// Since bounds has changed, the configuration needs to be computed accordingly.
getTaskFragment().computeConfigResourceOverrides(resolvedConfig, newParentConfiguration);
+
+ // The position of configuration bounds were calculated in screen space because that is
+ // easier to resolve the relative position in parent container. However, if the activity is
+ // scaled, the position should follow the scale because the configuration will be sent to
+ // the client which is expected to be in a scaled environment.
+ if (mSizeCompatScale != 1f) {
+ final int screenPosX = resolvedBounds.left;
+ final int screenPosY = resolvedBounds.top;
+ final int dx = (int) (screenPosX / mSizeCompatScale + 0.5f) - screenPosX;
+ final int dy = (int) (screenPosY / mSizeCompatScale + 0.5f) - screenPosY;
+ offsetBounds(resolvedConfig, dx, dy);
+ }
}
void recomputeConfiguration() {
@@ -9737,9 +9702,36 @@
return;
}
- if (getParent() != null) {
+ if (mTransitionController.isShellTransitionsEnabled()) {
+ final Transition transition = new Transition(TRANSIT_RELAUNCH, 0 /* flags */,
+ mTransitionController, mWmService.mSyncEngine);
+ final Runnable executeRestart = () -> {
+ if (mState != RESTARTING_PROCESS || !attachedToProcess()) {
+ transition.abort();
+ return;
+ }
+ // Request invisible so there will be a change after the activity is restarted
+ // to be visible.
+ setVisibleRequested(false);
+ transition.collect(this);
+ mTransitionController.requestStartTransition(transition, task,
+ null /* remoteTransition */, null /* displayChange */);
+ scheduleStopForRestartProcess();
+ };
+ if (mWmService.mSyncEngine.hasActiveSync()) {
+ mWmService.mSyncEngine.queueSyncSet(
+ () -> mTransitionController.moveToCollecting(transition), executeRestart);
+ } else {
+ mTransitionController.moveToCollecting(transition);
+ executeRestart.run();
+ }
+ } else {
startFreezingScreen();
+ scheduleStopForRestartProcess();
}
+ }
+
+ private void scheduleStopForRestartProcess() {
// The process will be killed until the activity reports stopped with saved state (see
// {@link ActivityTaskManagerService.activityStopped}).
try {
@@ -10518,6 +10510,18 @@
&& !inPinnedWindowingMode() && !inFreeformWindowingMode();
}
+ boolean canCaptureSnapshot() {
+ if (!isSurfaceShowing() || findMainWindow() == null) {
+ return false;
+ }
+ return forAllWindows(
+ // Ensure at least one window for the top app is visible before attempting to
+ // take a screenshot. Visible here means that the WSA surface is shown and has
+ // an alpha greater than 0.
+ ws -> ws.mWinAnimator != null && ws.mWinAnimator.getShown()
+ && ws.mWinAnimator.mLastAlpha > 0f, true /* traverseTopToBottom */);
+ }
+
void overrideCustomTransition(boolean open, int enterAnim, int exitAnim, int backgroundColor) {
CustomAppTransition transition = getCustomAnimation(open);
if (transition == null) {
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotCache.java b/services/core/java/com/android/server/wm/ActivitySnapshotCache.java
new file mode 100644
index 0000000..a54dd82
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotCache.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import android.window.TaskSnapshot;
+
+/**
+ * A snapshot cache for activity, the token is the hashCode of the activity.
+ */
+class ActivitySnapshotCache extends SnapshotCache<ActivityRecord> {
+
+ ActivitySnapshotCache(WindowManagerService service) {
+ super(service, "Activity");
+ }
+
+ @Override
+ void putSnapshot(ActivityRecord ar, TaskSnapshot snapshot) {
+ final int hasCode = System.identityHashCode(ar);
+ final CacheEntry entry = mRunningCache.get(hasCode);
+ if (entry != null) {
+ mAppIdMap.remove(entry.topApp);
+ }
+ mAppIdMap.put(ar, hasCode);
+ mRunningCache.put(hasCode, new CacheEntry(snapshot, ar));
+ }
+}
diff --git a/services/core/java/com/android/server/wm/ActivitySnapshotController.java b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
new file mode 100644
index 0000000..90a4820
--- /dev/null
+++ b/services/core/java/com/android/server/wm/ActivitySnapshotController.java
@@ -0,0 +1,505 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static com.android.server.wm.SnapshotController.ACTIVITY_CLOSE;
+import static com.android.server.wm.SnapshotController.ACTIVITY_OPEN;
+import static com.android.server.wm.SnapshotController.TASK_CLOSE;
+import static com.android.server.wm.SnapshotController.TASK_OPEN;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityManager;
+import android.os.Environment;
+import android.os.SystemProperties;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.window.TaskSnapshot;
+
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.server.LocalServices;
+import com.android.server.pm.UserManagerInternal;
+import com.android.server.wm.BaseAppSnapshotPersister.PersistInfoProvider;
+import com.android.server.wm.SnapshotController.TransitionState;
+
+import java.io.File;
+import java.util.ArrayList;
+
+/**
+ * When an app token becomes invisible, we take a snapshot (bitmap) and put it into our cache.
+ * Internally we use gralloc buffers to be able to draw them wherever we like without any copying.
+ * <p>
+ * System applications may retrieve a snapshot to represent the current state of an activity, and
+ * draw them in their own process.
+ * <p>
+ * Unlike TaskSnapshotController, we only keep one activity snapshot for a visible task in the
+ * cache. Which should largely reduce the memory usage.
+ * <p>
+ * To access this class, acquire the global window manager lock.
+ */
+class ActivitySnapshotController extends AbsAppSnapshotController<ActivityRecord,
+ ActivitySnapshotCache> {
+ private static final boolean DEBUG = false;
+ private static final String TAG = AbsAppSnapshotController.TAG;
+ // Maximum persisted snapshot count on disk.
+ private static final int MAX_PERSIST_SNAPSHOT_COUNT = 20;
+
+ static final String SNAPSHOTS_DIRNAME = "activity_snapshots";
+
+ /**
+ * The pending activities which should capture snapshot when process transition finish.
+ */
+ @VisibleForTesting
+ final ArraySet<ActivityRecord> mPendingCaptureActivity = new ArraySet<>();
+
+ /**
+ * The pending activities which should remove snapshot from memory when process transition
+ * finish.
+ */
+ @VisibleForTesting
+ final ArraySet<ActivityRecord> mPendingRemoveActivity = new ArraySet<>();
+
+ /**
+ * The pending activities which should delete snapshot files when process transition finish.
+ */
+ @VisibleForTesting
+ final ArraySet<ActivityRecord> mPendingDeleteActivity = new ArraySet<>();
+
+ /**
+ * The pending activities which should load snapshot from disk when process transition finish.
+ */
+ @VisibleForTesting
+ final ArraySet<ActivityRecord> mPendingLoadActivity = new ArraySet<>();
+
+ private final SnapshotPersistQueue mSnapshotPersistQueue;
+ private final PersistInfoProvider mPersistInfoProvider;
+ private final AppSnapshotLoader mSnapshotLoader;
+
+ /**
+ * File information holders, to make the sequence align, always update status of
+ * mUserSavedFiles/mSavedFilesInOrder before persist file from mPersister.
+ */
+ private final SparseArray<SparseArray<UserSavedFile>> mUserSavedFiles = new SparseArray<>();
+ // Keep sorted with create timeline.
+ private final ArrayList<UserSavedFile> mSavedFilesInOrder = new ArrayList<>();
+ private final TaskSnapshotPersister mPersister;
+
+ ActivitySnapshotController(WindowManagerService service, SnapshotPersistQueue persistQueue) {
+ super(service);
+ mSnapshotPersistQueue = persistQueue;
+ mPersistInfoProvider = createPersistInfoProvider(service,
+ Environment::getDataSystemCeDirectory);
+ mPersister = new TaskSnapshotPersister(persistQueue, mPersistInfoProvider);
+ mSnapshotLoader = new AppSnapshotLoader(mPersistInfoProvider);
+ initialize(new ActivitySnapshotCache(service));
+
+ final boolean snapshotEnabled =
+ !service.mContext
+ .getResources()
+ .getBoolean(com.android.internal.R.bool.config_disableTaskSnapshots)
+ && isSnapshotEnabled()
+ && !ActivityManager.isLowRamDeviceStatic(); // Don't support Android Go
+ setSnapshotEnabled(snapshotEnabled);
+ }
+
+ void systemReady() {
+ if (shouldDisableSnapshots()) {
+ return;
+ }
+ mService.mSnapshotController.registerTransitionStateConsumer(
+ ACTIVITY_OPEN, this::handleOpenActivityTransition);
+ mService.mSnapshotController.registerTransitionStateConsumer(
+ ACTIVITY_CLOSE, this::handleCloseActivityTransition);
+ mService.mSnapshotController.registerTransitionStateConsumer(
+ TASK_OPEN, this::handleOpenTaskTransition);
+ mService.mSnapshotController.registerTransitionStateConsumer(
+ TASK_CLOSE, this::handleCloseTaskTransition);
+ }
+
+ @Override
+ protected float initSnapshotScale() {
+ final float config = mService.mContext.getResources().getFloat(
+ com.android.internal.R.dimen.config_resActivitySnapshotScale);
+ return Math.max(Math.min(config, 1f), 0.1f);
+ }
+
+ // TODO remove when enabled
+ static boolean isSnapshotEnabled() {
+ return SystemProperties.getInt("persist.wm.debug.activity_screenshot", 0) != 0;
+ }
+
+ static PersistInfoProvider createPersistInfoProvider(
+ WindowManagerService service, BaseAppSnapshotPersister.DirectoryResolver resolver) {
+ // Don't persist reduced file, instead we only persist the "HighRes" bitmap which has
+ // already scaled with #initSnapshotScale
+ final boolean use16BitFormat = service.mContext.getResources().getBoolean(
+ com.android.internal.R.bool.config_use16BitTaskSnapshotPixelFormat);
+ return new PersistInfoProvider(resolver, SNAPSHOTS_DIRNAME,
+ false /* enableLowResSnapshots */, 0 /* lowResScaleFactor */, use16BitFormat);
+ }
+
+ /** Retrieves a snapshot for an activity from cache. */
+ @Nullable
+ TaskSnapshot getSnapshot(ActivityRecord ar) {
+ final int code = getSystemHashCode(ar);
+ return mCache.getSnapshot(code);
+ }
+
+ private void cleanUpUserFiles(int userId) {
+ synchronized (mSnapshotPersistQueue.getLock()) {
+ mSnapshotPersistQueue.sendToQueueLocked(
+ new SnapshotPersistQueue.WriteQueueItem(mPersistInfoProvider) {
+ @Override
+ boolean isReady() {
+ final UserManagerInternal mUserManagerInternal =
+ LocalServices.getService(UserManagerInternal.class);
+ return mUserManagerInternal.isUserUnlocked(userId);
+ }
+
+ @Override
+ void write() {
+ final File file = mPersistInfoProvider.getDirectory(userId);
+ if (file.exists()) {
+ final File[] contents = file.listFiles();
+ if (contents != null) {
+ for (int i = contents.length - 1; i >= 0; i--) {
+ contents[i].delete();
+ }
+ }
+ }
+ }
+ });
+ }
+ }
+
+ /**
+ * Prepare to handle on transition start. Clear all temporary fields.
+ */
+ void preTransitionStart() {
+ resetTmpFields();
+ }
+
+ /**
+ * on transition start has notified, start process data.
+ */
+ void postTransitionStart() {
+ if (shouldDisableSnapshots()) {
+ return;
+ }
+ onCommitTransition();
+ }
+
+ @VisibleForTesting
+ void resetTmpFields() {
+ mPendingCaptureActivity.clear();
+ mPendingRemoveActivity.clear();
+ mPendingDeleteActivity.clear();
+ mPendingLoadActivity.clear();
+ }
+
+ /**
+ * Start process all pending activities for a transition.
+ */
+ private void onCommitTransition() {
+ if (DEBUG) {
+ Slog.d(TAG, "ActivitySnapshotController#onCommitTransition result:"
+ + " capture " + mPendingCaptureActivity
+ + " remove " + mPendingRemoveActivity
+ + " delete " + mPendingDeleteActivity
+ + " load " + mPendingLoadActivity);
+ }
+ // task snapshots
+ for (int i = mPendingCaptureActivity.size() - 1; i >= 0; i--) {
+ recordSnapshot(mPendingCaptureActivity.valueAt(i));
+ }
+ // clear mTmpRemoveActivity from cache
+ for (int i = mPendingRemoveActivity.size() - 1; i >= 0; i--) {
+ final ActivityRecord ar = mPendingRemoveActivity.valueAt(i);
+ final int code = getSystemHashCode(ar);
+ mCache.onIdRemoved(code);
+ }
+ // clear snapshot on cache and delete files
+ for (int i = mPendingDeleteActivity.size() - 1; i >= 0; i--) {
+ final ActivityRecord ar = mPendingDeleteActivity.valueAt(i);
+ final int code = getSystemHashCode(ar);
+ mCache.onIdRemoved(code);
+ removeIfUserSavedFileExist(code, ar.mUserId);
+ }
+ // load snapshot to cache
+ for (int i = mPendingLoadActivity.size() - 1; i >= 0; i--) {
+ final ActivityRecord ar = mPendingLoadActivity.valueAt(i);
+ final int code = getSystemHashCode(ar);
+ final int userId = ar.mUserId;
+ if (mCache.getSnapshot(code) != null) {
+ // already in cache, skip
+ continue;
+ }
+ if (containsFile(code, userId)) {
+ synchronized (mSnapshotPersistQueue.getLock()) {
+ mSnapshotPersistQueue.sendToQueueLocked(
+ new SnapshotPersistQueue.WriteQueueItem(mPersistInfoProvider) {
+ @Override
+ void write() {
+ final TaskSnapshot snapshot = mSnapshotLoader.loadTask(code,
+ userId, false /* loadLowResolutionBitmap */);
+ synchronized (mService.getWindowManagerLock()) {
+ if (snapshot != null && !ar.finishing) {
+ mCache.putSnapshot(ar, snapshot);
+ }
+ }
+ }
+ });
+ }
+ }
+ }
+ // don't keep any reference
+ resetTmpFields();
+ }
+
+ private void recordSnapshot(ActivityRecord activity) {
+ final TaskSnapshot snapshot = recordSnapshotInner(activity, false /* allowSnapshotHome */);
+ if (snapshot != null) {
+ final int code = getSystemHashCode(activity);
+ addUserSavedFile(code, activity.mUserId, snapshot);
+ }
+ }
+
+ /**
+ * Called when the visibility of an app changes outside the regular app transition flow.
+ */
+ void notifyAppVisibilityChanged(ActivityRecord appWindowToken, boolean visible) {
+ if (!visible) {
+ resetTmpFields();
+ addBelowTopActivityIfExist(appWindowToken.getTask(), mPendingRemoveActivity,
+ "remove-snapshot");
+ onCommitTransition();
+ }
+ }
+
+ private static int getSystemHashCode(ActivityRecord activity) {
+ return System.identityHashCode(activity);
+ }
+
+ void handleOpenActivityTransition(TransitionState<ActivityRecord> transitionState) {
+ ArraySet<ActivityRecord> participant = transitionState.getParticipant(false /* open */);
+ for (ActivityRecord ar : participant) {
+ mPendingCaptureActivity.add(ar);
+ // remove the snapshot for the one below close
+ final ActivityRecord below = ar.getTask().getActivityBelow(ar);
+ if (below != null) {
+ mPendingRemoveActivity.add(below);
+ }
+ }
+ }
+
+ void handleCloseActivityTransition(TransitionState<ActivityRecord> transitionState) {
+ ArraySet<ActivityRecord> participant = transitionState.getParticipant(true /* open */);
+ for (ActivityRecord ar : participant) {
+ mPendingDeleteActivity.add(ar);
+ // load next one if exists.
+ final ActivityRecord below = ar.getTask().getActivityBelow(ar);
+ if (below != null) {
+ mPendingLoadActivity.add(below);
+ }
+ }
+ }
+
+ void handleCloseTaskTransition(TransitionState<Task> closeTaskTransitionRecord) {
+ ArraySet<Task> participant = closeTaskTransitionRecord.getParticipant(false /* open */);
+ for (Task close : participant) {
+ // this is close task transition
+ // remove the N - 1 from cache
+ addBelowTopActivityIfExist(close, mPendingRemoveActivity, "remove-snapshot");
+ }
+ }
+
+ void handleOpenTaskTransition(TransitionState<Task> openTaskTransitionRecord) {
+ ArraySet<Task> participant = openTaskTransitionRecord.getParticipant(true /* open */);
+ for (Task open : participant) {
+ // this is close task transition
+ // remove the N - 1 from cache
+ addBelowTopActivityIfExist(open, mPendingLoadActivity, "load-snapshot");
+ // Move the activities to top of mSavedFilesInOrder, so when purge happen, there
+ // will trim the persisted files from the most non-accessed.
+ adjustSavedFileOrder(open);
+ }
+ }
+
+ // Add the top -1 activity to a set if it exists.
+ private void addBelowTopActivityIfExist(Task task, ArraySet<ActivityRecord> set,
+ String debugMessage) {
+ final ActivityRecord topActivity = task.getTopMostActivity();
+ if (topActivity != null) {
+ final ActivityRecord below = task.getActivityBelow(topActivity);
+ if (below != null) {
+ set.add(below);
+ if (DEBUG) {
+ Slog.d(TAG, "ActivitySnapshotController#addBelowTopActivityIfExist "
+ + below + " from " + debugMessage);
+ }
+ }
+ }
+ }
+
+ private void adjustSavedFileOrder(Task nextTopTask) {
+ final int userId = nextTopTask.mUserId;
+ nextTopTask.forAllActivities(ar -> {
+ final int code = getSystemHashCode(ar);
+ final UserSavedFile usf = getUserFiles(userId).get(code);
+ if (usf != null) {
+ mSavedFilesInOrder.remove(usf);
+ mSavedFilesInOrder.add(usf);
+ }
+ }, false /* traverseTopToBottom */);
+ }
+
+ @Override
+ void onAppRemoved(ActivityRecord activity) {
+ super.onAppRemoved(activity);
+ final int code = getSystemHashCode(activity);
+ removeIfUserSavedFileExist(code, activity.mUserId);
+ if (DEBUG) {
+ Slog.d(TAG, "ActivitySnapshotController#onAppRemoved delete snapshot " + activity);
+ }
+ }
+
+ @Override
+ void onAppDied(ActivityRecord activity) {
+ super.onAppDied(activity);
+ final int code = getSystemHashCode(activity);
+ removeIfUserSavedFileExist(code, activity.mUserId);
+ if (DEBUG) {
+ Slog.d(TAG, "ActivitySnapshotController#onAppDied delete snapshot " + activity);
+ }
+ }
+
+ @Override
+ ActivityRecord getTopActivity(ActivityRecord activity) {
+ return activity;
+ }
+
+ @Override
+ ActivityRecord getTopFullscreenActivity(ActivityRecord activity) {
+ final WindowState win = activity.findMainWindow();
+ return (win != null && win.mAttrs.isFullscreen()) ? activity : null;
+ }
+
+ @Override
+ ActivityManager.TaskDescription getTaskDescription(ActivityRecord object) {
+ return object.taskDescription;
+ }
+
+ /**
+ * Find the window for a given activity to take a snapshot. During app transitions, trampoline
+ * activities can appear in the children, but should be ignored.
+ */
+ @Override
+ protected ActivityRecord findAppTokenForSnapshot(ActivityRecord activity) {
+ if (activity == null) {
+ return null;
+ }
+ return activity.canCaptureSnapshot() ? activity : null;
+ }
+
+ @Override
+ protected boolean use16BitFormat() {
+ return mPersistInfoProvider.use16BitFormat();
+ }
+
+ @NonNull
+ private SparseArray<UserSavedFile> getUserFiles(int userId) {
+ if (mUserSavedFiles.get(userId) == null) {
+ mUserSavedFiles.put(userId, new SparseArray<>());
+ // This is the first time this user attempt to access snapshot, clear up the disk.
+ cleanUpUserFiles(userId);
+ }
+ return mUserSavedFiles.get(userId);
+ }
+
+ private void removeIfUserSavedFileExist(int code, int userId) {
+ final UserSavedFile usf = getUserFiles(userId).get(code);
+ if (usf != null) {
+ mUserSavedFiles.remove(code);
+ mSavedFilesInOrder.remove(usf);
+ mPersister.removeSnap(code, userId);
+ }
+ }
+
+ private boolean containsFile(int code, int userId) {
+ return getUserFiles(userId).get(code) != null;
+ }
+
+ private void addUserSavedFile(int code, int userId, TaskSnapshot snapshot) {
+ final SparseArray<UserSavedFile> savedFiles = getUserFiles(userId);
+ final UserSavedFile savedFile = savedFiles.get(code);
+ if (savedFile == null) {
+ final UserSavedFile usf = new UserSavedFile(code, userId);
+ savedFiles.put(code, usf);
+ mSavedFilesInOrder.add(usf);
+ mPersister.persistSnapshot(code, userId, snapshot);
+
+ if (mSavedFilesInOrder.size() > MAX_PERSIST_SNAPSHOT_COUNT * 2) {
+ purgeSavedFile();
+ }
+ }
+ }
+
+ private void purgeSavedFile() {
+ final int savedFileCount = mSavedFilesInOrder.size();
+ final int removeCount = savedFileCount - MAX_PERSIST_SNAPSHOT_COUNT;
+ final ArrayList<UserSavedFile> usfs = new ArrayList<>();
+ if (removeCount > 0) {
+ final int removeTillIndex = savedFileCount - removeCount;
+ for (int i = savedFileCount - 1; i > removeTillIndex; --i) {
+ final UserSavedFile usf = mSavedFilesInOrder.remove(i);
+ if (usf != null) {
+ mUserSavedFiles.remove(usf.mFileId);
+ usfs.add(usf);
+ }
+ }
+ }
+ if (usfs.size() > 0) {
+ removeSnapshotFiles(usfs);
+ }
+ }
+
+ private void removeSnapshotFiles(ArrayList<UserSavedFile> files) {
+ synchronized (mSnapshotPersistQueue.getLock()) {
+ mSnapshotPersistQueue.sendToQueueLocked(
+ new SnapshotPersistQueue.WriteQueueItem(mPersistInfoProvider) {
+ @Override
+ void write() {
+ for (int i = files.size() - 1; i >= 0; --i) {
+ final UserSavedFile usf = files.get(i);
+ mSnapshotPersistQueue.deleteSnapshot(
+ usf.mFileId, usf.mUserId, mPersistInfoProvider);
+ }
+ }
+ });
+ }
+ }
+
+ static class UserSavedFile {
+ int mFileId;
+ int mUserId;
+ UserSavedFile(int fileId, int userId) {
+ mFileId = fileId;
+ mUserId = userId;
+ }
+ }
+}
diff --git a/services/core/java/com/android/server/wm/ActivityStartController.java b/services/core/java/com/android/server/wm/ActivityStartController.java
index 5e066fa..f8fb76a 100644
--- a/services/core/java/com/android/server/wm/ActivityStartController.java
+++ b/services/core/java/com/android/server/wm/ActivityStartController.java
@@ -50,8 +50,6 @@
import android.util.Slog;
import android.util.SparseArray;
import android.view.RemoteAnimationAdapter;
-import android.view.WindowManager;
-import android.window.RemoteTransition;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
@@ -562,9 +560,8 @@
final Task rootTask = mService.mRootWindowContainer.getDefaultTaskDisplayArea()
.getRootTask(WINDOWING_MODE_UNDEFINED, activityType);
if (rootTask == null) return false;
- final RemoteTransition remote = options.getRemoteTransition();
final ActivityRecord r = rootTask.topRunningActivity();
- if (r == null || r.isVisibleRequested() || !r.attachedToProcess() || remote == null
+ if (r == null || r.isVisibleRequested() || !r.attachedToProcess()
|| !r.mActivityComponent.equals(intent.getComponent())
// Recents keeps invisible while device is locked.
|| r.mDisplayContent.isKeyguardLocked()) {
@@ -573,47 +570,13 @@
mService.mRootWindowContainer.startPowerModeLaunchIfNeeded(true /* forceSend */, r);
final ActivityMetricsLogger.LaunchingState launchingState =
mSupervisor.getActivityMetricsLogger().notifyActivityLaunching(intent);
- final Transition transition = new Transition(WindowManager.TRANSIT_TO_FRONT,
- 0 /* flags */, r.mTransitionController, mService.mWindowManager.mSyncEngine);
- if (r.mTransitionController.isCollecting()) {
- // Special case: we are entering recents while an existing transition is running. In
- // this case, we know it's safe to "defer" the activity launch, so lets do so now so
- // that it can get its own transition and thus update launcher correctly.
- mService.mWindowManager.mSyncEngine.queueSyncSet(
- () -> {
- if (r.isAttached()) {
- r.mTransitionController.moveToCollecting(transition);
- }
- },
- () -> {
- if (r.isAttached() && transition.isCollecting()) {
- startExistingRecentsIfPossibleInner(options, r, rootTask,
- launchingState, remote, transition);
- }
- });
- } else {
- r.mTransitionController.moveToCollecting(transition);
- startExistingRecentsIfPossibleInner(options, r, rootTask, launchingState, remote,
- transition);
- }
- return true;
- }
-
- private void startExistingRecentsIfPossibleInner(ActivityOptions options, ActivityRecord r,
- Task rootTask, ActivityMetricsLogger.LaunchingState launchingState,
- RemoteTransition remoteTransition, Transition transition) {
final Task task = r.getTask();
mService.deferWindowLayout();
try {
final TransitionController controller = r.mTransitionController;
if (controller.getTransitionPlayer() != null) {
- controller.requestStartTransition(transition, task, remoteTransition,
- null /* displayChange */);
controller.collect(task);
controller.setTransientLaunch(r, TaskDisplayArea.getRootTaskAbove(rootTask));
- } else {
- // The transition player might be died when executing the queued transition.
- transition.abort();
}
task.moveToFront("startExistingRecents");
task.mInResumeTopActivity = true;
@@ -624,6 +587,7 @@
task.mInResumeTopActivity = false;
mService.continueWindowLayout();
}
+ return true;
}
void registerRemoteAnimationForNextActivityStart(String packageName,
diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java
index ce29564..12be1d3 100644
--- a/services/core/java/com/android/server/wm/ActivityStarter.java
+++ b/services/core/java/com/android/server/wm/ActivityStarter.java
@@ -1582,19 +1582,19 @@
}
}
if (isTransientLaunch) {
- if (forceTransientTransition && newTransition != null) {
- newTransition.collect(mLastStartActivityRecord);
- newTransition.collect(mPriorAboveTask);
+ if (forceTransientTransition) {
+ transitionController.collect(mLastStartActivityRecord);
+ transitionController.collect(mPriorAboveTask);
}
// `started` isn't guaranteed to be the actual relevant activity, so we must wait
// until after we launched to identify the relevant activity.
transitionController.setTransientLaunch(mLastStartActivityRecord, mPriorAboveTask);
- if (forceTransientTransition && newTransition != null) {
+ if (forceTransientTransition) {
final DisplayContent dc = mLastStartActivityRecord.getDisplayContent();
// update wallpaper target to TransientHide
dc.mWallpaperController.adjustWallpaperWindows();
// execute transition because there is no change
- newTransition.setReady(dc, true /* ready */);
+ transitionController.setReady(dc, true /* ready */);
}
}
if (!userLeaving) {
diff --git a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
index 992743a..7b9cc6f 100644
--- a/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/wm/ActivityTaskManagerService.java
@@ -75,9 +75,7 @@
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_IMMERSIVE;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_LOCKTASK;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
-import static com.android.server.am.ActivityManagerService.ANR_TRACE_DIR;
import static com.android.server.am.ActivityManagerService.STOCK_PM_FLAGS;
-import static com.android.server.am.ActivityManagerService.dumpStackTraces;
import static com.android.server.am.ActivityManagerServiceDumpActivitiesProto.ROOT_WINDOW_CONTAINER;
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONFIG_WILL_CHANGE;
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.CONTROLLER;
@@ -95,6 +93,8 @@
import static com.android.server.am.ActivityManagerServiceDumpProcessesProto.ScreenCompatPackage.PACKAGE;
import static com.android.server.am.EventLogTags.writeBootProgressEnableScreen;
import static com.android.server.am.EventLogTags.writeConfigurationChanged;
+import static com.android.server.am.StackTracesDumpHelper.ANR_TRACE_DIR;
+import static com.android.server.am.StackTracesDumpHelper.dumpStackTraces;
import static com.android.server.wm.ActivityInterceptorCallback.MAINLINE_FIRST_ORDERED_ID;
import static com.android.server.wm.ActivityInterceptorCallback.MAINLINE_LAST_ORDERED_ID;
import static com.android.server.wm.ActivityInterceptorCallback.SYSTEM_FIRST_ORDERED_ID;
@@ -1240,25 +1240,6 @@
ProfilerInfo profilerInfo, Bundle bOptions, int userId, boolean validateIncomingUser) {
final SafeActivityOptions opts = SafeActivityOptions.fromBundle(bOptions);
- // A quick path (skip general intent/task resolving) to start recents animation if the
- // recents (or home) activity is available in background.
- if (opts != null && opts.getOriginalOptions().getTransientLaunch()
- && isCallerRecents(Binder.getCallingUid())) {
- final long origId = Binder.clearCallingIdentity();
- try {
- synchronized (mGlobalLock) {
- Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents");
- if (mActivityStartController.startExistingRecentsIfPossible(
- intent, opts.getOriginalOptions())) {
- return ActivityManager.START_TASK_TO_FRONT;
- }
- // Else follow the standard launch procedure.
- }
- } finally {
- Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
- Binder.restoreCallingIdentity(origId);
- }
- }
assertPackageMatchesCallingUid(callingPackage);
enforceNotIsolatedCaller("startActivityAsUser");
@@ -5718,6 +5699,23 @@
boolean validateIncomingUser, PendingIntentRecord originatingPendingIntent,
BackgroundStartPrivileges backgroundStartPrivileges) {
assertPackageMatchesCallingUid(callingPackage);
+ // A quick path (skip general intent/task resolving) to start recents animation if the
+ // recents (or home) activity is available in background.
+ if (options != null && options.getOriginalOptions() != null
+ && options.getOriginalOptions().getTransientLaunch() && isCallerRecents(uid)) {
+ try {
+ synchronized (mGlobalLock) {
+ Trace.traceBegin(TRACE_TAG_WINDOW_MANAGER, "startExistingRecents");
+ if (mActivityStartController.startExistingRecentsIfPossible(
+ intent, options.getOriginalOptions())) {
+ return ActivityManager.START_TASK_TO_FRONT;
+ }
+ // Else follow the standard launch procedure.
+ }
+ } finally {
+ Trace.traceEnd(TRACE_TAG_WINDOW_MANAGER);
+ }
+ }
return getActivityStartController().startActivityInPackage(uid, realCallingPid,
realCallingUid, callingPackage, callingFeatureId, intent, resolvedType,
resultTo, resultWho, requestCode, startFlags, options, userId, inTask,
diff --git a/services/core/java/com/android/server/wm/AnrController.java b/services/core/java/com/android/server/wm/AnrController.java
index bbe7a33..90ec964 100644
--- a/services/core/java/com/android/server/wm/AnrController.java
+++ b/services/core/java/com/android/server/wm/AnrController.java
@@ -34,7 +34,7 @@
import android.view.InputApplicationHandle;
import com.android.internal.os.TimeoutRecord;
-import com.android.server.am.ActivityManagerService;
+import com.android.server.am.StackTracesDumpHelper;
import com.android.server.criticalevents.CriticalEventLog;
import java.io.File;
@@ -336,7 +336,7 @@
String criticalEvents =
CriticalEventLog.getInstance().logLinesForSystemServerTraceFile();
- final File tracesFile = ActivityManagerService.dumpStackTraces(firstPids,
+ final File tracesFile = StackTracesDumpHelper.dumpStackTraces(firstPids,
null /* processCpuTracker */, null /* lastPids */,
CompletableFuture.completedFuture(nativePids),
null /* logExceptionCreatingFile */, "Pre-dump", criticalEvents,
diff --git a/services/core/java/com/android/server/wm/AppTransitionController.java b/services/core/java/com/android/server/wm/AppTransitionController.java
index 4e94f96..841d28b 100644
--- a/services/core/java/com/android/server/wm/AppTransitionController.java
+++ b/services/core/java/com/android/server/wm/AppTransitionController.java
@@ -321,7 +321,7 @@
mService.mSurfaceAnimationRunner.continueStartingAnimations();
}
- mService.mTaskSnapshotController.onTransitionStarting(mDisplayContent);
+ mService.mSnapshotController.onTransitionStarting(mDisplayContent);
mDisplayContent.mOpeningApps.clear();
mDisplayContent.mClosingApps.clear();
diff --git a/services/core/java/com/android/server/wm/DisplayContent.java b/services/core/java/com/android/server/wm/DisplayContent.java
index a4d475f..1344788 100644
--- a/services/core/java/com/android/server/wm/DisplayContent.java
+++ b/services/core/java/com/android/server/wm/DisplayContent.java
@@ -1228,7 +1228,8 @@
private void finishHoldScreenUpdate() {
final boolean hold = mTmpHoldScreenWindow != null;
if (hold && mTmpHoldScreenWindow != mHoldScreenWindow) {
- mHoldScreenWakeLock.setWorkSource(new WorkSource(mTmpHoldScreenWindow.mSession.mUid));
+ mHoldScreenWakeLock.setWorkSource(new WorkSource(mTmpHoldScreenWindow.mSession.mUid,
+ mTmpHoldScreenWindow.mSession.mPackageName));
}
mHoldScreenWindow = mTmpHoldScreenWindow;
mTmpHoldScreenWindow = null;
diff --git a/services/core/java/com/android/server/wm/DragState.java b/services/core/java/com/android/server/wm/DragState.java
index 0b28ba2..bc9efc8 100644
--- a/services/core/java/com/android/server/wm/DragState.java
+++ b/services/core/java/com/android/server/wm/DragState.java
@@ -377,15 +377,10 @@
mDragWindowHandle.ownerUid = MY_UID;
mDragWindowHandle.scaleFactor = 1.0f;
- // InputConfig.PREVENT_SPLITTING: To keep the default behavior of this window to be
- // focusable, which allows the system to consume keys when dragging is active. This can
- // also be used to modify the drag state on key press. For example, cancel drag on
- // escape key.
// InputConfig.TRUSTED_OVERLAY: To not block any touches while D&D ongoing and allowing
// touches to pass through to windows underneath. This allows user to interact with the
// UI to navigate while dragging.
- mDragWindowHandle.inputConfig =
- InputConfig.PREVENT_SPLITTING | InputConfig.TRUSTED_OVERLAY;
+ mDragWindowHandle.inputConfig = InputConfig.TRUSTED_OVERLAY;
// The drag window cannot receive new touches.
mDragWindowHandle.touchableRegion.setEmpty();
diff --git a/services/core/java/com/android/server/wm/InputMonitor.java b/services/core/java/com/android/server/wm/InputMonitor.java
index 8c59548..8f40e79 100644
--- a/services/core/java/com/android/server/wm/InputMonitor.java
+++ b/services/core/java/com/android/server/wm/InputMonitor.java
@@ -18,6 +18,7 @@
import static android.app.WindowConfiguration.WINDOWING_MODE_FULLSCREEN;
import static android.os.Trace.TRACE_TAG_WINDOW_MANAGER;
+import static android.view.ViewTreeObserver.InternalInsetsInfo.TOUCHABLE_INSETS_REGION;
import static android.view.WindowManager.INPUT_CONSUMER_PIP;
import static android.view.WindowManager.INPUT_CONSUMER_RECENTS_ANIMATION;
import static android.view.WindowManager.INPUT_CONSUMER_WALLPAPER;
@@ -296,8 +297,11 @@
// be applied using the SurfaceControl hierarchy from the Organizer. This means
// we need to make sure that these changes in crop are reflected in the input
// windows, and so ensure this flag is set so that the input crop always reflects
- // the surface hierarchy.
- useSurfaceBoundsAsTouchRegion = true;
+ // the surface hierarchy. However, we only want to set this when the client did
+ // not already provide a touchable region, so that we don't ignore the one provided.
+ if (w.mTouchableInsets != TOUCHABLE_INSETS_REGION) {
+ useSurfaceBoundsAsTouchRegion = true;
+ }
if (w.mAttrs.isModal()) {
TaskFragment parent = w.getTaskFragment();
diff --git a/services/core/java/com/android/server/wm/LaunchParamsPersister.java b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
index bf511adf0..bb50372 100644
--- a/services/core/java/com/android/server/wm/LaunchParamsPersister.java
+++ b/services/core/java/com/android/server/wm/LaunchParamsPersister.java
@@ -263,8 +263,8 @@
boolean changed = !Objects.equals(params.mDisplayUniqueId, info.uniqueId);
params.mDisplayUniqueId = info.uniqueId;
- changed |= params.mWindowingMode != task.getWindowingMode();
- params.mWindowingMode = task.getWindowingMode();
+ changed |= params.mWindowingMode != task.getTaskDisplayArea().getWindowingMode();
+ params.mWindowingMode = task.getTaskDisplayArea().getWindowingMode();
if (task.mLastNonFullscreenBounds != null) {
changed |= !Objects.equals(params.mBounds, task.mLastNonFullscreenBounds);
diff --git a/services/core/java/com/android/server/wm/LetterboxUiController.java b/services/core/java/com/android/server/wm/LetterboxUiController.java
index 5db39fc..ef464d2 100644
--- a/services/core/java/com/android/server/wm/LetterboxUiController.java
+++ b/services/core/java/com/android/server/wm/LetterboxUiController.java
@@ -447,6 +447,10 @@
@ScreenOrientation
int overrideOrientationIfNeeded(@ScreenOrientation int candidate) {
+ // In some cases (e.g. Kids app) we need to map the candidate orientation to some other
+ // orientation.
+ candidate = mActivityRecord.mWmService.mapOrientationRequest(candidate);
+
if (FALSE.equals(mBooleanPropertyAllowOrientationOverride)) {
return candidate;
}
@@ -837,7 +841,7 @@
int dividerInsets =
getResources().getDimensionPixelSize(R.dimen.docked_stack_divider_insets);
int dividerSize = dividerWindowWidth - dividerInsets * 2;
- final Rect bounds = new Rect(displayContent.getBounds());
+ final Rect bounds = new Rect(displayContent.getWindowConfiguration().getAppBounds());
if (bounds.width() >= bounds.height()) {
bounds.inset(/* dx */ dividerSize / 2, /* dy */ 0);
bounds.right = bounds.centerX();
@@ -1494,7 +1498,7 @@
}
private void inheritConfiguration(ActivityRecord firstOpaque) {
- // To avoid wrong behaviour, we're not forcing a specific aspet ratio to activities
+ // To avoid wrong behaviour, we're not forcing a specific aspect ratio to activities
// which are not already providing one (e.g. permission dialogs) and presumably also
// not resizable.
if (mActivityRecord.getMinAspectRatio() != UNDEFINED_ASPECT_RATIO) {
diff --git a/services/core/java/com/android/server/wm/RootWindowContainer.java b/services/core/java/com/android/server/wm/RootWindowContainer.java
index b2a4df1..fda2125 100644
--- a/services/core/java/com/android/server/wm/RootWindowContainer.java
+++ b/services/core/java/com/android/server/wm/RootWindowContainer.java
@@ -44,7 +44,6 @@
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_TASKS;
import static com.android.internal.protolog.ProtoLogGroup.WM_DEBUG_WALLPAPER;
import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_SURFACE_ALLOC;
-import static com.android.internal.protolog.ProtoLogGroup.WM_SHOW_TRANSACTIONS;
import static com.android.server.policy.PhoneWindowManager.SYSTEM_DIALOG_REASON_ASSIST;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_LAYOUT;
import static com.android.server.policy.WindowManagerPolicy.FINISH_LAYOUT_REDO_WALLPAPER;
@@ -432,13 +431,6 @@
}
};
- private static final Consumer<WindowState> sRemoveReplacedWindowsConsumer = w -> {
- final ActivityRecord activity = w.mActivityRecord;
- if (activity != null) {
- activity.removeReplacedWindowIfNeeded(w);
- }
- };
-
RootWindowContainer(WindowManagerService service) {
super(service);
mHandler = new MyHandler(service.mH.getLooper());
@@ -662,17 +654,6 @@
forAllWindows(mCloseSystemDialogsConsumer, false /* traverseTopToBottom */);
}
- void removeReplacedWindows() {
- ProtoLog.i(WM_SHOW_TRANSACTIONS, ">>> OPEN TRANSACTION removeReplacedWindows");
- mWmService.openSurfaceTransaction();
- try {
- forAllWindows(sRemoveReplacedWindowsConsumer, true /* traverseTopToBottom */);
- } finally {
- mWmService.closeSurfaceTransaction("removeReplacedWindows");
- ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION removeReplacedWindows");
- }
- }
-
boolean hasPendingLayoutChanges(WindowAnimator animator) {
boolean hasChanges = false;
diff --git a/services/core/java/com/android/server/wm/Session.java b/services/core/java/com/android/server/wm/Session.java
index ce9bff8..7b10c63 100644
--- a/services/core/java/com/android/server/wm/Session.java
+++ b/services/core/java/com/android/server/wm/Session.java
@@ -116,7 +116,7 @@
private boolean mShowingAlertWindowNotificationAllowed;
private boolean mClientDead = false;
private float mLastReportedAnimatorScale;
- private String mPackageName;
+ protected String mPackageName;
private String mRelayoutTag;
private final InsetsSourceControl.Array mDummyControls = new InsetsSourceControl.Array();
final boolean mSetsUnrestrictedKeepClearAreas;
@@ -232,11 +232,6 @@
}
@Override
- public void prepareToReplaceWindows(IBinder appToken, boolean childrenOnly) {
- mService.setWillReplaceWindows(appToken, childrenOnly);
- }
-
- @Override
public boolean cancelDraw(IWindow window) {
return mService.cancelDraw(this, window);
}
@@ -862,7 +857,7 @@
@Override
public void grantInputChannel(int displayId, SurfaceControl surface,
IWindow window, IBinder hostInputToken, int flags, int privateFlags, int type,
- IBinder windowToken, IBinder focusGrantToken, String inputHandleName,
+ int inputFeatures, IBinder windowToken, IBinder focusGrantToken, String inputHandleName,
InputChannel outInputChannel) {
if (hostInputToken == null && !mCanAddInternalSystemWindow) {
// Callers without INTERNAL_SYSTEM_WINDOW permission cannot grant input channel to
@@ -874,7 +869,7 @@
try {
mService.grantInputChannel(this, mUid, mPid, displayId, surface, window, hostInputToken,
flags, mCanAddInternalSystemWindow ? privateFlags : 0,
- type, windowToken, focusGrantToken, inputHandleName,
+ type, inputFeatures, windowToken, focusGrantToken, inputHandleName,
outInputChannel);
} finally {
Binder.restoreCallingIdentity(identity);
@@ -883,11 +878,11 @@
@Override
public void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
- int flags, int privateFlags, Region region) {
+ int flags, int privateFlags, int inputFeatures, Region region) {
final long identity = Binder.clearCallingIdentity();
try {
mService.updateInputChannel(channelToken, displayId, surface, flags,
- mCanAddInternalSystemWindow ? privateFlags : 0, region);
+ mCanAddInternalSystemWindow ? privateFlags : 0, inputFeatures, region);
} finally {
Binder.restoreCallingIdentity(identity);
}
diff --git a/services/core/java/com/android/server/wm/AbsAppSnapshotCache.java b/services/core/java/com/android/server/wm/SnapshotCache.java
similarity index 96%
rename from services/core/java/com/android/server/wm/AbsAppSnapshotCache.java
rename to services/core/java/com/android/server/wm/SnapshotCache.java
index c8adc8f..401b260 100644
--- a/services/core/java/com/android/server/wm/AbsAppSnapshotCache.java
+++ b/services/core/java/com/android/server/wm/SnapshotCache.java
@@ -25,13 +25,13 @@
* Base class for an app snapshot cache
* @param <TYPE> The basic type, either Task or ActivityRecord
*/
-abstract class AbsAppSnapshotCache<TYPE extends WindowContainer> {
+abstract class SnapshotCache<TYPE extends WindowContainer> {
protected final WindowManagerService mService;
protected final String mName;
protected final ArrayMap<ActivityRecord, Integer> mAppIdMap = new ArrayMap<>();
protected final ArrayMap<Integer, CacheEntry> mRunningCache = new ArrayMap<>();
- AbsAppSnapshotCache(WindowManagerService service, String name) {
+ SnapshotCache(WindowManagerService service, String name) {
mService = service;
mName = name;
}
diff --git a/services/core/java/com/android/server/wm/SnapshotController.java b/services/core/java/com/android/server/wm/SnapshotController.java
new file mode 100644
index 0000000..cd1263e
--- /dev/null
+++ b/services/core/java/com/android/server/wm/SnapshotController.java
@@ -0,0 +1,337 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.view.WindowManager.TRANSIT_CLOSE;
+import static android.view.WindowManager.TRANSIT_FIRST_CUSTOM;
+import static android.view.WindowManager.TRANSIT_OPEN;
+import static android.view.WindowManager.TRANSIT_TO_BACK;
+import static android.view.WindowManager.TRANSIT_TO_FRONT;
+
+import android.annotation.IntDef;
+import android.util.ArraySet;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.view.WindowManager;
+
+import com.android.internal.annotations.VisibleForTesting;
+
+import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.util.ArrayList;
+import java.util.function.Consumer;
+
+/**
+ * Integrates common functionality from TaskSnapshotController and ActivitySnapshotController.
+ */
+class SnapshotController {
+ private static final boolean DEBUG = false;
+ private static final String TAG = AbsAppSnapshotController.TAG;
+
+ static final int ACTIVITY_OPEN = 1;
+ static final int ACTIVITY_CLOSE = 2;
+ static final int TASK_OPEN = 4;
+ static final int TASK_CLOSE = 8;
+ /** @hide */
+ @Retention(RetentionPolicy.SOURCE)
+ @IntDef(
+ value = {ACTIVITY_OPEN,
+ ACTIVITY_CLOSE,
+ TASK_OPEN,
+ TASK_CLOSE})
+ @interface TransitionStateType {}
+
+ private final SnapshotPersistQueue mSnapshotPersistQueue;
+ final TaskSnapshotController mTaskSnapshotController;
+ final ActivitySnapshotController mActivitySnapshotController;
+
+ private final ArraySet<Task> mTmpCloseTasks = new ArraySet<>();
+ private final ArraySet<Task> mTmpOpenTasks = new ArraySet<>();
+
+ private final SparseArray<TransitionState> mTmpOpenCloseRecord = new SparseArray<>();
+ private final ArraySet<Integer> mTmpAnalysisRecord = new ArraySet<>();
+ private final SparseArray<ArrayList<Consumer<TransitionState>>> mTransitionStateConsumer =
+ new SparseArray<>();
+ private int mActivatedType;
+
+ private final ActivityOrderCheck mActivityOrderCheck = new ActivityOrderCheck();
+ private final ActivityOrderCheck.AnalysisResult mResultHandler = (type, close, open) -> {
+ addTransitionRecord(type, true/* open */, open);
+ addTransitionRecord(type, false/* open */, close);
+ };
+
+ private static class ActivityOrderCheck {
+ private ActivityRecord mOpenActivity;
+ private ActivityRecord mCloseActivity;
+ private int mOpenIndex = -1;
+ private int mCloseIndex = -1;
+
+ private void reset() {
+ mOpenActivity = null;
+ mCloseActivity = null;
+ mOpenIndex = -1;
+ mCloseIndex = -1;
+ }
+
+ private void setTarget(boolean open, ActivityRecord ar, int index) {
+ if (open) {
+ mOpenActivity = ar;
+ mOpenIndex = index;
+ } else {
+ mCloseActivity = ar;
+ mCloseIndex = index;
+ }
+ }
+
+ void analysisOrder(ArraySet<ActivityRecord> closeApps,
+ ArraySet<ActivityRecord> openApps, Task task, AnalysisResult result) {
+ for (int j = closeApps.size() - 1; j >= 0; j--) {
+ final ActivityRecord ar = closeApps.valueAt(j);
+ if (ar.getTask() == task) {
+ setTarget(false, ar, task.mChildren.indexOf(ar));
+ break;
+ }
+ }
+ for (int j = openApps.size() - 1; j >= 0; j--) {
+ final ActivityRecord ar = openApps.valueAt(j);
+ if (ar.getTask() == task) {
+ setTarget(true, ar, task.mChildren.indexOf(ar));
+ break;
+ }
+ }
+ if (mOpenIndex > mCloseIndex && mCloseIndex != -1) {
+ result.onCheckResult(ACTIVITY_OPEN, mCloseActivity, mOpenActivity);
+ } else if (mOpenIndex < mCloseIndex && mOpenIndex != -1) {
+ result.onCheckResult(ACTIVITY_CLOSE, mCloseActivity, mOpenActivity);
+ }
+ reset();
+ }
+ private interface AnalysisResult {
+ void onCheckResult(@TransitionStateType int type,
+ ActivityRecord close, ActivityRecord open);
+ }
+ }
+
+ private void addTransitionRecord(int type, boolean open, WindowContainer target) {
+ TransitionState record = mTmpOpenCloseRecord.get(type);
+ if (record == null) {
+ record = new TransitionState();
+ mTmpOpenCloseRecord.set(type, record);
+ }
+ record.addParticipant(target, open);
+ mTmpAnalysisRecord.add(type);
+ }
+
+ private void clearRecord() {
+ mTmpOpenCloseRecord.clear();
+ mTmpAnalysisRecord.clear();
+ }
+
+ static class TransitionState<TYPE extends WindowContainer> {
+ private final ArraySet<TYPE> mOpenParticipant = new ArraySet<>();
+ private final ArraySet<TYPE> mCloseParticipant = new ArraySet<>();
+
+ void addParticipant(TYPE target, boolean open) {
+ final ArraySet<TYPE> participant = open
+ ? mOpenParticipant : mCloseParticipant;
+ participant.add(target);
+ }
+
+ ArraySet<TYPE> getParticipant(boolean open) {
+ return open ? mOpenParticipant : mCloseParticipant;
+ }
+ }
+
+ SnapshotController(WindowManagerService wms) {
+ mSnapshotPersistQueue = new SnapshotPersistQueue();
+ mTaskSnapshotController = new TaskSnapshotController(wms, mSnapshotPersistQueue);
+ mActivitySnapshotController = new ActivitySnapshotController(wms, mSnapshotPersistQueue);
+ }
+
+ void registerTransitionStateConsumer(@TransitionStateType int type,
+ Consumer<TransitionState> consumer) {
+ ArrayList<Consumer<TransitionState>> consumers = mTransitionStateConsumer.get(type);
+ if (consumers == null) {
+ consumers = new ArrayList<>();
+ mTransitionStateConsumer.set(type, consumers);
+ }
+ if (!consumers.contains(consumer)) {
+ consumers.add(consumer);
+ }
+ mActivatedType |= type;
+ }
+
+ void unregisterTransitionStateConsumer(int type, Consumer<TransitionState> consumer) {
+ final ArrayList<Consumer<TransitionState>> consumers = mTransitionStateConsumer.get(type);
+ if (consumers == null) {
+ return;
+ }
+ consumers.remove(consumer);
+ if (consumers.size() == 0) {
+ mActivatedType &= ~type;
+ }
+ }
+
+ private boolean hasTransitionStateConsumer(@TransitionStateType int type) {
+ return (mActivatedType & type) != 0;
+ }
+
+ void systemReady() {
+ mSnapshotPersistQueue.systemReady();
+ mTaskSnapshotController.systemReady();
+ mActivitySnapshotController.systemReady();
+ }
+
+ void setPause(boolean paused) {
+ mSnapshotPersistQueue.setPaused(paused);
+ }
+
+ void onAppRemoved(ActivityRecord activity) {
+ mTaskSnapshotController.onAppRemoved(activity);
+ mActivitySnapshotController.onAppRemoved(activity);
+ }
+
+ void onAppDied(ActivityRecord activity) {
+ mTaskSnapshotController.onAppDied(activity);
+ mActivitySnapshotController.onAppDied(activity);
+ }
+
+ void notifyAppVisibilityChanged(ActivityRecord appWindowToken, boolean visible) {
+ if (!visible && hasTransitionStateConsumer(TASK_CLOSE)) {
+ // close task transition
+ addTransitionRecord(TASK_CLOSE, false /*open*/, appWindowToken.getTask());
+ mActivitySnapshotController.preTransitionStart();
+ notifyTransition(TASK_CLOSE);
+ mActivitySnapshotController.postTransitionStart();
+ clearRecord();
+ }
+ }
+
+ // For legacy transition
+ void onTransitionStarting(DisplayContent displayContent) {
+ handleAppTransition(displayContent.mClosingApps, displayContent.mOpeningApps);
+ }
+
+ // For shell transition, adapt to legacy transition.
+ void onTransitionReady(@WindowManager.TransitionType int type,
+ ArraySet<WindowContainer> participants) {
+ final boolean isTransitionOpen = isTransitionOpen(type);
+ final boolean isTransitionClose = isTransitionClose(type);
+ if (!isTransitionOpen && !isTransitionClose && type < TRANSIT_FIRST_CUSTOM
+ || (mActivatedType == 0)) {
+ return;
+ }
+ final ArraySet<ActivityRecord> openingApps = new ArraySet<>();
+ final ArraySet<ActivityRecord> closingApps = new ArraySet<>();
+
+ for (int i = participants.size() - 1; i >= 0; --i) {
+ final ActivityRecord ar = participants.valueAt(i).asActivityRecord();
+ if (ar == null || ar.getTask() == null) continue;
+ if (ar.isVisibleRequested()) {
+ openingApps.add(ar);
+ } else {
+ closingApps.add(ar);
+ }
+ }
+ handleAppTransition(closingApps, openingApps);
+ }
+
+ private static boolean isTransitionOpen(int type) {
+ return type == TRANSIT_OPEN || type == TRANSIT_TO_FRONT;
+ }
+ private static boolean isTransitionClose(int type) {
+ return type == TRANSIT_CLOSE || type == TRANSIT_TO_BACK;
+ }
+
+ @VisibleForTesting
+ void handleAppTransition(ArraySet<ActivityRecord> closingApps,
+ ArraySet<ActivityRecord> openApps) {
+ if (mActivatedType == 0) {
+ return;
+ }
+ analysisTransition(closingApps, openApps);
+ mActivitySnapshotController.preTransitionStart();
+ for (Integer transitionType : mTmpAnalysisRecord) {
+ notifyTransition(transitionType);
+ }
+ mActivitySnapshotController.postTransitionStart();
+ clearRecord();
+ }
+
+ private void notifyTransition(int transitionType) {
+ final TransitionState record = mTmpOpenCloseRecord.get(transitionType);
+ final ArrayList<Consumer<TransitionState>> consumers =
+ mTransitionStateConsumer.get(transitionType);
+ for (Consumer<TransitionState> consumer : consumers) {
+ consumer.accept(record);
+ }
+ }
+
+ private void analysisTransition(ArraySet<ActivityRecord> closingApps,
+ ArraySet<ActivityRecord> openingApps) {
+ getParticipantTasks(closingApps, mTmpCloseTasks, false /* isOpen */);
+ getParticipantTasks(openingApps, mTmpOpenTasks, true /* isOpen */);
+ if (DEBUG) {
+ Slog.d(TAG, "AppSnapshotController#analysisTransition participants"
+ + " mTmpCloseTasks " + mTmpCloseTasks
+ + " mTmpOpenTasks " + mTmpOpenTasks);
+ }
+ for (int i = mTmpCloseTasks.size() - 1; i >= 0; i--) {
+ final Task closeTask = mTmpCloseTasks.valueAt(i);
+ if (mTmpOpenTasks.contains(closeTask)) {
+ if (hasTransitionStateConsumer(ACTIVITY_OPEN)
+ || hasTransitionStateConsumer(ACTIVITY_CLOSE)) {
+ mActivityOrderCheck.analysisOrder(closingApps, openingApps, closeTask,
+ mResultHandler);
+ }
+ } else if (hasTransitionStateConsumer(TASK_CLOSE)) {
+ // close task transition
+ addTransitionRecord(TASK_CLOSE, false /*open*/, closeTask);
+ }
+ }
+ if (hasTransitionStateConsumer(TASK_OPEN)) {
+ for (int i = mTmpOpenTasks.size() - 1; i >= 0; i--) {
+ final Task openTask = mTmpOpenTasks.valueAt(i);
+ if (!mTmpCloseTasks.contains(openTask)) {
+ // this is open task transition
+ addTransitionRecord(TASK_OPEN, true /*open*/, openTask);
+ }
+ }
+ }
+ mTmpCloseTasks.clear();
+ mTmpOpenTasks.clear();
+ }
+
+ private void getParticipantTasks(ArraySet<ActivityRecord> activityRecords, ArraySet<Task> tasks,
+ boolean isOpen) {
+ for (int i = activityRecords.size() - 1; i >= 0; i--) {
+ final ActivityRecord activity = activityRecords.valueAt(i);
+ final Task task = activity.getTask();
+ if (task == null) continue;
+
+ if (isOpen == activity.isVisibleRequested()) {
+ tasks.add(task);
+ }
+ }
+ }
+
+ void dump(PrintWriter pw, String prefix) {
+ mTaskSnapshotController.dump(pw, prefix);
+ mActivitySnapshotController.dump(pw, prefix);
+ }
+}
diff --git a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
index fdc3616..afef85e 100644
--- a/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
+++ b/services/core/java/com/android/server/wm/SnapshotPersistQueue.java
@@ -129,7 +129,7 @@
}
}
- private void deleteSnapshot(int index, int userId, PersistInfoProvider provider) {
+ void deleteSnapshot(int index, int userId, PersistInfoProvider provider) {
final File protoFile = provider.getProtoFile(index, userId);
final File bitmapLowResFile = provider.getLowResolutionBitmapFile(index, userId);
protoFile.delete();
diff --git a/services/core/java/com/android/server/wm/Task.java b/services/core/java/com/android/server/wm/Task.java
index 67ca844..68b2d0f 100644
--- a/services/core/java/com/android/server/wm/Task.java
+++ b/services/core/java/com/android/server/wm/Task.java
@@ -866,23 +866,8 @@
return false;
}
- final int toRootTaskWindowingMode = toRootTask.getWindowingMode();
final ActivityRecord topActivity = getTopNonFinishingActivity();
- final boolean mightReplaceWindow = topActivity != null
- && replaceWindowsOnTaskMove(getWindowingMode(), toRootTaskWindowingMode);
- if (mightReplaceWindow) {
- // We are about to relaunch the activity because its configuration changed due to
- // being maximized, i.e. size change. The activity will first remove the old window
- // and then add a new one. This call will tell window manager about this, so it can
- // preserve the old window until the new one is drawn. This prevents having a gap
- // between the removal and addition, in which no window is visible. We also want the
- // entrance of the new window to be properly animated.
- // Note here we always set the replacing window first, as the flags might be needed
- // during the relaunch. If we end up not doing any relaunch, we clear the flags later.
- windowManager.setWillReplaceWindow(topActivity.token, animate);
- }
-
mAtmService.deferWindowLayout();
boolean kept = true;
try {
@@ -926,17 +911,10 @@
mAtmService.continueWindowLayout();
}
- if (mightReplaceWindow) {
- // If we didn't actual do a relaunch (indicated by kept==true meaning we kept the old
- // window), we need to clear the replace window settings. Otherwise, we schedule a
- // timeout to remove the old window if the replacing window is not coming in time.
- windowManager.scheduleClearWillReplaceWindows(topActivity.token, !kept);
- }
-
if (!deferResume) {
// The task might have already been running and its visibility needs to be synchronized
// with the visibility of the root task / windows.
- root.ensureActivitiesVisible(null, 0, !mightReplaceWindow);
+ root.ensureActivitiesVisible(null, 0, PRESERVE_WINDOWS);
root.resumeFocusedTasksTopActivities();
}
@@ -947,17 +925,6 @@
return (preferredRootTask == toRootTask);
}
- /**
- * @return {@code true} if the windows of tasks being moved to the target root task from the
- * source root task should be replaced, meaning that window manager will keep the old window
- * around until the new is ready.
- */
- private static boolean replaceWindowsOnTaskMove(
- int sourceWindowingMode, int targetWindowingMode) {
- return sourceWindowingMode == WINDOWING_MODE_FREEFORM
- || targetWindowingMode == WINDOWING_MODE_FREEFORM;
- }
-
void touchActiveTime() {
lastActiveTime = SystemClock.elapsedRealtime();
}
@@ -2277,10 +2244,11 @@
return;
}
- // Don't persist state if display isn't in freeform mode. Then the task will be launched
- // back to its last state in a freeform display when it's launched in a freeform display
- // next time.
- if (getWindowConfiguration().getDisplayWindowingMode() != WINDOWING_MODE_FREEFORM) {
+ // Don't persist state if Task Display Area isn't in freeform mode. Then the task will be
+ // launched back to its last state in a freeform Task Display Area when it's launched in a
+ // freeform Task Display Area next time.
+ if (getTaskDisplayArea() == null
+ || getTaskDisplayArea().getWindowingMode() != WINDOWING_MODE_FREEFORM) {
return;
}
@@ -3393,6 +3361,8 @@
&& info.pictureInPictureParams.isLaunchIntoPip()
&& top.getLastParentBeforePip() != null)
? top.getLastParentBeforePip().mTaskId : INVALID_TASK_ID;
+ info.lastParentTaskIdBeforePip = top != null && top.getLastParentBeforePip() != null
+ ? top.getLastParentBeforePip().mTaskId : INVALID_TASK_ID;
info.shouldDockBigOverlays = top != null && top.shouldDockBigOverlays;
info.mTopActivityLocusId = top != null ? top.getLocusId() : null;
diff --git a/services/core/java/com/android/server/wm/TaskFragment.java b/services/core/java/com/android/server/wm/TaskFragment.java
index 7c57dc1..6bc9fa4 100644
--- a/services/core/java/com/android/server/wm/TaskFragment.java
+++ b/services/core/java/com/android/server/wm/TaskFragment.java
@@ -458,6 +458,22 @@
&& organizer.asBinder().equals(mTaskFragmentOrganizer.asBinder());
}
+ /**
+ * Returns the process of organizer if this TaskFragment is organized and the activity lives in
+ * a different process than the organizer.
+ */
+ @Nullable
+ private WindowProcessController getOrganizerProcessIfDifferent(@Nullable ActivityRecord r) {
+ if ((r == null || mTaskFragmentOrganizerProcessName == null)
+ || (mTaskFragmentOrganizerProcessName.equals(r.processName)
+ && mTaskFragmentOrganizerUid == r.getUid())) {
+ // No organizer or the process is the same.
+ return null;
+ }
+ return mAtmService.getProcessController(mTaskFragmentOrganizerProcessName,
+ mTaskFragmentOrganizerUid);
+ }
+
void setAnimationParams(@NonNull TaskFragmentAnimationParams animationParams) {
mAnimationParams = animationParams;
}
@@ -815,6 +831,16 @@
setResumedActivity(record, reason + " - onActivityStateChanged");
mTaskSupervisor.mRecentTasks.add(record.getTask());
}
+
+ // Update the process state for the organizer process if the activity is in a different
+ // process in case the organizer process may not have activity state change in its process.
+ final WindowProcessController hostProcess = getOrganizerProcessIfDifferent(record);
+ if (hostProcess != null) {
+ mTaskSupervisor.onProcessActivityStateChanged(hostProcess, false /* forceBatch */);
+ hostProcess.updateProcessInfo(false /* updateServiceConnectionActivities */,
+ true /* activityChange */, true /* updateOomAdj */,
+ false /* addPendingTopUid */);
+ }
}
/**
@@ -1942,6 +1968,11 @@
addingActivity.inHistory = true;
task.onDescendantActivityAdded(taskHadActivity, activityType, addingActivity);
}
+
+ final WindowProcessController hostProcess = getOrganizerProcessIfDifferent(addingActivity);
+ if (hostProcess != null) {
+ hostProcess.addEmbeddedActivity(addingActivity);
+ }
}
@Override
@@ -2232,8 +2263,8 @@
// task, because they should not be affected by insets.
inOutConfig.smallestScreenWidthDp = (int) (0.5f
+ Math.min(mTmpFullBounds.width(), mTmpFullBounds.height()) / density);
- } else if (windowingMode == WINDOWING_MODE_MULTI_WINDOW
- && isEmbeddedWithBoundsOverride()) {
+ } else if (windowingMode == WINDOWING_MODE_MULTI_WINDOW && mIsEmbedded
+ && insideParentBounds && !resolvedBounds.equals(parentBounds)) {
// For embedded TFs, the smallest width should be updated. Otherwise, inherit
// from the parent task would result in applications loaded wrong resource.
inOutConfig.smallestScreenWidthDp =
@@ -2757,14 +2788,18 @@
void removeChild(WindowContainer child, boolean removeSelfIfPossible) {
super.removeChild(child);
+ final ActivityRecord r = child.asActivityRecord();
if (BackNavigationController.isScreenshotEnabled()) {
//TODO(b/207481538) Remove once the infrastructure to support per-activity screenshot is
// implemented
- ActivityRecord r = child.asActivityRecord();
if (r != null) {
mBackScreenshots.remove(r.mActivityComponent.flattenToString());
}
}
+ final WindowProcessController hostProcess = getOrganizerProcessIfDifferent(r);
+ if (hostProcess != null) {
+ hostProcess.removeEmbeddedActivity(r);
+ }
if (removeSelfIfPossible && shouldRemoveSelfOnLastChildRemoval() && !hasChild()) {
removeImmediately("removeLastChild " + child);
}
diff --git a/services/core/java/com/android/server/wm/TaskOrganizerController.java b/services/core/java/com/android/server/wm/TaskOrganizerController.java
index b131365..93c8c36 100644
--- a/services/core/java/com/android/server/wm/TaskOrganizerController.java
+++ b/services/core/java/com/android/server/wm/TaskOrganizerController.java
@@ -1166,12 +1166,15 @@
}
@Override
- public void setIsIgnoreOrientationRequestDisabled(boolean isDisabled) {
- enforceTaskPermission("setIsIgnoreOrientationRequestDisabled()");
+ public void setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled,
+ @Nullable int[] fromOrientations, @Nullable int[] toOrientations) {
+ enforceTaskPermission("setOrientationRequestPolicy()");
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
- mService.mWindowManager.setIsIgnoreOrientationRequestDisabled(isDisabled);
+ mService.mWindowManager
+ .setOrientationRequestPolicy(isIgnoreOrientationRequestDisabled,
+ fromOrientations, toOrientations);
}
} finally {
Binder.restoreCallingIdentity(origId);
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotCache.java b/services/core/java/com/android/server/wm/TaskSnapshotCache.java
index 55e863e..33486cc 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotCache.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotCache.java
@@ -24,7 +24,7 @@
* <p>
* Access to this class should be guarded by the global window manager lock.
*/
-class TaskSnapshotCache extends AbsAppSnapshotCache<Task> {
+class TaskSnapshotCache extends SnapshotCache<Task> {
private final AppSnapshotLoader mLoader;
diff --git a/services/core/java/com/android/server/wm/TaskSnapshotController.java b/services/core/java/com/android/server/wm/TaskSnapshotController.java
index 679f0f5..4d0bff9 100644
--- a/services/core/java/com/android/server/wm/TaskSnapshotController.java
+++ b/services/core/java/com/android/server/wm/TaskSnapshotController.java
@@ -16,6 +16,7 @@
package com.android.server.wm;
+import static com.android.server.wm.SnapshotController.TASK_CLOSE;
import static com.android.server.wm.WindowManagerDebugConfig.DEBUG_SCREENSHOT;
import static com.android.server.wm.WindowManagerDebugConfig.TAG_WM;
@@ -77,6 +78,13 @@
setSnapshotEnabled(snapshotEnabled);
}
+ void systemReady() {
+ if (!shouldDisableSnapshots()) {
+ mService.mSnapshotController.registerTransitionStateConsumer(TASK_CLOSE,
+ this::handleTaskClose);
+ }
+ }
+
static PersistInfoProvider createPersistInfoProvider(WindowManagerService service,
BaseAppSnapshotPersister.DirectoryResolver resolver) {
final float highResTaskSnapshotScale = service.mContext.getResources().getFloat(
@@ -109,8 +117,21 @@
enableLowResSnapshots, lowResScaleFactor, use16BitFormat);
}
- void onTransitionStarting(DisplayContent displayContent) {
- handleClosingApps(displayContent.mClosingApps);
+ void handleTaskClose(SnapshotController.TransitionState<Task> closeTaskTransitionRecord) {
+ if (shouldDisableSnapshots()) {
+ return;
+ }
+ mTmpTasks.clear();
+ final ArraySet<Task> tasks = closeTaskTransitionRecord.getParticipant(false /* open */);
+ if (mService.mAtmService.getTransitionController().isShellTransitionsEnabled()) {
+ mTmpTasks.addAll(tasks);
+ } else {
+ for (Task task : tasks) {
+ getClosingTasksInner(task, mTmpTasks);
+ }
+ }
+ snapshotTasks(mTmpTasks);
+ mSkipClosingAppSnapshotTasks.clear();
}
/**
@@ -189,18 +210,7 @@
* children, which should be ignored.
*/
@Nullable protected ActivityRecord findAppTokenForSnapshot(Task task) {
- return task.getActivity((r) -> {
- if (r == null || !r.isSurfaceShowing() || r.findMainWindow() == null) {
- return false;
- }
- return r.forAllWindows(
- // Ensure at least one window for the top app is visible before attempting to
- // take a screenshot. Visible here means that the WSA surface is shown and has
- // an alpha greater than 0.
- ws -> ws.mWinAnimator != null && ws.mWinAnimator.getShown()
- && ws.mWinAnimator.mLastAlpha > 0f, true /* traverseTopToBottom */);
-
- });
+ return task.getActivity(ActivityRecord::canCaptureSnapshot);
}
@@ -272,32 +282,22 @@
final Task task = activity.getTask();
if (task == null) continue;
- // Since RecentsAnimation will handle task snapshot while switching apps with the
- // best capture timing (e.g. IME window capture),
- // No need additional task capture while task is controlled by RecentsAnimation.
- if (isAnimatingByRecents(task)) {
- mSkipClosingAppSnapshotTasks.add(task);
- }
- // If the task of the app is not visible anymore, it means no other app in that task
- // is opening. Thus, the task is closing.
- if (!task.isVisible() && !mSkipClosingAppSnapshotTasks.contains(task)) {
- outClosingTasks.add(task);
- }
+ getClosingTasksInner(task, outClosingTasks);
}
}
- /**
- * Called when an {@link ActivityRecord} has been removed.
- */
- void onAppRemoved(ActivityRecord activity) {
- mCache.onAppRemoved(activity);
- }
-
- /**
- * Called when the process of an {@link ActivityRecord} has died.
- */
- void onAppDied(ActivityRecord activity) {
- mCache.onAppDied(activity);
+ void getClosingTasksInner(Task task, ArraySet<Task> outClosingTasks) {
+ // Since RecentsAnimation will handle task snapshot while switching apps with the
+ // best capture timing (e.g. IME window capture),
+ // No need additional task capture while task is controlled by RecentsAnimation.
+ if (isAnimatingByRecents(task)) {
+ mSkipClosingAppSnapshotTasks.add(task);
+ }
+ // If the task of the app is not visible anymore, it means no other app in that task
+ // is opening. Thus, the task is closing.
+ if (!task.isVisible() && !mSkipClosingAppSnapshotTasks.contains(task)) {
+ outClosingTasks.add(task);
+ }
}
void notifyTaskRemovedFromRecents(int taskId, int userId) {
@@ -361,9 +361,4 @@
&& mService.mPolicy.isKeyguardSecure(mService.mCurrentUserId);
snapshotTasks(mTmpTasks, allowSnapshotHome);
}
-
- private boolean isAnimatingByRecents(@NonNull Task task) {
- return task.isAnimatingByRecents()
- || mService.mAtmService.getTransitionController().inRecentsTransition(task);
- }
}
diff --git a/services/core/java/com/android/server/wm/Transition.java b/services/core/java/com/android/server/wm/Transition.java
index 97f48b7..ba49dd0 100644
--- a/services/core/java/com/android/server/wm/Transition.java
+++ b/services/core/java/com/android/server/wm/Transition.java
@@ -278,13 +278,14 @@
setTransientLaunchToChanges(activity);
if (restoreBelow != null) {
+ final Task transientRootTask = activity.getRootTask();
// Collect all visible activities which can be occluded by the transient activity to
// make sure they are in the participants so their visibilities can be updated when
// finishing transition.
((WindowContainer<?>) restoreBelow.getParent()).forAllTasks(t -> {
if (t.isVisibleRequested() && !t.isAlwaysOnTop()
&& !t.getWindowConfiguration().tasksAreFloating()) {
- if (t.isRootTask()) {
+ if (t.isRootTask() && t != transientRootTask) {
mTransientHideTasks.add(t);
}
if (t.isLeafTask()) {
@@ -828,6 +829,7 @@
}
mLogger.mFinishTimeNs = SystemClock.elapsedRealtimeNanos();
mController.mLoggerHandler.post(mLogger::logOnFinish);
+ mController.mTransitionTracer.logFinishedTransition(this);
// Close the transactions now. They were originally copied to Shell in case we needed to
// apply them due to a remote failure. Since we don't need to apply them anymore, free them
// immediately.
@@ -877,8 +879,10 @@
&& mTransientLaunches != null) {
// If transition is transient, then snapshots are taken at end of
// transition.
- mController.mTaskSnapshotController.recordSnapshot(
- task, false /* allowSnapshotHome */);
+ mController.mSnapshotController.mTaskSnapshotController
+ .recordSnapshot(task, false /* allowSnapshotHome */);
+ mController.mSnapshotController.mActivitySnapshotController
+ .notifyAppVisibilityChanged(ar, false /* visible */);
}
ar.commitVisibility(false /* visible */, false /* performLayout */,
true /* fromTransition */);
@@ -1012,6 +1016,7 @@
dc.removeImeSurfaceImmediately();
dc.handleCompleteDeferredRemoval();
}
+ validateVisibility();
mState = STATE_FINISHED;
mController.mTransitionTracer.logState(this);
@@ -1043,6 +1048,7 @@
}
ProtoLog.v(ProtoLogGroup.WM_DEBUG_WINDOW_TRANSITIONS, "Aborting Transition: %d", mSyncId);
mState = STATE_ABORT;
+ mController.mTransitionTracer.logAbortedTransition(this);
// Syncengine abort will call through to onTransactionReady()
mSyncEngine.abort(mSyncId);
mController.dispatchLegacyAppTransitionCancelled();
@@ -1106,12 +1112,13 @@
// needs to be updated for STATE_ABORT.
commitVisibleActivities(transaction);
+ // Fall-back to the default display if there isn't one participating.
+ final DisplayContent primaryDisplay = !mTargetDisplays.isEmpty() ? mTargetDisplays.get(0)
+ : mController.mAtm.mRootWindowContainer.getDefaultDisplay();
+
if (mState == STATE_ABORT) {
mController.abort(this);
- // Fall-back to the default display if there isn't one participating.
- final DisplayContent dc = !mTargetDisplays.isEmpty() ? mTargetDisplays.get(0)
- : mController.mAtm.mRootWindowContainer.getDefaultDisplay();
- dc.getPendingTransaction().merge(transaction);
+ primaryDisplay.getPendingTransaction().merge(transaction);
mSyncId = -1;
mOverrideOptions = null;
cleanUpInternal();
@@ -1123,6 +1130,10 @@
mFinishTransaction = mController.mAtm.mWindowManager.mTransactionFactory.get();
mController.moveToPlaying(this);
+ // Flags must be assigned before calculateTransitionInfo. Otherwise it won't take effect.
+ if (primaryDisplay.isKeyguardLocked()) {
+ mFlags |= TRANSIT_FLAG_KEYGUARD_LOCKED;
+ }
// Check whether the participants were animated from back navigation.
final boolean markBackAnimated = mController.mAtm.mBackNavigationController
.containsBackAnimationTargets(this);
@@ -1136,9 +1147,6 @@
final DisplayContent dc = mController.mAtm.mRootWindowContainer.getDisplayContent(
info.getRoot(i).getDisplayId());
mTargetDisplays.add(dc);
- if (dc.isKeyguardLocked()) {
- mFlags |= TRANSIT_FLAG_KEYGUARD_LOCKED;
- }
}
if (markBackAnimated) {
@@ -1219,13 +1227,7 @@
// transferred. If transition is transient, IME won't be moved during the transition and
// the tasks are still live, so we take the snapshot at the end of the transition instead.
if (mTransientLaunches == null) {
- for (int i = mParticipants.size() - 1; i >= 0; --i) {
- final ActivityRecord ar = mParticipants.valueAt(i).asActivityRecord();
- if (ar == null || ar.isVisibleRequested() || ar.getTask() == null
- || ar.getTask().isVisibleRequested()) continue;
- mController.mTaskSnapshotController.recordSnapshot(
- ar.getTask(), false /* allowSnapshotHome */);
- }
+ mController.mSnapshotController.onTransitionReady(mType, mParticipants);
}
// This is non-null only if display has changes. It handles the visible windows that don't
@@ -1245,8 +1247,7 @@
"Calling onTransitionReady: %s", info);
mLogger.mSendTimeNs = SystemClock.elapsedRealtimeNanos();
mLogger.mInfo = info;
- mController.mTransitionTracer.logSentTransition(
- this, mTargets, mLogger.mCreateTimeNs, mLogger.mSendTimeNs, info);
+ mController.mTransitionTracer.logSentTransition(this, mTargets, info);
mController.getTransitionPlayer().onTransitionReady(
mToken, info, transaction, mFinishTransaction);
if (Trace.isTagEnabled(TRACE_TAG_WINDOW_MANAGER)) {
@@ -1480,9 +1481,9 @@
// then we have to notify KeyguardService directly. This can happen if there is
// another ongoing transition when the app changes occlusion OR if the app dies or
// is killed. Both of these are common during tests.
- final boolean notify = !(transit == TRANSIT_KEYGUARD_OCCLUDE
- || transit == TRANSIT_KEYGUARD_UNOCCLUDE);
- mController.mAtm.mWindowManager.mPolicy.applyKeyguardOcclusionChange(notify);
+ if (transit != TRANSIT_KEYGUARD_OCCLUDE && transit != TRANSIT_KEYGUARD_UNOCCLUDE) {
+ mController.mAtm.mWindowManager.mPolicy.applyKeyguardOcclusionChange();
+ }
}
}
@@ -1920,6 +1921,7 @@
change.setLastParent(info.mStartParent.mRemoteToken.toWindowContainerToken());
}
change.setMode(info.getTransitMode(target));
+ info.mReadyMode = change.getMode();
change.setStartAbsBounds(info.mAbsoluteBounds);
change.setFlags(info.getChangeFlags(target));
change.setDisplayId(info.mDisplayId, getDisplayId(target));
@@ -2177,6 +2179,26 @@
return mainWin.getAttrs().rotationAnimation;
}
+ private void validateVisibility() {
+ for (int i = mTargets.size() - 1; i >= 0; --i) {
+ if (reduceMode(mTargets.get(i).mReadyMode) != TRANSIT_CLOSE) {
+ return;
+ }
+ }
+ // All modes are CLOSE. The surfaces may be hidden by the animation unexpectedly.
+ // If the window container should be visible, then recover it.
+ mController.mStateValidators.add(() -> {
+ for (int i = mTargets.size() - 1; i >= 0; --i) {
+ final ChangeInfo change = mTargets.get(i);
+ if (!change.mContainer.isVisibleRequested()) continue;
+ Slog.e(TAG, "Force show for visible " + change.mContainer
+ + " which may be hidden by transition unexpectedly");
+ change.mContainer.getSyncTransaction().show(change.mContainer.mSurfaceControl);
+ change.mContainer.scheduleAnimation();
+ }
+ });
+ }
+
/** Applies the new configuration for the changed displays. */
void applyDisplayChangeIfNeeded() {
for (int i = mParticipants.size() - 1; i >= 0; --i) {
@@ -2262,6 +2284,10 @@
SurfaceControl mSnapshot;
float mSnapshotLuma;
+ /** The mode which is set when the transition is ready. */
+ @TransitionInfo.TransitionMode
+ int mReadyMode;
+
ChangeInfo(@NonNull WindowContainer origState) {
mContainer = origState;
mVisible = origState.isVisibleRequested();
diff --git a/services/core/java/com/android/server/wm/TransitionController.java b/services/core/java/com/android/server/wm/TransitionController.java
index 86bb6b5..f314b21 100644
--- a/services/core/java/com/android/server/wm/TransitionController.java
+++ b/services/core/java/com/android/server/wm/TransitionController.java
@@ -88,8 +88,9 @@
private WindowProcessController mTransitionPlayerProc;
final ActivityTaskManagerService mAtm;
+
final RemotePlayer mRemotePlayer;
- TaskSnapshotController mTaskSnapshotController;
+ SnapshotController mSnapshotController;
TransitionTracer mTransitionTracer;
private final ArrayList<WindowManagerInternal.AppTransitionListener> mLegacyListeners =
@@ -153,7 +154,7 @@
}
void setWindowManager(WindowManagerService wms) {
- mTaskSnapshotController = wms.mTaskSnapshotController;
+ mSnapshotController = wms.mSnapshotController;
mTransitionTracer = wms.mTransitionTracer;
mIsWaitingForDisplayEnabled = !wms.mDisplayEnabled;
registerLegacyListener(wms.mActivityManagerAppTransitionNotifier);
@@ -739,12 +740,12 @@
t.setEarlyWakeupStart();
// Usually transitions put quite a load onto the system already (with all the things
// happening in app), so pause task snapshot persisting to not increase the load.
- mAtm.mWindowManager.mSnapshotPersistQueue.setPaused(true);
+ mAtm.mWindowManager.mSnapshotController.setPause(true);
mAnimatingState = true;
Trace.asyncTraceBegin(Trace.TRACE_TAG_WINDOW_MANAGER, "transitAnim", 0);
} else if (!animatingState && mAnimatingState) {
t.setEarlyWakeupEnd();
- mAtm.mWindowManager.mSnapshotPersistQueue.setPaused(false);
+ mAtm.mWindowManager.mSnapshotController.setPause(false);
mAnimatingState = false;
Trace.asyncTraceEnd(Trace.TRACE_TAG_WINDOW_MANAGER, "transitAnim", 0);
}
@@ -976,6 +977,8 @@
WindowContainerTransaction mStartWCT;
int mSyncId;
TransitionInfo mInfo;
+ ProtoOutputStream mProtoOutputStream = new ProtoOutputStream();
+ long mProtoToken;
private String buildOnSendLog() {
StringBuilder sb = new StringBuilder("Sent Transition #").append(mSyncId)
diff --git a/services/core/java/com/android/server/wm/TransitionTracer.java b/services/core/java/com/android/server/wm/TransitionTracer.java
index 7b1975d..57c0d65 100644
--- a/services/core/java/com/android/server/wm/TransitionTracer.java
+++ b/services/core/java/com/android/server/wm/TransitionTracer.java
@@ -18,14 +18,6 @@
import static android.os.Build.IS_USER;
-import static com.android.server.wm.shell.ChangeInfo.CHANGE_FLAGS;
-import static com.android.server.wm.shell.ChangeInfo.HAS_CHANGED;
-import static com.android.server.wm.shell.ChangeInfo.TRANSIT_MODE;
-import static com.android.server.wm.shell.ChangeInfo.WINDOWING_MODE;
-import static com.android.server.wm.shell.ChangeInfo.WINDOW_IDENTIFIER;
-import static com.android.server.wm.shell.TransitionInfoChange.LAYER_ID;
-import static com.android.server.wm.shell.TransitionInfoChange.MODE;
-import static com.android.server.wm.shell.TransitionState.CHANGE;
import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER;
import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_H;
import static com.android.server.wm.shell.TransitionTraceProto.MAGIC_NUMBER_L;
@@ -66,20 +58,67 @@
/**
* Records key information about a transition that has been sent to Shell to be played.
+ * More information will be appended to the same proto object once the transition is finished or
+ * aborted.
+ * Transition information won't be added to the trace buffer until
+ * {@link #logFinishedTransition} or {@link #logAbortedTransition} is called for this
+ * transition.
+ *
* @param transition The transition that has been sent to Shell.
* @param targets Information about the target windows of the transition.
- * @param createTimeNs System elapsed time (nanoseconds since boot including sleep time) at
- * which the transition to be recorded was created.
- * @param sendTimeNs System elapsed time (nanoseconds since boot including sleep time) at which
- * @param info
+ * @param info The TransitionInfo send over to Shell to execute the transition.
*/
public void logSentTransition(Transition transition, ArrayList<ChangeInfo> targets,
- long createTimeNs, long sendTimeNs, TransitionInfo info) {
- mTraceBuffer.pushSentTransition(transition, targets, createTimeNs, sendTimeNs);
+ TransitionInfo info) {
+ // Dump the info to proto that will not be available when the transition finishes or
+ // is canceled
+ final ProtoOutputStream outputStream = transition.mLogger.mProtoOutputStream;
+ transition.mLogger.mProtoToken = outputStream
+ .start(com.android.server.wm.shell.TransitionTraceProto.FINISHED_TRANSITIONS);
+ outputStream.write(com.android.server.wm.shell.Transition.START_TRANSACTION_ID,
+ transition.getStartTransaction().getId());
+ outputStream.write(com.android.server.wm.shell.Transition.FINISH_TRANSACTION_ID,
+ transition.getFinishTransaction().getId());
+ dumpTransitionTargetsToProto(outputStream, transition, targets);
+
logTransitionInfo(transition, info);
}
/**
+ * Completes the information dumped in {@link #logSentTransition} for a transition
+ * that has finished or aborted, and add the proto object to the trace buffer.
+ *
+ * @param transition The transition that has finished.
+ */
+ public void logFinishedTransition(Transition transition) {
+ if (transition.mLogger.mProtoToken == 0) {
+ // Transition finished but never sent, so open token never added
+ final ProtoOutputStream outputStream = transition.mLogger.mProtoOutputStream;
+ transition.mLogger.mProtoToken = outputStream
+ .start(com.android.server.wm.shell.TransitionTraceProto.FINISHED_TRANSITIONS);
+ }
+
+ // Dump the rest of the transition's info that wasn't dumped during logSentTransition
+ dumpFinishedTransitionToProto(transition.mLogger.mProtoOutputStream, transition);
+ transition.mLogger.mProtoOutputStream.end(transition.mLogger.mProtoToken);
+ mTraceBuffer.pushTransitionProto(transition.mLogger.mProtoOutputStream);
+ }
+
+ /**
+ * Same as {@link #logFinishedTransition} but don't add the transition to the trace buffer
+ * unless actively tracing.
+ *
+ * @param transition The transition that has been aborted
+ */
+ public void logAbortedTransition(Transition transition) {
+ // We don't care about aborted transitions unless actively tracing
+ if (!mActiveTracingEnabled) {
+ return;
+ }
+ logFinishedTransition(transition);
+ }
+
+ /**
* Records the current state of a transition in the transition trace (if it is running).
* @param transition the transition that we want to record the state of.
*/
@@ -87,7 +126,9 @@
if (!mActiveTracingEnabled) {
return;
}
- mTraceBuffer.pushTransitionState(transition);
+ final ProtoOutputStream outputStream = new ProtoOutputStream();
+ dumpTransitionStateToProto(outputStream, transition);
+ mTraceBuffer.pushTransitionState(outputStream);
}
/**
@@ -99,171 +140,180 @@
if (!mActiveTracingEnabled) {
return;
}
- mTraceBuffer.pushTransitionInfo(transition, info);
+ final ProtoOutputStream outputStream = new ProtoOutputStream();
+ dumpTransitionInfoToProto(outputStream, transition, info);
+ mTraceBuffer.pushTransitionInfo(outputStream);
+ }
+
+ private void dumpTransitionTargetsToProto(ProtoOutputStream outputStream,
+ Transition transition, ArrayList<ChangeInfo> targets) {
+ Trace.beginSection("TransitionTracer#dumpTransitionTargetsToProto");
+ if (mActiveTracingEnabled) {
+ outputStream.write(com.android.server.wm.shell.Transition.ID,
+ transition.getSyncId());
+ }
+
+ outputStream.write(com.android.server.wm.shell.Transition.TYPE, transition.mType);
+
+ for (int i = 0; i < targets.size(); ++i) {
+ final long changeToken = outputStream
+ .start(com.android.server.wm.shell.Transition.TARGETS);
+
+ final Transition.ChangeInfo target = targets.get(i);
+
+ final int mode = target.getTransitMode(target.mContainer);
+ final int layerId;
+ if (target.mContainer.mSurfaceControl.isValid()) {
+ layerId = target.mContainer.mSurfaceControl.getLayerId();
+ } else {
+ layerId = -1;
+ }
+
+ outputStream.write(com.android.server.wm.shell.Target.MODE, mode);
+ outputStream.write(com.android.server.wm.shell.Target.LAYER_ID, layerId);
+
+ if (mActiveTracingEnabled) {
+ // What we use in the WM trace
+ final int windowId = System.identityHashCode(target.mContainer);
+ outputStream.write(com.android.server.wm.shell.Target.WINDOW_ID, windowId);
+ }
+
+ outputStream.end(changeToken);
+ }
+
+ Trace.endSection();
+ }
+
+ private void dumpFinishedTransitionToProto(
+ ProtoOutputStream outputStream,
+ Transition transition
+ ) {
+ Trace.beginSection("TransitionTracer#dumpFinishedTransitionToProto");
+
+ outputStream.write(com.android.server.wm.shell.Transition.CREATE_TIME_NS,
+ transition.mLogger.mCreateTimeNs);
+ outputStream.write(com.android.server.wm.shell.Transition.SEND_TIME_NS,
+ transition.mLogger.mSendTimeNs);
+ outputStream.write(com.android.server.wm.shell.Transition.FINISH_TIME_NS,
+ transition.mLogger.mFinishTimeNs);
+
+ Trace.endSection();
+ }
+
+ private void dumpTransitionStateToProto(ProtoOutputStream outputStream, Transition transition) {
+ Trace.beginSection("TransitionTracer#dumpTransitionStateToProto");
+
+ final long stateToken = outputStream
+ .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITION_STATES);
+
+ outputStream.write(com.android.server.wm.shell.TransitionState.TIME_NS,
+ SystemClock.elapsedRealtimeNanos());
+ outputStream.write(com.android.server.wm.shell.TransitionState.TRANSITION_ID,
+ transition.getSyncId());
+ outputStream.write(com.android.server.wm.shell.TransitionState.TRANSITION_TYPE,
+ transition.mType);
+ outputStream.write(com.android.server.wm.shell.TransitionState.STATE,
+ transition.getState());
+ outputStream.write(com.android.server.wm.shell.TransitionState.FLAGS,
+ transition.getFlags());
+
+ for (int i = 0; i < transition.mChanges.size(); ++i) {
+ final WindowContainer window = transition.mChanges.keyAt(i);
+ final ChangeInfo changeInfo = transition.mChanges.valueAt(i);
+ dumpChangeInfoToProto(outputStream, window, changeInfo);
+ }
+
+ for (int i = 0; i < transition.mParticipants.size(); ++i) {
+ final WindowContainer window = transition.mParticipants.valueAt(i);
+ window.writeIdentifierToProto(outputStream,
+ com.android.server.wm.shell.TransitionState.PARTICIPANTS);
+ }
+
+ outputStream.end(stateToken);
+ Trace.endSection();
+ }
+
+ private void dumpChangeInfoToProto(ProtoOutputStream outputStream, WindowContainer window,
+ ChangeInfo changeInfo) {
+ Trace.beginSection("TransitionTraceBuffer#writeChange");
+ final long changeEntryToken =
+ outputStream.start(com.android.server.wm.shell.TransitionState.CHANGE);
+
+ final int transitMode = changeInfo.getTransitMode(window);
+ final boolean hasChanged = changeInfo.hasChanged();
+ final int changeFlags = changeInfo.getChangeFlags(window);
+ final int windowingMode = changeInfo.mWindowingMode;
+
+ outputStream.write(com.android.server.wm.shell.ChangeInfo.TRANSIT_MODE, transitMode);
+ outputStream.write(com.android.server.wm.shell.ChangeInfo.HAS_CHANGED, hasChanged);
+ outputStream.write(com.android.server.wm.shell.ChangeInfo.CHANGE_FLAGS, changeFlags);
+ outputStream.write(com.android.server.wm.shell.ChangeInfo.WINDOWING_MODE, windowingMode);
+ window.writeIdentifierToProto(
+ outputStream, com.android.server.wm.shell.ChangeInfo.WINDOW_IDENTIFIER);
+
+ outputStream.end(changeEntryToken);
+ Trace.endSection();
+ }
+
+ private void dumpTransitionInfoToProto(ProtoOutputStream outputStream,
+ Transition transition, TransitionInfo info) {
+ Trace.beginSection("TransitionTracer#dumpTransitionInfoToProto");
+ final long transitionInfoToken = outputStream
+ .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITION_INFO);
+
+ outputStream.write(com.android.server.wm.shell.TransitionInfo.TRANSITION_ID,
+ transition.getSyncId());
+ for (int i = 0; i < info.getChanges().size(); ++i) {
+ TransitionInfo.Change change = info.getChanges().get(i);
+ dumpTransitionInfoChangeToProto(outputStream, change);
+ }
+
+ outputStream.end(transitionInfoToken);
+ Trace.endSection();
+ }
+
+ private void dumpTransitionInfoChangeToProto(
+ ProtoOutputStream outputStream,
+ TransitionInfo.Change change
+ ) {
+ Trace.beginSection("TransitionTracer#dumpTransitionInfoChangeToProto");
+ final long changeEntryToken = outputStream
+ .start(com.android.server.wm.shell.TransitionInfo.CHANGE);
+
+ outputStream.write(com.android.server.wm.shell.TransitionInfoChange.LAYER_ID,
+ change.getLeash().getLayerId());
+ outputStream.write(com.android.server.wm.shell.TransitionInfoChange.MODE, change.getMode());
+
+ outputStream.end(changeEntryToken);
+ Trace.endSection();
}
private class TransitionTraceBuffer {
- private final TraceBuffer mBuffer = new TraceBuffer(ALWAYS_ON_TRACING_CAPACITY);
+ private final TraceBuffer mTransitionBuffer = new TraceBuffer(ALWAYS_ON_TRACING_CAPACITY);
private final TraceBuffer mStateBuffer = new TraceBuffer(ACTIVE_TRACING_BUFFER_CAPACITY);
private final TraceBuffer mTransitionInfoBuffer =
new TraceBuffer(ACTIVE_TRACING_BUFFER_CAPACITY);
- public void pushSentTransition(
- Transition transition,
- ArrayList<ChangeInfo> targets,
- long createTimeNs,
- long sendTimeNs
- ) {
- Trace.beginSection("TransitionTraceBuffer#pushSentTransition");
- final ProtoOutputStream outputStream = new ProtoOutputStream();
- final long transitionToken = outputStream
- .start(com.android.server.wm.shell.TransitionTraceProto.SENT_TRANSITIONS);
-
- if (mActiveTracingEnabled) {
- outputStream.write(com.android.server.wm.shell.Transition.ID,
- transition.getSyncId());
- }
-
- outputStream.write(com.android.server.wm.shell.Transition.START_TRANSACTION_ID,
- transition.getStartTransaction().getId());
- outputStream.write(com.android.server.wm.shell.Transition.FINISH_TRANSACTION_ID,
- transition.getFinishTransaction().getId());
-
- outputStream.write(com.android.server.wm.shell.Transition.CREATE_TIME_NS, createTimeNs);
- outputStream.write(com.android.server.wm.shell.Transition.SEND_TIME_NS, sendTimeNs);
-
- for (int i = 0; i < targets.size(); ++i) {
- final long changeToken = outputStream
- .start(com.android.server.wm.shell.Transition.TARGETS);
-
- final Transition.ChangeInfo target = targets.get(i);
-
- final int mode = target.getTransitMode(target.mContainer);
- final int layerId;
- if (target.mContainer.mSurfaceControl.isValid()) {
- layerId = target.mContainer.mSurfaceControl.getLayerId();
- } else {
- layerId = -1;
- }
-
- outputStream.write(com.android.server.wm.shell.Target.MODE, mode);
- outputStream.write(com.android.server.wm.shell.Target.LAYER_ID, layerId);
-
- if (mActiveTracingEnabled) {
- // What we use in the WM trace
- final int windowId = System.identityHashCode(target.mContainer);
- outputStream.write(com.android.server.wm.shell.Target.WINDOW_ID, windowId);
- }
-
- outputStream.end(changeToken);
- }
-
- outputStream.end(transitionToken);
- mBuffer.add(outputStream);
-
- Trace.endSection();
+ private void pushTransitionProto(ProtoOutputStream outputStream) {
+ mTransitionBuffer.add(outputStream);
}
- private void pushTransitionState(Transition transition) {
- Trace.beginSection("TransitionTraceBuffer#pushTransitionState");
- final ProtoOutputStream outputStream = new ProtoOutputStream();
- final long stateToken = outputStream
- .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITION_STATES);
-
- outputStream.write(com.android.server.wm.shell.TransitionState.TIME_NS,
- SystemClock.elapsedRealtimeNanos());
- outputStream.write(com.android.server.wm.shell.TransitionState.TRANSITION_ID,
- transition.getSyncId());
- outputStream.write(com.android.server.wm.shell.TransitionState.TRANSITION_TYPE,
- transition.mType);
- outputStream.write(com.android.server.wm.shell.TransitionState.STATE,
- transition.getState());
- outputStream.write(com.android.server.wm.shell.TransitionState.FLAGS,
- transition.getFlags());
-
- for (int i = 0; i < transition.mChanges.size(); ++i) {
- final WindowContainer window = transition.mChanges.keyAt(i);
- final ChangeInfo changeInfo = transition.mChanges.valueAt(i);
- writeChange(outputStream, window, changeInfo);
- }
-
- for (int i = 0; i < transition.mChanges.size(); ++i) {
- final WindowContainer window = transition.mChanges.keyAt(i);
- final ChangeInfo changeInfo = transition.mChanges.valueAt(i);
- writeChange(outputStream, window, changeInfo);
- }
-
- for (int i = 0; i < transition.mParticipants.size(); ++i) {
- final WindowContainer window = transition.mParticipants.valueAt(i);
- window.writeIdentifierToProto(outputStream,
- com.android.server.wm.shell.TransitionState.PARTICIPANTS);
- }
-
- outputStream.end(stateToken);
-
+ private void pushTransitionState(ProtoOutputStream outputStream) {
mStateBuffer.add(outputStream);
- Trace.endSection();
}
- private void pushTransitionInfo(Transition transition, TransitionInfo info) {
- Trace.beginSection("TransitionTraceBuffer#pushTransitionInfo");
- final ProtoOutputStream outputStream = new ProtoOutputStream();
- final long transitionInfoToken = outputStream
- .start(com.android.server.wm.shell.TransitionTraceProto.TRANSITION_INFO);
-
- outputStream.write(com.android.server.wm.shell.TransitionInfo.TRANSITION_ID,
- transition.getSyncId());
- for (int i = 0; i < info.getChanges().size(); ++i) {
- TransitionInfo.Change change = info.getChanges().get(i);
- writeTransitionInfoChange(outputStream, change);
- }
-
- outputStream.end(transitionInfoToken);
+ private void pushTransitionInfo(ProtoOutputStream outputStream) {
mTransitionInfoBuffer.add(outputStream);
- Trace.endSection();
- }
-
- private void writeChange(ProtoOutputStream outputStream, WindowContainer window,
- ChangeInfo changeInfo) {
- Trace.beginSection("TransitionTraceBuffer#writeChange");
- final long changeEntryToken = outputStream.start(CHANGE);
-
- final int transitMode = changeInfo.getTransitMode(window);
- final boolean hasChanged = changeInfo.hasChanged();
- final int changeFlags = changeInfo.getChangeFlags(window);
- final int windowingMode = changeInfo.mWindowingMode;
-
- outputStream.write(TRANSIT_MODE, transitMode);
- outputStream.write(HAS_CHANGED, hasChanged);
- outputStream.write(CHANGE_FLAGS, changeFlags);
- outputStream.write(WINDOWING_MODE, windowingMode);
- window.writeIdentifierToProto(outputStream, WINDOW_IDENTIFIER);
-
- outputStream.end(changeEntryToken);
- Trace.endSection();
- }
-
- private void writeTransitionInfoChange(
- ProtoOutputStream outputStream,
- TransitionInfo.Change change
- ) {
- Trace.beginSection("TransitionTraceBuffer#writeTransitionInfoChange");
- final long changeEntryToken = outputStream
- .start(com.android.server.wm.shell.TransitionInfo.CHANGE);
-
- outputStream.write(LAYER_ID, change.getLeash().getLayerId());
- outputStream.write(MODE, change.getMode());
-
- outputStream.end(changeEntryToken);
- Trace.endSection();
}
public void writeToFile(File file, ProtoOutputStream proto) throws IOException {
- mBuffer.writeTraceToFile(file, proto);
+ mTransitionBuffer.writeTraceToFile(file, proto);
}
public void reset() {
- mBuffer.resetBuffer();
+ mTransitionBuffer.resetBuffer();
+ mStateBuffer.resetBuffer();
+ mTransitionInfoBuffer.resetBuffer();
}
}
@@ -280,7 +330,7 @@
LogAndPrintln.i(pw, "Starting shell transition trace.");
synchronized (mEnabledLock) {
mActiveTracingEnabled = true;
- mTraceBuffer.mBuffer.setCapacity(ACTIVE_TRACING_BUFFER_CAPACITY);
+ mTraceBuffer.mTransitionBuffer.setCapacity(ACTIVE_TRACING_BUFFER_CAPACITY);
mTraceBuffer.reset();
}
Trace.endSection();
@@ -309,7 +359,8 @@
synchronized (mEnabledLock) {
mActiveTracingEnabled = false;
writeTraceToFileLocked(pw, outputFile);
- mTraceBuffer.mBuffer.setCapacity(ALWAYS_ON_TRACING_CAPACITY);
+ mTraceBuffer.reset();
+ mTraceBuffer.mTransitionBuffer.setCapacity(ALWAYS_ON_TRACING_CAPACITY);
}
Trace.endSection();
}
diff --git a/services/core/java/com/android/server/wm/WallpaperController.java b/services/core/java/com/android/server/wm/WallpaperController.java
index 2b848d5..0b9ceea 100644
--- a/services/core/java/com/android/server/wm/WallpaperController.java
+++ b/services/core/java/com/android/server/wm/WallpaperController.java
@@ -163,14 +163,6 @@
if (DEBUG_WALLPAPER) Slog.v(TAG, "Win " + w + ": isOnScreen=" + w.isOnScreen()
+ " mDrawState=" + w.mWinAnimator.mDrawState);
- if (w.mWillReplaceWindow && mWallpaperTarget == null
- && !mFindResults.useTopWallpaperAsTarget) {
- // When we are replacing a window and there was wallpaper before replacement, we want to
- // keep the window until the new windows fully appear and can determine the visibility,
- // to avoid flickering.
- mFindResults.setUseTopWallpaperAsTarget(true);
- }
-
final WindowContainer animatingContainer = w.mActivityRecord != null
? w.mActivityRecord.getAnimatingContainer() : null;
final boolean keyguardGoingAwayWithWallpaper = (animatingContainer != null
diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java
index c11391e..10bedd4 100644
--- a/services/core/java/com/android/server/wm/WindowAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowAnimator.java
@@ -69,10 +69,6 @@
SparseArray<DisplayContentsAnimator> mDisplayContentsAnimators = new SparseArray<>(2);
private boolean mInitialized = false;
- // When set to true the animator will go over all windows after an animation frame is posted and
- // check if some got replaced and can be removed.
- private boolean mRemoveReplacedWindows = false;
-
private Choreographer mChoreographer;
/**
@@ -204,11 +200,11 @@
| ANIMATION_TYPE_RECENTS /* typesToCheck */);
if (runningExpensiveAnimations && !mRunningExpensiveAnimations) {
// Usually app transitions put quite a load onto the system already (with all the things
- // happening in app), so pause task snapshot persisting to not increase the load.
- mService.mSnapshotPersistQueue.setPaused(true);
+ // happening in app), so pause snapshot persisting to not increase the load.
+ mService.mSnapshotController.setPause(true);
mTransaction.setEarlyWakeupStart();
} else if (!runningExpensiveAnimations && mRunningExpensiveAnimations) {
- mService.mSnapshotPersistQueue.setPaused(false);
+ mService.mSnapshotController.setPause(false);
mTransaction.setEarlyWakeupEnd();
}
mRunningExpensiveAnimations = runningExpensiveAnimations;
@@ -217,11 +213,6 @@
mService.closeSurfaceTransaction("WindowAnimator");
ProtoLog.i(WM_SHOW_TRANSACTIONS, "<<< CLOSE TRANSACTION animate");
- if (mRemoveReplacedWindows) {
- root.removeReplacedWindows();
- mRemoveReplacedWindows = false;
- }
-
mService.mAtmService.mTaskOrganizerController.dispatchPendingEvents();
executeAfterPrepareSurfacesRunnables();
@@ -286,10 +277,6 @@
return displayAnimator;
}
- void requestRemovalOfReplacedWindows(WindowState win) {
- mRemoveReplacedWindows = true;
- }
-
void scheduleAnimation() {
if (!mAnimationFrameCallbackScheduled) {
mAnimationFrameCallbackScheduled = true;
diff --git a/services/core/java/com/android/server/wm/WindowManagerInternal.java b/services/core/java/com/android/server/wm/WindowManagerInternal.java
index 2f3a70e..969afe5 100644
--- a/services/core/java/com/android/server/wm/WindowManagerInternal.java
+++ b/services/core/java/com/android/server/wm/WindowManagerInternal.java
@@ -740,7 +740,7 @@
/**
* Show IME on imeTargetWindow once IME has finished layout.
*
- * @param imeTargetWindowToken token of the (IME target) window on which IME should be shown.
+ * @param imeTargetWindowToken token of the (IME target) window which IME should be shown.
* @param statsToken the token tracking the current IME show request or {@code null} otherwise.
*/
public abstract void showImePostLayout(IBinder imeTargetWindowToken,
@@ -749,7 +749,7 @@
/**
* Hide IME using imeTargetWindow when requested.
*
- * @param imeTargetWindowToken token of the (IME target) window on which IME should be hidden.
+ * @param imeTargetWindowToken token of the (IME target) window on which requests hiding IME.
* @param displayId the id of the display the IME is on.
* @param statsToken the token tracking the current IME hide request or {@code null} otherwise.
*/
diff --git a/services/core/java/com/android/server/wm/WindowManagerService.java b/services/core/java/com/android/server/wm/WindowManagerService.java
index a81f1a8..2a028c9 100644
--- a/services/core/java/com/android/server/wm/WindowManagerService.java
+++ b/services/core/java/com/android/server/wm/WindowManagerService.java
@@ -88,7 +88,6 @@
import static android.view.WindowManager.LayoutParams.TYPE_WALLPAPER;
import static android.view.WindowManager.REMOVE_CONTENT_MODE_UNDEFINED;
import static android.view.WindowManager.TRANSIT_NONE;
-import static android.view.WindowManager.TRANSIT_RELAUNCH;
import static android.view.WindowManager.TRANSIT_TO_FRONT;
import static android.view.WindowManager.fixScale;
import static android.view.WindowManagerGlobal.ADD_OKAY;
@@ -238,6 +237,7 @@
import android.util.Pair;
import android.util.Slog;
import android.util.SparseBooleanArray;
+import android.util.SparseIntArray;
import android.util.TimeUtils;
import android.util.TypedValue;
import android.util.proto.ProtoOutputStream;
@@ -382,9 +382,6 @@
/** Amount of time (in milliseconds) to delay before declaring a window freeze timeout. */
static final int WINDOW_FREEZE_TIMEOUT_DURATION = 2000;
- /** Amount of time (in milliseconds) to delay before declaring a window replacement timeout. */
- static final int WINDOW_REPLACEMENT_TIMEOUT_DURATION = 2000;
-
/** Amount of time to allow a last ANR message to exist before freeing the memory. */
static final int LAST_ANR_LIFETIME_DURATION_MSECS = 2 * 60 * 60 * 1000; // Two hours
@@ -565,12 +562,6 @@
final WindowManagerGlobalLock mGlobalLock;
/**
- * List of app window tokens that are waiting for replacing windows. If the
- * replacement doesn't come in time the stale windows needs to be disposed of.
- */
- final ArrayList<ActivityRecord> mWindowReplacementTimeouts = new ArrayList<>();
-
- /**
* Windows that are being resized. Used so we can tell the client about
* the resize after closing the transaction in which we resized the
* underlying surface.
@@ -604,6 +595,13 @@
/** List of window currently causing non-system overlay windows to be hidden. */
private ArrayList<WindowState> mHidingNonSystemOverlayWindows = new ArrayList<>();
+ /**
+ * In some cases (e.g. when {@link R.bool.config_reverseDefaultRotation} has value
+ * {@value true}) we need to map some orientation to others. This {@link SparseIntArray}
+ * contains the relation between the source orientation and the one to use.
+ */
+ private final SparseIntArray mOrientationMapping = new SparseIntArray();
+
final AccessibilityController mAccessibilityController;
private RecentsAnimationController mRecentsAnimationController;
@@ -691,8 +689,8 @@
// changes the orientation.
private final PowerManager.WakeLock mScreenFrozenLock;
- final SnapshotPersistQueue mSnapshotPersistQueue;
final TaskSnapshotController mTaskSnapshotController;
+ final SnapshotController mSnapshotController;
final BlurController mBlurController;
final TaskFpsCallbackController mTaskFpsCallbackController;
@@ -1202,8 +1200,8 @@
mSyncEngine = new BLASTSyncEngine(this);
mWindowPlacerLocked = new WindowSurfacePlacer(this);
- mSnapshotPersistQueue = new SnapshotPersistQueue();
- mTaskSnapshotController = new TaskSnapshotController(this, mSnapshotPersistQueue);
+ mSnapshotController = new SnapshotController(this);
+ mTaskSnapshotController = mSnapshotController.mTaskSnapshotController;
mWindowTracing = WindowTracing.createDefaultAndStartLooper(this,
Choreographer.getInstance());
@@ -1774,15 +1772,6 @@
final WindowStateAnimator winAnimator = win.mWinAnimator;
winAnimator.mEnterAnimationPending = true;
winAnimator.mEnteringAnimation = true;
- // Check if we need to prepare a transition for replacing window first.
- if (!win.mTransitionController.isShellTransitionsEnabled()
- && activity != null && activity.isVisible()
- && !prepareWindowReplacementTransition(activity)) {
- // If not, check if need to set up a dummy transition during display freeze
- // so that the unfreeze wait for the apps to draw. This might be needed if
- // the app is relaunching.
- prepareNoneTransitionForRelaunching(activity);
- }
if (displayPolicy.areSystemBarsForcedConsumedLw()) {
res |= WindowManagerGlobal.ADD_FLAG_ALWAYS_CONSUME_SYSTEM_BARS;
@@ -1944,48 +1933,6 @@
}
/**
- * Returns true if we're done setting up any transitions.
- */
- private boolean prepareWindowReplacementTransition(ActivityRecord activity) {
- activity.clearAllDrawn();
- final WindowState replacedWindow = activity.getReplacingWindow();
- if (replacedWindow == null) {
- // We expect to already receive a request to remove the old window. If it did not
- // happen, let's just simply add a window.
- return false;
- }
- // We use the visible frame, because we want the animation to morph the window from what
- // was visible to the user to the final destination of the new window.
- final Rect frame = new Rect(replacedWindow.getFrame());
- final WindowManager.LayoutParams attrs = replacedWindow.mAttrs;
- frame.inset(replacedWindow.getInsetsStateWithVisibilityOverride().calculateVisibleInsets(
- frame, attrs.type, replacedWindow.getWindowingMode(), attrs.softInputMode,
- attrs.flags));
- // We treat this as if this activity was opening, so we can trigger the app transition
- // animation and piggy-back on existing transition animation infrastructure.
- final DisplayContent dc = activity.getDisplayContent();
- dc.mOpeningApps.add(activity);
- dc.prepareAppTransition(TRANSIT_RELAUNCH);
- dc.mAppTransition.overridePendingAppTransitionClipReveal(frame.left, frame.top,
- frame.width(), frame.height());
- dc.executeAppTransition();
- return true;
- }
-
- private void prepareNoneTransitionForRelaunching(ActivityRecord activity) {
- // Set up a none-transition and add the app to opening apps, so that the display
- // unfreeze wait for the apps to be drawn.
- // Note that if the display unfroze already because app unfreeze timed out,
- // we don't set up the transition anymore and just let it go.
- final DisplayContent dc = activity.getDisplayContent();
- if (mDisplayFrozen && !dc.mOpeningApps.contains(activity) && activity.isRelaunching()) {
- dc.mOpeningApps.add(activity);
- dc.prepareAppTransition(TRANSIT_NONE);
- dc.executeAppTransition();
- }
- }
-
- /**
* Set whether screen capture is disabled for all windows of a specific user from
* the device policy cache.
*/
@@ -2390,12 +2337,6 @@
// If we are not currently running the exit animation, we need to see about starting
// one.
- // We don't want to animate visibility of windows which are pending replacement.
- // In the case of activity relaunch child windows could request visibility changes as
- // they are detached from the main application window during the tear down process.
- // If we satisfied these visibility changes though, we would cause a visual glitch
- // hiding the window before it's replacement was available. So we just do nothing on
- // our side.
// This must be called before the call to performSurfacePlacement.
if (!shouldRelayout && winAnimator.hasSurface() && !win.mAnimatingExit) {
if (DEBUG_VISIBILITY) {
@@ -2403,20 +2344,18 @@
"Relayout invis " + win + ": mAnimatingExit=" + win.mAnimatingExit);
}
result |= RELAYOUT_RES_SURFACE_CHANGED;
- if (!win.mWillReplaceWindow) {
- // When FLAG_SHOW_WALLPAPER flag is removed from a window, we usually set a flag
- // in DC#pendingLayoutChanges and update the wallpaper target later.
- // However it's possible that FLAG_SHOW_WALLPAPER flag is removed from a window
- // when the window is about to exit, so we update the wallpaper target
- // immediately here. Otherwise this window will be stuck in exiting and its
- // surface remains on the screen.
- // TODO(b/189856716): Allow destroying surface even if it belongs to the
- // keyguard target.
- if (wallpaperMayMove) {
- displayContent.mWallpaperController.adjustWallpaperWindows();
- }
- tryStartExitingAnimation(win, winAnimator);
+ // When FLAG_SHOW_WALLPAPER flag is removed from a window, we usually set a flag
+ // in DC#pendingLayoutChanges and update the wallpaper target later.
+ // However it's possible that FLAG_SHOW_WALLPAPER flag is removed from a window
+ // when the window is about to exit, so we update the wallpaper target
+ // immediately here. Otherwise this window will be stuck in exiting and its
+ // surface remains on the screen.
+ // TODO(b/189856716): Allow destroying surface even if it belongs to the
+ // keyguard target.
+ if (wallpaperMayMove) {
+ displayContent.mWallpaperController.adjustWallpaperWindows();
}
+ tryStartExitingAnimation(win, winAnimator);
}
// Create surfaceControl before surface placement otherwise layout will be skipped
@@ -3267,15 +3206,13 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.DISABLE_KEYGUARD)
/**
* @see android.app.KeyguardManager#exitKeyguardSecurely
*/
@Override
public void exitKeyguardSecurely(final IOnKeyguardExitResult callback) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DISABLE_KEYGUARD)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Requires DISABLE_KEYGUARD permission");
- }
+ exitKeyguardSecurely_enforcePermission();
if (callback == null) {
throw new IllegalArgumentException("callback == null");
@@ -4180,25 +4117,52 @@
/**
* Controls whether ignore orientation request logic in {@link DisplayArea} is disabled
- * at runtime.
+ * at runtime and how to optionally map some requested orientations to others.
*
* <p>Note: this assumes that {@link #mGlobalLock} is held by the caller.
*
- * @param isDisabled when {@code true}, the system always ignores the value of {@link
- * DisplayArea#getIgnoreOrientationRequest} and app requested orientation is
- * respected.
+ * @param isIgnoreOrientationRequestDisabled when {@code true}, the system always ignores the
+ * value of {@link DisplayArea#getIgnoreOrientationRequest} and app requested
+ * orientation is respected.
+ * @param fromOrientations The orientations we want to map to the correspondent orientations
+ * in toOrientation.
+ * @param toOrientations The orientations we map to the ones in fromOrientations at the same
+ * index
*/
- void setIsIgnoreOrientationRequestDisabled(boolean isDisabled) {
- if (isDisabled == mIsIgnoreOrientationRequestDisabled) {
+ void setOrientationRequestPolicy(boolean isIgnoreOrientationRequestDisabled,
+ @Nullable int[] fromOrientations, @Nullable int[] toOrientations) {
+ mOrientationMapping.clear();
+ if (fromOrientations != null && toOrientations != null
+ && fromOrientations.length == toOrientations.length) {
+ for (int i = 0; i < fromOrientations.length; i++) {
+ mOrientationMapping.put(fromOrientations[i], toOrientations[i]);
+ }
+ }
+ if (isIgnoreOrientationRequestDisabled == mIsIgnoreOrientationRequestDisabled) {
return;
}
- mIsIgnoreOrientationRequestDisabled = isDisabled;
+ mIsIgnoreOrientationRequestDisabled = isIgnoreOrientationRequestDisabled;
for (int i = mRoot.getChildCount() - 1; i >= 0; i--) {
mRoot.getChildAt(i).onIsIgnoreOrientationRequestDisabledChanged();
}
}
/**
+ * When {@link mIsIgnoreOrientationRequestDisabled} is {@value true} this method returns the
+ * orientation to use in place of the one in input. It returns the same requestedOrientation in
+ * input otherwise.
+ *
+ * @param requestedOrientation The orientation that can be mapped.
+ * @return The orientation to use in place of requestedOrientation.
+ */
+ int mapOrientationRequest(int requestedOrientation) {
+ if (!mIsIgnoreOrientationRequestDisabled) {
+ return requestedOrientation;
+ }
+ return mOrientationMapping.get(requestedOrientation, requestedOrientation);
+ }
+
+ /**
* Whether the system ignores the value of {@link DisplayArea#getIgnoreOrientationRequest} and
* app requested orientation is respected.
*
@@ -4405,13 +4369,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APP_TOKENS)
@Override
public SurfaceControl addShellRoot(int displayId, IWindow client,
@WindowManager.ShellRootLayer int shellRootLayer) {
- if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
- }
+ addShellRoot_enforcePermission();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -4426,13 +4388,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APP_TOKENS)
@Override
public void setShellRootAccessibilityWindow(int displayId,
@WindowManager.ShellRootLayer int shellRootLayer, IWindow target) {
- if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
- }
+ setShellRootAccessibilityWindow_enforcePermission();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -4451,13 +4411,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APP_TOKENS)
@Override
public void setDisplayWindowInsetsController(
int displayId, IDisplayWindowInsetsController insetsController) {
- if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
- }
+ setDisplayWindowInsetsController_enforcePermission();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -4472,13 +4430,11 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.MANAGE_APP_TOKENS)
@Override
public void updateDisplayWindowRequestedVisibleTypes(
int displayId, @InsetsType int requestedVisibleTypes) {
- if (mContext.checkCallingOrSelfPermission(MANAGE_APP_TOKENS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + MANAGE_APP_TOKENS);
- }
+ updateDisplayWindowRequestedVisibleTypes_enforcePermission();
final long origId = Binder.clearCallingIdentity();
try {
synchronized (mGlobalLock) {
@@ -5175,7 +5131,7 @@
mSystemReady = true;
mPolicy.systemReady();
mRoot.forAllDisplayPolicies(DisplayPolicy::systemReady);
- mSnapshotPersistQueue.systemReady();
+ mSnapshotController.systemReady();
mHasWideColorGamutSupport = queryWideColorGamutSupport();
mHasHdrSupport = queryHdrSupport();
UiThread.getHandler().post(mSettingsObserver::loadSettings);
@@ -5328,8 +5284,6 @@
public static final int UPDATE_MULTI_WINDOW_STACKS = 41;
- public static final int WINDOW_REPLACEMENT_TIMEOUT = 46;
-
public static final int UPDATE_ANIMATION_SCALE = 51;
public static final int WINDOW_HIDE_TIMEOUT = 52;
public static final int RESTORE_POINTER_ICON = 55;
@@ -5555,16 +5509,6 @@
}
break;
}
- case WINDOW_REPLACEMENT_TIMEOUT: {
- synchronized (mGlobalLock) {
- for (int i = mWindowReplacementTimeouts.size() - 1; i >= 0; i--) {
- final ActivityRecord activity = mWindowReplacementTimeouts.get(i);
- activity.onWindowReplacementTimeout();
- }
- mWindowReplacementTimeouts.clear();
- }
- break;
- }
case WINDOW_HIDE_TIMEOUT: {
final WindowState window = (WindowState) msg.obj;
synchronized (mGlobalLock) {
@@ -5699,12 +5643,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@Override
public void setForcedDisplaySize(int displayId, int width, int height) {
- if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
- }
+ setForcedDisplaySize_enforcePermission();
final long ident = Binder.clearCallingIdentity();
try {
@@ -5719,12 +5661,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@Override
public void setForcedDisplayScalingMode(int displayId, int mode) {
- if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
- }
+ setForcedDisplayScalingMode_enforcePermission();
final long ident = Binder.clearCallingIdentity();
try {
@@ -5807,12 +5747,10 @@
return changed;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@Override
public void clearForcedDisplaySize(int displayId) {
- if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
- }
+ clearForcedDisplaySize_enforcePermission();
final long ident = Binder.clearCallingIdentity();
try {
@@ -5872,12 +5810,10 @@
return -1;
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@Override
public void setForcedDisplayDensityForUser(int displayId, int density, int userId) {
- if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
- }
+ setForcedDisplayDensityForUser_enforcePermission();
final int targetUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, true, "setForcedDisplayDensityForUser",
@@ -5900,12 +5836,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.WRITE_SECURE_SETTINGS)
@Override
public void clearForcedDisplayDensityForUser(int displayId, int userId) {
- if (mContext.checkCallingOrSelfPermission(WRITE_SECURE_SETTINGS)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Must hold permission " + WRITE_SECURE_SETTINGS);
- }
+ clearForcedDisplayDensityForUser_enforcePermission();
final int callingUserId = ActivityManager.handleIncomingUser(Binder.getCallingPid(),
Binder.getCallingUid(), userId, false, true, "clearForcedDisplayDensityForUser",
@@ -6400,12 +6334,9 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.STATUS_BAR)
public void setNavBarVirtualKeyHapticFeedbackEnabled(boolean enabled) {
- if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.STATUS_BAR)
- != PackageManager.PERMISSION_GRANTED) {
- throw new SecurityException("Caller does not hold permission "
- + android.Manifest.permission.STATUS_BAR);
- }
+ setNavBarVirtualKeyHapticFeedbackEnabled_enforcePermission();
synchronized (mGlobalLock) {
mPolicy.setNavBarVirtualKeyHapticFeedbackEnabledLw(enabled);
@@ -6445,11 +6376,10 @@
}
}
+ @android.annotation.EnforcePermission(android.Manifest.permission.RESTRICTED_VR_ACCESS)
@Override
public Region getCurrentImeTouchRegion() {
- if (mContext.checkCallingOrSelfPermission(RESTRICTED_VR_ACCESS) != PERMISSION_GRANTED) {
- throw new SecurityException("getCurrentImeTouchRegion is restricted to VR services");
- }
+ getCurrentImeTouchRegion_enforcePermission();
synchronized (mGlobalLock) {
final Region r = new Region();
// TODO(b/111080190): this method is only return the recent focused IME touch region,
@@ -6731,7 +6661,7 @@
pw.println();
mInputManagerCallback.dump(pw, " ");
- mTaskSnapshotController.dump(pw, " ");
+ mSnapshotController.dump(pw, " ");
if (mAccessibilityController.hasCallbacks()) {
mAccessibilityController.dump(pw, " ");
}
@@ -7083,98 +7013,6 @@
return mGlobalLock;
}
- /**
- * Hint to a token that its activity will relaunch, which will trigger removal and addition of
- * a window.
- *
- * @param token Application token for which the activity will be relaunched.
- */
- void setWillReplaceWindow(IBinder token, boolean animate) {
- final ActivityRecord activity = mRoot.getActivityRecord(token);
- if (activity == null) {
- ProtoLog.w(WM_ERROR, "Attempted to set replacing window on non-existing app token %s",
- token);
- return;
- }
- if (!activity.hasContentToDisplay()) {
- ProtoLog.w(WM_ERROR,
- "Attempted to set replacing window on app token with no content %s",
- token);
- return;
- }
- activity.setWillReplaceWindows(animate);
- }
-
- /**
- * Hint to a token that its windows will be replaced across activity relaunch.
- * The windows would otherwise be removed shortly following this as the
- * activity is torn down.
- * @param token Application token for which the activity will be relaunched.
- * @param childrenOnly Whether to mark only child windows for replacement
- * (for the case where main windows are being preserved/
- * reused rather than replaced).
- *
- */
- // TODO: The s at the end of the method name is the only difference with the name of the method
- // above. We should combine them or find better names.
- void setWillReplaceWindows(IBinder token, boolean childrenOnly) {
- synchronized (mGlobalLock) {
- final ActivityRecord activity = mRoot.getActivityRecord(token);
- if (activity == null) {
- ProtoLog.w(WM_ERROR,
- "Attempted to set replacing window on non-existing app token %s",
- token);
- return;
- }
- if (!activity.hasContentToDisplay()) {
- ProtoLog.w(WM_ERROR,
- "Attempted to set replacing window on app token with no content %s",
- token);
- return;
- }
-
- if (childrenOnly) {
- activity.setWillReplaceChildWindows();
- } else {
- activity.setWillReplaceWindows(false /* animate */);
- }
-
- scheduleClearWillReplaceWindows(token, true /* replacing */);
- }
- }
-
- /**
- * If we're replacing the window, schedule a timer to clear the replaced window
- * after a timeout, in case the replacing window is not coming.
- *
- * If we're not replacing the window, clear the replace window settings of the app.
- *
- * @param token Application token for the activity whose window might be replaced.
- * @param replacing Whether the window is being replaced or not.
- */
- void scheduleClearWillReplaceWindows(IBinder token, boolean replacing) {
- final ActivityRecord activity = mRoot.getActivityRecord(token);
- if (activity == null) {
- ProtoLog.w(WM_ERROR, "Attempted to reset replacing window on non-existing app token %s",
- token);
- return;
- }
- if (replacing) {
- scheduleWindowReplacementTimeouts(activity);
- } else {
- activity.clearWillReplaceWindows();
- }
- }
-
- void scheduleWindowReplacementTimeouts(ActivityRecord activity) {
- if (!mWindowReplacementTimeouts.contains(activity)) {
- mWindowReplacementTimeouts.add(activity);
- }
- mH.removeMessages(H.WINDOW_REPLACEMENT_TIMEOUT);
- mH.sendEmptyMessageDelayed(
- H.WINDOW_REPLACEMENT_TIMEOUT, WINDOW_REPLACEMENT_TIMEOUT_DURATION);
- }
-
@Override
public int getDockedStackSide() {
return 0;
@@ -8744,8 +8582,8 @@
*/
void grantInputChannel(Session session, int callingUid, int callingPid, int displayId,
SurfaceControl surface, IWindow window, IBinder hostInputToken,
- int flags, int privateFlags, int type, IBinder windowToken, IBinder focusGrantToken,
- String inputHandleName, InputChannel outInputChannel) {
+ int flags, int privateFlags, int inputFeatures, int type, IBinder windowToken,
+ IBinder focusGrantToken, String inputHandleName, InputChannel outInputChannel) {
final int sanitizedType = sanitizeWindowType(session, displayId, windowToken, type);
final InputApplicationHandle applicationHandle;
final String name;
@@ -8762,7 +8600,7 @@
}
updateInputChannel(clientChannel.getToken(), callingUid, callingPid, displayId, surface,
- name, applicationHandle, flags, privateFlags, sanitizedType,
+ name, applicationHandle, flags, privateFlags, inputFeatures, sanitizedType,
null /* region */, window);
clientChannel.copyTo(outInputChannel);
@@ -8803,13 +8641,14 @@
private void updateInputChannel(IBinder channelToken, int callingUid, int callingPid,
int displayId, SurfaceControl surface, String name,
InputApplicationHandle applicationHandle, int flags,
- int privateFlags, int type, Region region, IWindow window) {
+ int privateFlags, int inputFeatures, int type, Region region, IWindow window) {
final InputWindowHandle h = new InputWindowHandle(applicationHandle, displayId);
h.token = channelToken;
h.setWindowToken(window);
h.name = name;
flags = sanitizeFlagSlippery(flags, name, callingUid, callingPid);
+ inputFeatures = sanitizeSpyWindow(inputFeatures, name, callingUid, callingPid);
final int sanitizedLpFlags =
(flags & (FLAG_NOT_TOUCHABLE | FLAG_SLIPPERY | LayoutParams.FLAG_NOT_FOCUSABLE))
@@ -8819,7 +8658,7 @@
// Do not allow any input features to be set without sanitizing them first.
h.inputConfig = InputConfigAdapter.getInputConfigFromWindowParams(
- type, sanitizedLpFlags, 0 /*inputFeatures*/);
+ type, sanitizedLpFlags, inputFeatures);
if ((flags & LayoutParams.FLAG_NOT_FOCUSABLE) != 0) {
@@ -8856,7 +8695,7 @@
* is undefined.
*/
void updateInputChannel(IBinder channelToken, int displayId, SurfaceControl surface,
- int flags, int privateFlags, Region region) {
+ int flags, int privateFlags, int inputFeatures, Region region) {
final InputApplicationHandle applicationHandle;
final String name;
final EmbeddedWindowController.EmbeddedWindow win;
@@ -8871,7 +8710,8 @@
}
updateInputChannel(channelToken, win.mOwnerUid, win.mOwnerPid, displayId, surface, name,
- applicationHandle, flags, privateFlags, win.mWindowType, region, win.mClient);
+ applicationHandle, flags, privateFlags, inputFeatures, win.mWindowType, region,
+ win.mClient);
}
/** Return whether layer tracing is enabled */
@@ -9519,30 +9359,6 @@
mSurfaceSyncGroupController.markSyncGroupReady(syncGroupToken);
}
- private ArraySet<ActivityRecord> getVisibleActivityRecords(int displayId) {
- ArraySet<ActivityRecord> result = new ArraySet<>();
- synchronized (mGlobalLock) {
- ArraySet<ComponentName> addedActivities = new ArraySet<>();
- DisplayContent displayContent = mRoot.getDisplayContent(displayId);
- if (displayContent != null) {
- displayContent.forAllWindows(
- (w) -> {
- if (w.isVisible()
- && w.isDisplayed()
- && w.mActivityRecord != null
- && !addedActivities.contains(
- w.mActivityRecord.mActivityComponent)
- && w.mActivityRecord.isVisible()
- && w.isVisibleNow()) {
- addedActivities.add(w.mActivityRecord.mActivityComponent);
- result.add(w.mActivityRecord);
- }
- },
- true /* traverseTopToBottom */);
- }
- }
- return result;
- }
/**
* Must be called when a screenshot is taken via hardware chord.
@@ -9558,14 +9374,20 @@
throw new SecurityException("Requires STATUS_BAR_SERVICE permission");
}
synchronized (mGlobalLock) {
- ArraySet<ComponentName> notifiedApps = new ArraySet<>();
- ArraySet<ActivityRecord> visibleApps = getVisibleActivityRecords(displayId);
- for (ActivityRecord ar : visibleApps) {
- if (ar.isRegisteredForScreenCaptureCallback()) {
- ar.reportScreenCaptured();
- notifiedApps.add(ar.mActivityComponent);
- }
+ final DisplayContent displayContent = mRoot.getDisplayContent(displayId);
+ if (displayContent == null) {
+ return new ArrayList<>();
}
+ ArraySet<ComponentName> notifiedApps = new ArraySet<>();
+ displayContent.forAllActivities(
+ (ar) -> {
+ if (!notifiedApps.contains(ar.mActivityComponent) && ar.isVisible()
+ && ar.isRegisteredForScreenCaptureCallback()) {
+ ar.reportScreenCaptured();
+ notifiedApps.add(ar.mActivityComponent);
+ }
+ },
+ true /* traverseTopToBottom */);
return List.copyOf(notifiedApps);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowOrganizerController.java b/services/core/java/com/android/server/wm/WindowOrganizerController.java
index 55294ed..653b125 100644
--- a/services/core/java/com/android/server/wm/WindowOrganizerController.java
+++ b/services/core/java/com/android/server/wm/WindowOrganizerController.java
@@ -439,7 +439,11 @@
// multiple sync at the same time because it may cause conflict.
// Create a new transition when there is no active sync to collect the changes.
final Transition transition = mTransitionController.createTransition(type);
- applyTransaction(wct, -1 /* syncId */, transition, caller);
+ if (applyTransaction(wct, -1 /* syncId */, transition, caller)
+ == TRANSACT_EFFECTS_NONE && transition.mParticipants.isEmpty()) {
+ transition.abort();
+ return;
+ }
mTransitionController.requestStartTransition(transition, null /* startTask */,
null /* remoteTransition */, null /* displayChange */);
transition.setAllReady();
@@ -476,24 +480,26 @@
// calls startSyncSet.
() -> mTransitionController.moveToCollecting(nextTransition),
() -> {
- if (mTaskFragmentOrganizerController.isValidTransaction(wct)) {
- applyTransaction(wct, -1 /*syncId*/, nextTransition, caller);
+ if (mTaskFragmentOrganizerController.isValidTransaction(wct)
+ && (applyTransaction(wct, -1 /* syncId */, nextTransition, caller)
+ != TRANSACT_EFFECTS_NONE
+ || !nextTransition.mParticipants.isEmpty())) {
mTransitionController.requestStartTransition(nextTransition,
null /* startTask */, null /* remoteTransition */,
null /* displayChange */);
nextTransition.setAllReady();
- } else {
- nextTransition.abort();
+ return;
}
+ nextTransition.abort();
});
} finally {
Binder.restoreCallingIdentity(ident);
}
}
- private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
+ private int applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
@Nullable Transition transition, @NonNull CallerInfo caller) {
- applyTransaction(t, syncId, transition, caller, null /* finishTransition */);
+ return applyTransaction(t, syncId, transition, caller, null /* finishTransition */);
}
/**
@@ -501,8 +507,9 @@
* @param transition A transition to collect changes into.
* @param caller Info about the calling process.
* @param finishTransition The transition that is currently being finished.
+ * @return The effects of the window container transaction.
*/
- private void applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
+ private int applyTransaction(@NonNull WindowContainerTransaction t, int syncId,
@Nullable Transition transition, @NonNull CallerInfo caller,
@Nullable Transition finishTransition) {
int effects = TRANSACT_EFFECTS_NONE;
@@ -639,6 +646,7 @@
mService.mTaskSupervisor.setDeferRootVisibilityUpdate(false /* deferUpdate */);
mService.continueWindowLayout();
}
+ return effects;
}
private int applyChanges(@NonNull WindowContainer<?> container,
@@ -676,7 +684,7 @@
}
}
- final int prevWindowingMode = container.getWindowingMode();
+ final int prevWindowingMode = container.getRequestedOverrideWindowingMode();
if (windowingMode > -1 && prevWindowingMode != windowingMode) {
if (mService.isInLockTaskMode()
&& WindowConfiguration.inMultiWindowMode(windowingMode)) {
diff --git a/services/core/java/com/android/server/wm/WindowProcessController.java b/services/core/java/com/android/server/wm/WindowProcessController.java
index 834b708..8685723 100644
--- a/services/core/java/com/android/server/wm/WindowProcessController.java
+++ b/services/core/java/com/android/server/wm/WindowProcessController.java
@@ -69,6 +69,7 @@
import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
+import android.util.ArrayMap;
import android.util.Log;
import android.util.Slog;
import android.util.proto.ProtoOutputStream;
@@ -228,8 +229,17 @@
* in another process. This is used to check if the process is currently showing anything
* visible to the user.
*/
+ private static final int REMOTE_ACTIVITY_FLAG_HOST_ACTIVITY = 1;
+ /** The activity in a different process is embedded in a task created by this process. */
+ private static final int REMOTE_ACTIVITY_FLAG_EMBEDDED_ACTIVITY = 1 << 1;
+
+ /**
+ * Activities that run on different processes while this process shows something in these
+ * activities or the appearance of the activities are controlled by this process. The value of
+ * map is an array of size 1 to store the kinds of remote.
+ */
@Nullable
- private final ArrayList<ActivityRecord> mHostActivities = new ArrayList<>();
+ private ArrayMap<ActivityRecord, int[]> mRemoteActivities;
/** Whether our process is currently running a {@link RecentsAnimation} */
private boolean mRunningRecentsAnimation;
@@ -857,7 +867,7 @@
return true;
}
}
- if (isEmbedded()) {
+ if (hasEmbeddedWindow()) {
return true;
}
}
@@ -868,9 +878,13 @@
* @return {@code true} if this process is rendering content on to a window shown by
* another process.
*/
- private boolean isEmbedded() {
- for (int i = mHostActivities.size() - 1; i >= 0; --i) {
- final ActivityRecord r = mHostActivities.get(i);
+ private boolean hasEmbeddedWindow() {
+ if (mRemoteActivities == null) return false;
+ for (int i = mRemoteActivities.size() - 1; i >= 0; --i) {
+ if ((mRemoteActivities.valueAt(i)[0] & REMOTE_ACTIVITY_FLAG_HOST_ACTIVITY) == 0) {
+ continue;
+ }
+ final ActivityRecord r = mRemoteActivities.keyAt(i);
if (r.isInterestingToUserLocked()) {
return true;
}
@@ -1038,15 +1052,46 @@
/** Adds an activity that hosts UI drawn by the current process. */
void addHostActivity(ActivityRecord r) {
- if (mHostActivities.contains(r)) {
- return;
- }
- mHostActivities.add(r);
+ final int[] flags = getRemoteActivityFlags(r);
+ flags[0] |= REMOTE_ACTIVITY_FLAG_HOST_ACTIVITY;
}
/** Removes an activity that hosts UI drawn by the current process. */
void removeHostActivity(ActivityRecord r) {
- mHostActivities.remove(r);
+ removeRemoteActivityFlags(r, REMOTE_ACTIVITY_FLAG_HOST_ACTIVITY);
+ }
+
+ /** Adds an embedded activity in a different process to this process that organizes it. */
+ void addEmbeddedActivity(ActivityRecord r) {
+ final int[] flags = getRemoteActivityFlags(r);
+ flags[0] |= REMOTE_ACTIVITY_FLAG_EMBEDDED_ACTIVITY;
+ }
+
+ /** Removes an embedded activity which was added by {@link #addEmbeddedActivity}. */
+ void removeEmbeddedActivity(ActivityRecord r) {
+ removeRemoteActivityFlags(r, REMOTE_ACTIVITY_FLAG_EMBEDDED_ACTIVITY);
+ }
+
+ private int[] getRemoteActivityFlags(ActivityRecord r) {
+ if (mRemoteActivities == null) {
+ mRemoteActivities = new ArrayMap<>();
+ }
+ int[] flags = mRemoteActivities.get(r);
+ if (flags == null) {
+ mRemoteActivities.put(r, flags = new int[1]);
+ }
+ return flags;
+ }
+
+ private void removeRemoteActivityFlags(ActivityRecord r, int flags) {
+ if (mRemoteActivities == null) return;
+ final int index = mRemoteActivities.indexOfKey(r);
+ if (index < 0) return;
+ final int[] currentFlags = mRemoteActivities.valueAt(index);
+ currentFlags[0] &= ~flags;
+ if (currentFlags[0] == 0) {
+ mRemoteActivities.removeAt(index);
+ }
}
public interface ComputeOomAdjCallback {
@@ -1121,6 +1166,16 @@
}
}
}
+ if (mRemoteActivities != null) {
+ // Make this process have visible state if its organizer embeds visible activities of
+ // other process, so this process can be responsive for the organizer events.
+ for (int i = mRemoteActivities.size() - 1; i >= 0; i--) {
+ if ((mRemoteActivities.valueAt(i)[0] & REMOTE_ACTIVITY_FLAG_EMBEDDED_ACTIVITY) != 0
+ && mRemoteActivities.keyAt(i).isVisibleRequested()) {
+ stateFlags |= ACTIVITY_STATE_FLAG_IS_VISIBLE;
+ }
+ }
+ }
stateFlags |= minTaskLayer & ACTIVITY_STATE_FLAG_MASK_MIN_TASK_LAYER;
if (visible) {
@@ -1795,7 +1850,21 @@
pw.print(prefix); pw.print(" - "); pw.println(mActivities.get(i));
}
}
-
+ if (mRemoteActivities != null && !mRemoteActivities.isEmpty()) {
+ pw.print(prefix); pw.println("Remote Activities:");
+ for (int i = mRemoteActivities.size() - 1; i >= 0; i--) {
+ pw.print(prefix); pw.print(" - ");
+ pw.print(mRemoteActivities.keyAt(i)); pw.print(" flags=");
+ final int flags = mRemoteActivities.valueAt(i)[0];
+ if ((flags & REMOTE_ACTIVITY_FLAG_HOST_ACTIVITY) != 0) {
+ pw.print("host ");
+ }
+ if ((flags & REMOTE_ACTIVITY_FLAG_EMBEDDED_ACTIVITY) != 0) {
+ pw.print("embedded");
+ }
+ pw.println();
+ }
+ }
if (mRecentTasks.size() > 0) {
pw.println(prefix + "Recent Tasks:");
for (int i = 0; i < mRecentTasks.size(); i++) {
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index d6c0311..d1bd06f 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -59,13 +59,11 @@
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_NO_MOVE_ANIMATION;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_SYSTEM_APPLICATION_OVERLAY;
import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
-import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_ADJUST_RESIZE;
import static android.view.WindowManager.LayoutParams.SOFT_INPUT_MASK_ADJUST;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_HIDE_NON_SYSTEM_OVERLAY_WINDOWS;
import static android.view.WindowManager.LayoutParams.SYSTEM_FLAG_SHOW_FOR_ALL_USERS;
import static android.view.WindowManager.LayoutParams.TYPE_ACCESSIBILITY_MAGNIFICATION_OVERLAY;
-import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_MEDIA_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_OVERLAY;
@@ -632,22 +630,6 @@
boolean mHasSurface = false;
- // This window will be replaced due to relaunch. This allows window manager
- // to differentiate between simple removal of a window and replacement. In the latter case it
- // will preserve the old window until the new one is drawn.
- boolean mWillReplaceWindow = false;
- // If true, the replaced window was already requested to be removed.
- private boolean mReplacingRemoveRequested = false;
- // Whether the replacement of the window should trigger app transition animation.
- private boolean mAnimateReplacingWindow = false;
- // If not null, the window that will be used to replace the old one. This is being set when
- // the window is added and unset when this window reports its first draw.
- private WindowState mReplacementWindow = null;
- // For the new window in the replacement transition, if we have
- // requested to replace without animation, then we should
- // make sure we also don't apply an enter animation for
- // the new window.
- boolean mSkipEnterAnimationForSeamlessReplacement = false;
// Whether this window is being moved via the resize API
private boolean mMovedByResize;
@@ -1309,13 +1291,6 @@
}
boolean skipLayout() {
- if (mWillReplaceWindow && (mAnimatingExit || !mReplacingRemoveRequested)) {
- // This window is being replaced and either already got information that it's being
- // removed or we are still waiting for some information. Because of this we don't
- // want to apply any more changes to it, so it remains in this state until new window
- // appears.
- return true;
- }
// Skip layout of the window when in transition to pip mode.
return mActivityRecord != null && mActivityRecord.mWaitForEnteringPinnedMode;
}
@@ -2354,24 +2329,6 @@
}
}
- void onWindowReplacementTimeout() {
- if (mWillReplaceWindow) {
- // Since the window already timed out, remove it immediately now.
- // Use WindowState#removeImmediately() instead of WindowState#removeIfPossible(), as
- // the latter delays removal on certain conditions, which will leave the stale window
- // in the root task and marked mWillReplaceWindow=false, so the window will never be
- // removed.
- //
- // Also removes child windows.
- removeImmediately();
- } else {
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final WindowState c = mChildren.get(i);
- c.onWindowReplacementTimeout();
- }
- }
- }
-
@Override
void removeImmediately() {
if (mRemoved) {
@@ -2388,11 +2345,6 @@
mWinAnimator.destroySurfaceLocked(getSyncTransaction());
super.removeImmediately();
- mWillReplaceWindow = false;
- if (mReplacementWindow != null) {
- mReplacementWindow.mSkipEnterAnimationForSeamlessReplacement = false;
- }
-
final DisplayContent dc = getDisplayContent();
if (isImeLayeringTarget()) {
// Remove the attached IME screenshot surface.
@@ -2472,12 +2424,11 @@
ProtoLog.v(WM_DEBUG_APP_TRANSITIONS,
"Remove %s: mSurfaceController=%s mAnimatingExit=%b mRemoveOnExit=%b "
+ "mHasSurface=%b surfaceShowing=%b animating=%b app-animation=%b "
- + "mWillReplaceWindow=%b mDisplayFrozen=%b callers=%s",
+ + "mDisplayFrozen=%b callers=%s",
this, mWinAnimator.mSurfaceController, mAnimatingExit, mRemoveOnExit,
mHasSurface, mWinAnimator.getShown(),
isAnimating(TRANSITION | PARENTS),
mActivityRecord != null && mActivityRecord.isAnimating(PARENTS | TRANSITION),
- mWillReplaceWindow,
mWmService.mDisplayFrozen, Debug.getCallers(6));
// Visibility of the removed window. Will be used later to update orientation later on.
@@ -2487,22 +2438,6 @@
// window until the animation is done. If the display is frozen, just remove immediately,
// since the animation wouldn't be seen.
if (mHasSurface && mToken.okToAnimate()) {
- if (mWillReplaceWindow) {
- // This window is going to be replaced. We need to keep it around until the new one
- // gets added, then we will get rid of this one.
- ProtoLog.v(WM_DEBUG_ADD_REMOVE,
- "Preserving %s until the new one is added", this);
- // TODO: We are overloading mAnimatingExit flag to prevent the window state from
- // been removed. We probably need another flag to indicate that window removal
- // should be deffered vs. overloading the flag that says we are playing an exit
- // animation.
- ProtoLog.v(WM_DEBUG_ANIM,
- "Set animatingExit: reason=remove/replaceWindow win=%s", this);
- mAnimatingExit = true;
- mReplacingRemoveRequested = true;
- return;
- }
-
// If we are not currently running the exit animation, we need to see about starting one
wasVisible = isVisible();
@@ -2714,53 +2649,6 @@
mInputWindowHandle.setToken(null);
}
- /** Returns true if the replacement window was removed. */
- boolean removeReplacedWindowIfNeeded(WindowState replacement) {
- if (mWillReplaceWindow && mReplacementWindow == replacement && replacement.hasDrawn()) {
- replacement.mSkipEnterAnimationForSeamlessReplacement = false;
- removeReplacedWindow();
- return true;
- }
-
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final WindowState c = mChildren.get(i);
- if (c.removeReplacedWindowIfNeeded(replacement)) {
- return true;
- }
- }
- return false;
- }
-
- private void removeReplacedWindow() {
- ProtoLog.d(WM_DEBUG_ADD_REMOVE, "Removing replaced window: %s", this);
- mWillReplaceWindow = false;
- mAnimateReplacingWindow = false;
- mReplacingRemoveRequested = false;
- mReplacementWindow = null;
- if (mAnimatingExit || !mAnimateReplacingWindow) {
- removeImmediately();
- }
- }
-
- boolean setReplacementWindowIfNeeded(WindowState replacementCandidate) {
- boolean replacementSet = false;
-
- if (mWillReplaceWindow && mReplacementWindow == null
- && getWindowTag().toString().equals(replacementCandidate.getWindowTag().toString())) {
-
- mReplacementWindow = replacementCandidate;
- replacementCandidate.mSkipEnterAnimationForSeamlessReplacement = !mAnimateReplacingWindow;
- replacementSet = true;
- }
-
- for (int i = mChildren.size() - 1; i >= 0; --i) {
- final WindowState c = mChildren.get(i);
- replacementSet |= c.setReplacementWindowIfNeeded(replacementCandidate);
- }
-
- return replacementSet;
- }
-
void setDisplayLayoutNeeded() {
final DisplayContent dc = getDisplayContent();
if (dc != null) {
@@ -3025,8 +2913,9 @@
.windowForClientLocked(mSession, mClient, false);
Slog.i(TAG, "WIN DEATH: " + win);
if (win != null) {
- if (win.mActivityRecord != null && win.mActivityRecord.findMainWindow() == win) {
- mWmService.mTaskSnapshotController.onAppDied(win.mActivityRecord);
+ if (win.mActivityRecord != null
+ && win.mActivityRecord.findMainWindow() == win) {
+ mWmService.mSnapshotController.onAppDied(win.mActivityRecord);
}
win.removeIfPossible();
} else if (mHasSurface) {
@@ -4391,49 +4280,6 @@
return parent != null && parent.isGoneForLayout();
}
- void setWillReplaceWindow(boolean animate) {
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState c = mChildren.get(i);
- c.setWillReplaceWindow(animate);
- }
-
- if ((mAttrs.privateFlags & PRIVATE_FLAG_WILL_NOT_REPLACE_ON_RELAUNCH) != 0
- || mAttrs.type == TYPE_APPLICATION_STARTING) {
- // We don't set replacing on starting windows since they are added by window manager and
- // not the client so won't be replaced by the client.
- return;
- }
-
- mWillReplaceWindow = true;
- mReplacementWindow = null;
- mAnimateReplacingWindow = animate;
- }
-
- void clearWillReplaceWindow() {
- mWillReplaceWindow = false;
- mReplacementWindow = null;
- mAnimateReplacingWindow = false;
-
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState c = mChildren.get(i);
- c.clearWillReplaceWindow();
- }
- }
-
- boolean waitingForReplacement() {
- if (mWillReplaceWindow) {
- return true;
- }
-
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState c = mChildren.get(i);
- if (c.waitingForReplacement()) {
- return true;
- }
- }
- return false;
- }
-
void requestUpdateWallpaperIfNeeded() {
final DisplayContent dc = getDisplayContent();
if (dc != null && ((mIsWallpaper && !mLastConfigReportedToClient) || hasWallpaper())) {
@@ -4464,43 +4310,6 @@
return winY;
}
- // During activity relaunch due to resize, we sometimes use window replacement
- // for only child windows (as the main window is handled by window preservation)
- // and the big surface.
- //
- // Though windows of TYPE_APPLICATION or TYPE_DRAWN_APPLICATION (as opposed to
- // TYPE_BASE_APPLICATION) are not children in the sense of an attached window,
- // we also want to replace them at such phases, as they won't be covered by window
- // preservation, and in general we expect them to return following relaunch.
- boolean shouldBeReplacedWithChildren() {
- return mIsChildWindow || mAttrs.type == TYPE_APPLICATION
- || mAttrs.type == TYPE_DRAWN_APPLICATION;
- }
-
- void setWillReplaceChildWindows() {
- if (shouldBeReplacedWithChildren()) {
- setWillReplaceWindow(false /* animate */);
- }
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState c = mChildren.get(i);
- c.setWillReplaceChildWindows();
- }
- }
-
- WindowState getReplacingWindow() {
- if (mAnimatingExit && mWillReplaceWindow && mAnimateReplacingWindow) {
- return this;
- }
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState c = mChildren.get(i);
- final WindowState replacing = c.getReplacingWindow();
- if (replacing != null) {
- return replacing;
- }
- }
- return null;
- }
-
int getRotationAnimationHint() {
if (mActivityRecord != null) {
return mActivityRecord.mRotationAnimationHint;
@@ -4990,14 +4799,11 @@
boolean clearAnimatingFlags() {
boolean didSomething = false;
- // We don't want to clear it out for windows that get replaced, because the
- // animation depends on the flag to remove the replaced window.
- //
// We also don't clear the mAnimatingExit flag for windows which have the
// mRemoveOnExit flag. This indicates an explicit remove request has been issued
// by the client. We should let animation proceed and not clear this flag or
// they won't eventually be removed by WindowStateAnimator#finishExit.
- if (!mWillReplaceWindow && !mRemoveOnExit) {
+ if (!mRemoveOnExit) {
// Clear mAnimating flag together with mAnimatingExit. When animation
// changes from exiting to entering, we need to clear this flag until the
// new animation gets applied, so that isAnimationStarting() becomes true
@@ -5312,7 +5118,7 @@
return activity.needsZBoost();
}
}
- return mWillReplaceWindow;
+ return false;
}
private boolean isStartingWindowAssociatedToTask() {
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index e8625bc..3aac816 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -449,7 +449,6 @@
if (prepared && mDrawState == HAS_DRAWN) {
if (mLastHidden) {
mSurfaceController.showRobustly(t);
- mAnimator.requestRemovalOfReplacedWindows(w);
mLastHidden = false;
final DisplayContent displayContent = w.getDisplayContent();
if (!displayContent.getLastHasContent()) {
@@ -504,13 +503,6 @@
}
void applyEnterAnimationLocked() {
- // If we are the new part of a window replacement transition and we have requested
- // not to animate, we instead want to make it seamless, so we don't want to apply
- // an enter transition.
- if (mWin.mSkipEnterAnimationForSeamlessReplacement) {
- return;
- }
-
final int transit;
if (mEnterAnimationPending) {
mEnterAnimationPending = false;
diff --git a/services/core/java/com/android/server/wm/WindowToken.java b/services/core/java/com/android/server/wm/WindowToken.java
index c6b7898..327483e 100644
--- a/services/core/java/com/android/server/wm/WindowToken.java
+++ b/services/core/java/com/android/server/wm/WindowToken.java
@@ -315,17 +315,6 @@
return mChildren.isEmpty();
}
- WindowState getReplacingWindow() {
- for (int i = mChildren.size() - 1; i >= 0; i--) {
- final WindowState win = mChildren.get(i);
- final WindowState replacing = win.getReplacingWindow();
- if (replacing != null) {
- return replacing;
- }
- }
- return null;
- }
-
/** Return true if this token has a window that wants the wallpaper displayed behind it. */
boolean windowsCanBeWallpaperTarget() {
for (int j = mChildren.size() - 1; j >= 0; j--) {
diff --git a/services/core/jni/com_android_server_input_InputManagerService.cpp b/services/core/jni/com_android_server_input_InputManagerService.cpp
index da44da4..a5b1943 100644
--- a/services/core/jni/com_android_server_input_InputManagerService.cpp
+++ b/services/core/jni/com_android_server_input_InputManagerService.cpp
@@ -379,7 +379,7 @@
jobject mServiceObj;
sp<Looper> mLooper;
- Mutex mLock;
+ std::mutex mLock;
struct Locked {
// Display size information.
std::vector<DisplayViewport> viewports{};
@@ -469,7 +469,7 @@
dump += StringPrintf(INDENT "Interactive: %s\n", toString(mInteractive.load()));
}
{
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
dump += StringPrintf(INDENT "System UI Lights Out: %s\n",
toString(mLocked.systemUiLightsOut));
dump += StringPrintf(INDENT "Pointer Speed: %" PRId32 "\n", mLocked.pointerSpeed);
@@ -532,7 +532,7 @@
}
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
mLocked.viewports = viewports;
std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
if (controller != nullptr) {
@@ -669,7 +669,7 @@
}
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
outConfig->pointerVelocityControlParameters.scale = exp2f(mLocked.pointerSpeed
* POINTER_SPEED_EXPONENT);
@@ -717,7 +717,7 @@
std::shared_ptr<PointerControllerInterface> NativeInputManager::obtainPointerController(
int32_t /* deviceId */) {
ATRACE_CALL();
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
if (controller == nullptr) {
@@ -1065,7 +1065,7 @@
}
void NativeInputManager::setSystemUiLightsOut(bool lightsOut) {
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.systemUiLightsOut != lightsOut) {
mLocked.systemUiLightsOut = lightsOut;
@@ -1085,7 +1085,7 @@
void NativeInputManager::setPointerDisplayId(int32_t displayId) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.pointerDisplayId == displayId) {
return;
@@ -1101,7 +1101,7 @@
void NativeInputManager::setPointerSpeed(int32_t speed) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.pointerSpeed == speed) {
return;
@@ -1117,7 +1117,7 @@
void NativeInputManager::setPointerAcceleration(float acceleration) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.pointerAcceleration == acceleration) {
return;
@@ -1133,7 +1133,7 @@
void NativeInputManager::setTouchpadPointerSpeed(int32_t speed) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.touchpadPointerSpeed == speed) {
return;
@@ -1149,7 +1149,7 @@
void NativeInputManager::setTouchpadNaturalScrollingEnabled(bool enabled) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.touchpadNaturalScrollingEnabled == enabled) {
return;
@@ -1165,7 +1165,7 @@
void NativeInputManager::setTouchpadTapToClickEnabled(bool enabled) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.touchpadTapToClickEnabled == enabled) {
return;
@@ -1181,7 +1181,7 @@
void NativeInputManager::setTouchpadRightClickZoneEnabled(bool enabled) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.touchpadRightClickZoneEnabled == enabled) {
return;
@@ -1197,7 +1197,7 @@
void NativeInputManager::setInputDeviceEnabled(uint32_t deviceId, bool enabled) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
auto it = mLocked.disabledInputDevices.find(deviceId);
bool currentlyEnabled = it == mLocked.disabledInputDevices.end();
@@ -1215,7 +1215,7 @@
void NativeInputManager::setShowTouches(bool enabled) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.showTouches == enabled) {
return;
@@ -1243,7 +1243,7 @@
}
void NativeInputManager::setPointerIconType(PointerIconStyle iconId) {
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
if (controller != nullptr) {
controller->updatePointerIcon(iconId);
@@ -1251,7 +1251,7 @@
}
void NativeInputManager::reloadPointerIcons() {
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
if (controller != nullptr) {
controller->reloadPointerResources();
@@ -1259,7 +1259,7 @@
}
void NativeInputManager::setCustomPointerIcon(const SpriteIcon& icon) {
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
std::shared_ptr<PointerController> controller = mLocked.pointerController.lock();
if (controller != nullptr) {
controller->setCustomPointerIcon(icon);
@@ -1522,7 +1522,7 @@
void NativeInputManager::setPointerCapture(const PointerCaptureRequest& request) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.pointerCaptureRequest == request) {
return;
@@ -1633,7 +1633,7 @@
void NativeInputManager::setStylusButtonMotionEventsEnabled(bool enabled) {
{ // acquire lock
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
if (mLocked.stylusButtonMotionEventsEnabled == enabled) {
return;
@@ -1657,7 +1657,7 @@
}
FloatPoint NativeInputManager::getMouseCursorPosition() {
- AutoMutex _l(mLock);
+ std::scoped_lock _l(mLock);
const auto pc = mLocked.pointerController.lock();
if (!pc) return {AMOTION_EVENT_INVALID_CURSOR_POSITION, AMOTION_EVENT_INVALID_CURSOR_POSITION};
diff --git a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
index e09c0a2..38dadc6 100644
--- a/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/ClearRequestSession.java
@@ -121,33 +121,36 @@
private void respondToClientWithResponseAndFinish() {
Log.i(TAG, "respondToClientWithResponseAndFinish");
+ collectFinalPhaseMetricStatus(false, ProviderStatusForMetrics.FINAL_SUCCESS);
if (isSessionCancelled()) {
- mChosenProviderFinalPhaseMetric.setChosenProviderStatus(
- ProviderStatusForMetrics.FINAL_SUCCESS.getMetricCode());
- logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
- ApiStatus.CLIENT_CANCELED);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode());
finishSession(/*propagateCancellation=*/true);
return;
}
try {
mClientCallback.onSuccess();
- logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
- ApiStatus.SUCCESS);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.SUCCESS.getMetricCode());
} catch (RemoteException e) {
- mChosenProviderFinalPhaseMetric.setChosenProviderStatus(
- ProviderStatusForMetrics.FINAL_FAILURE.getMetricCode());
+ collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE);
Log.i(TAG, "Issue while propagating the response to the client");
- logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
- ApiStatus.FAILURE);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.FAILURE.getMetricCode());
}
finishSession(/*propagateCancellation=*/false);
}
private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) {
Log.i(TAG, "respondToClientWithErrorAndFinish");
+ collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE);
if (isSessionCancelled()) {
- logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
- ApiStatus.CLIENT_CANCELED);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode());
finishSession(/*propagateCancellation=*/true);
return;
}
@@ -156,8 +159,9 @@
} catch (RemoteException e) {
e.printStackTrace();
}
- logApiCall(ApiName.CLEAR_CREDENTIAL, /* apiStatus */
- ApiStatus.FAILURE);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.FAILURE.getMetricCode());
finishSession(/*propagateCancellation=*/false);
}
diff --git a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
index 793d83e..06fe4f0 100644
--- a/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/CreateRequestSession.java
@@ -142,40 +142,47 @@
private void respondToClientWithResponseAndFinish(CreateCredentialResponse response) {
Log.i(TAG, "respondToClientWithResponseAndFinish");
- // TODO immediately add exception bit to chosen provider and do final emits across all
- // including sequenceCounter!
+ // TODO(b/271135048) - Improve Metrics super/sub class setup and emit.
+ collectFinalPhaseMetricStatus(false, ProviderStatusForMetrics.FINAL_SUCCESS);
if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
Log.i(TAG, "Request has already been completed. This is strange.");
return;
}
if (isSessionCancelled()) {
- logApiCall(ApiName.CREATE_CREDENTIAL, /* apiStatus */
- ApiStatus.CLIENT_CANCELED);
+ // TODO(b/271135048) - Migrate to superclass utilities (post beta1 cleanup) - applies
+ // for all
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode());
finishSession(/*propagateCancellation=*/true);
return;
}
try {
mClientCallback.onResponse(response);
- logApiCall(ApiName.CREATE_CREDENTIAL, /* apiStatus */
- ApiStatus.SUCCESS);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.SUCCESS.getMetricCode());
} catch (RemoteException e) {
+ collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE);
Log.i(TAG, "Issue while responding to client: " + e.getMessage());
- logApiCall(ApiName.CREATE_CREDENTIAL, /* apiStatus */
- ApiStatus.FAILURE);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.FAILURE.getMetricCode());
}
finishSession(/*propagateCancellation=*/false);
}
private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) {
Log.i(TAG, "respondToClientWithErrorAndFinish");
-
+ collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE);
if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
Log.i(TAG, "Request has already been completed. This is strange.");
return;
}
if (isSessionCancelled()) {
- logApiCall(ApiName.CREATE_CREDENTIAL, /* apiStatus */
- ApiStatus.CLIENT_CANCELED);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode());
finishSession(/*propagateCancellation=*/true);
return;
}
@@ -189,12 +196,16 @@
}
private void logFailureOrUserCancel(String errorType) {
+ collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE);
if (CreateCredentialException.TYPE_USER_CANCELED.equals(errorType)) {
- logApiCall(ApiName.CREATE_CREDENTIAL,
- /* apiStatus */ ApiStatus.USER_CANCELED);
+ mChosenProviderFinalPhaseMetric.setHasException(false);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.USER_CANCELED.getMetricCode());
} else {
- logApiCall(ApiName.CREATE_CREDENTIAL,
- /* apiStatus */ ApiStatus.FAILURE);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.FAILURE.getMetricCode());
}
}
diff --git a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
index 4c5c366..a15d6630 100644
--- a/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
+++ b/services/credentials/java/com/android/server/credentials/CredentialManagerService.java
@@ -16,6 +16,7 @@
package com.android.server.credentials;
+import static android.Manifest.permission.CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS;
import static android.Manifest.permission.CREDENTIAL_MANAGER_SET_ORIGIN;
import static android.Manifest.permission.LAUNCH_CREDENTIAL_SELECTOR;
import static android.content.Context.CREDENTIAL_SERVICE;
@@ -124,7 +125,8 @@
serviceInfos.forEach(
info -> {
services.add(
- new CredentialManagerServiceImpl(this, mLock, resolvedUserId, info));
+ new CredentialManagerServiceImpl(this, mLock, resolvedUserId,
+ info));
});
return services;
}
@@ -418,6 +420,7 @@
// Check privileged permissions
mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ORIGIN, null);
}
+ enforcePermissionForAllowedProviders(request);
final int userId = UserHandle.getCallingUserId();
final int callingUid = Binder.getCallingUid();
@@ -447,6 +450,9 @@
// TODO(b/273308895): implement
ICancellationSignal cancelTransport = CancellationSignal.createTransport();
+
+ enforcePermissionForAllowedProviders(request);
+
return cancelTransport;
}
@@ -592,9 +598,13 @@
}
private void finalizeAndEmitInitialPhaseMetric(RequestSession session) {
- var initMetric = session.mInitialPhaseMetric;
- initMetric.setCredentialServiceBeginQueryTimeNanoseconds(System.nanoTime());
- MetricUtilities.logApiCalled(initMetric);
+ try {
+ var initMetric = session.mInitialPhaseMetric;
+ initMetric.setCredentialServiceBeginQueryTimeNanoseconds(System.nanoTime());
+ MetricUtilities.logApiCalled(initMetric, ++session.mSequenceCounter);
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
+ }
}
@Override
@@ -819,6 +829,17 @@
}
}
+ private void enforcePermissionForAllowedProviders(GetCredentialRequest request) {
+ boolean containsAllowedProviders = request.getCredentialOptions()
+ .stream()
+ .anyMatch(option -> option.getAllowedProviders() != null
+ && !option.getAllowedProviders().isEmpty());
+ if (containsAllowedProviders) {
+ mContext.enforceCallingPermission(CREDENTIAL_MANAGER_SET_ALLOWED_PROVIDERS,
+ null);
+ }
+ }
+
private void enforceCallingPackage(String callingPackage, int callingUid) {
int packageUid;
PackageManager pm = mContext.createContextAsUser(
diff --git a/services/credentials/java/com/android/server/credentials/GetRequestSession.java b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
index 00fbbba..8082cdb 100644
--- a/services/credentials/java/com/android/server/credentials/GetRequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/GetRequestSession.java
@@ -27,6 +27,7 @@
import android.credentials.IGetCredentialCallback;
import android.credentials.ui.ProviderData;
import android.credentials.ui.RequestInfo;
+import android.os.Binder;
import android.os.CancellationSignal;
import android.os.RemoteException;
import android.service.credentials.CallingAppInfo;
@@ -84,11 +85,12 @@
protected void launchUiWithProviderData(ArrayList<ProviderData> providerDataList) {
mChosenProviderFinalPhaseMetric.setUiCallStartTimeNanoseconds(System.nanoTime());
try {
- mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
+ Binder.withCleanCallingIdentity(() ->
+ mClientCallback.onPendingIntent(mCredentialManagerUi.createPendingIntent(
RequestInfo.newGetRequestInfo(
- mRequestId, mClientRequest, mClientAppInfo.getPackageName()),
- providerDataList));
- } catch (RemoteException e) {
+ mRequestId, mClientRequest, mClientAppInfo.getPackageName()),
+ providerDataList)));
+ } catch (RuntimeException e) {
mChosenProviderFinalPhaseMetric.setUiReturned(false);
respondToClientWithErrorAndFinish(
GetCredentialException.TYPE_UNKNOWN, "Unable to instantiate selector");
@@ -123,36 +125,43 @@
}
private void respondToClientWithResponseAndFinish(GetCredentialResponse response) {
+ collectFinalPhaseMetricStatus(false, ProviderStatusForMetrics.FINAL_SUCCESS);
if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
Log.i(TAG, "Request has already been completed. This is strange.");
return;
}
if (isSessionCancelled()) {
- logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
- ApiStatus.CLIENT_CANCELED);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode());
finishSession(/*propagateCancellation=*/true);
return;
}
try {
mClientCallback.onResponse(response);
- logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
- ApiStatus.SUCCESS);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.SUCCESS.getMetricCode());
} catch (RemoteException e) {
+ collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE);
Log.i(TAG, "Issue while responding to client with a response : " + e.getMessage());
- logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
- ApiStatus.FAILURE);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.FAILURE.getMetricCode());
}
finishSession(/*propagateCancellation=*/false);
}
private void respondToClientWithErrorAndFinish(String errorType, String errorMsg) {
+ collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE);
if (mRequestSessionStatus == RequestSessionStatus.COMPLETE) {
Log.i(TAG, "Request has already been completed. This is strange.");
return;
}
if (isSessionCancelled()) {
- logApiCall(ApiName.GET_CREDENTIAL, /* apiStatus */
- ApiStatus.CLIENT_CANCELED);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.CLIENT_CANCELED.getMetricCode());
finishSession(/*propagateCancellation=*/true);
return;
}
@@ -167,12 +176,16 @@
}
private void logFailureOrUserCancel(String errorType) {
+ collectFinalPhaseMetricStatus(true, ProviderStatusForMetrics.FINAL_FAILURE);
if (GetCredentialException.TYPE_USER_CANCELED.equals(errorType)) {
- logApiCall(ApiName.GET_CREDENTIAL,
- /* apiStatus */ ApiStatus.USER_CANCELED);
+ mChosenProviderFinalPhaseMetric.setHasException(false);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.USER_CANCELED.getMetricCode());
} else {
- logApiCall(ApiName.GET_CREDENTIAL,
- /* apiStatus */ ApiStatus.FAILURE);
+ logApiCall(mChosenProviderFinalPhaseMetric,
+ mCandidateBrowsingPhaseMetric,
+ /* apiStatus */ ApiStatus.FAILURE.getMetricCode());
}
}
diff --git a/services/credentials/java/com/android/server/credentials/MetricUtilities.java b/services/credentials/java/com/android/server/credentials/MetricUtilities.java
index ed139b5..65fb368 100644
--- a/services/credentials/java/com/android/server/credentials/MetricUtilities.java
+++ b/services/credentials/java/com/android/server/credentials/MetricUtilities.java
@@ -24,10 +24,12 @@
import com.android.internal.util.FrameworkStatsLog;
import com.android.server.credentials.metrics.ApiName;
import com.android.server.credentials.metrics.ApiStatus;
+import com.android.server.credentials.metrics.CandidateBrowsingPhaseMetric;
import com.android.server.credentials.metrics.CandidatePhaseMetric;
import com.android.server.credentials.metrics.ChosenProviderFinalPhaseMetric;
import com.android.server.credentials.metrics.InitialPhaseMetric;
+import java.util.List;
import java.util.Map;
/**
@@ -81,48 +83,138 @@
}
/**
- * The most common logging helper, handles the overall status of the API request with the
- * provider status and latencies. Other versions of this method may be more useful depending
- * on the situation, as this is geared towards the logging of {@link ProviderSession} types.
+ * A logging utility used primarily for the final phase of the current metric setup.
*
- * @param apiName the api type to log
- * @param apiStatus the api status to log
- * @param providers a map with known providers
- * @param callingUid the calling UID of the client app
- * @param chosenProviderFinalPhaseMetric the metric data type of the final chosen provider
+ * @param finalPhaseMetric the coalesced data of the chosen provider
+ * @param browsingPhaseMetrics the coalesced data of the browsing phase
+ * @param apiStatus the final status of this particular api call
+ * @param emitSequenceId an emitted sequence id for the current session
*/
- protected static void logApiCalled(ApiName apiName, ApiStatus apiStatus,
- Map<String, ProviderSession> providers, int callingUid,
- ChosenProviderFinalPhaseMetric chosenProviderFinalPhaseMetric) {
+ protected static void logApiCalled(ChosenProviderFinalPhaseMetric finalPhaseMetric,
+ List<CandidateBrowsingPhaseMetric> browsingPhaseMetrics, int apiStatus,
+ int emitSequenceId) {
+ try {
+ int browsedSize = browsingPhaseMetrics.size();
+ int[] browsedClickedEntries = new int[browsedSize];
+ int[] browsedProviderUid = new int[browsedSize];
+ int index = 0;
+ for (CandidateBrowsingPhaseMetric metric : browsingPhaseMetrics) {
+ browsedClickedEntries[index] = metric.getEntryEnum();
+ browsedProviderUid[index] = metric.getProviderUid();
+ index++;
+ }
+ FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE,
+ /* session_id */ finalPhaseMetric.getSessionId(),
+ /* sequence_num */ emitSequenceId,
+ /* ui_returned_final_start */ finalPhaseMetric.isUiReturned(),
+ /* chosen_provider_uid */ finalPhaseMetric.getChosenUid(),
+ /* chosen_provider_query_start_timestamp_microseconds */
+ finalPhaseMetric.getTimestampFromReferenceStartMicroseconds(finalPhaseMetric
+ .getQueryStartTimeNanoseconds()),
+ /* chosen_provider_query_end_timestamp_microseconds */
+ finalPhaseMetric.getTimestampFromReferenceStartMicroseconds(finalPhaseMetric
+ .getQueryEndTimeNanoseconds()),
+ /* chosen_provider_ui_invoked_timestamp_microseconds */
+ finalPhaseMetric.getTimestampFromReferenceStartMicroseconds(finalPhaseMetric
+ .getUiCallStartTimeNanoseconds()),
+ /* chosen_provider_ui_finished_timestamp_microseconds */
+ finalPhaseMetric.getTimestampFromReferenceStartMicroseconds(finalPhaseMetric
+ .getUiCallEndTimeNanoseconds()),
+ /* chosen_provider_finished_timestamp_microseconds */
+ finalPhaseMetric.getTimestampFromReferenceStartMicroseconds(finalPhaseMetric
+ .getFinalFinishTimeNanoseconds()),
+ /* chosen_provider_status */ finalPhaseMetric.getChosenProviderStatus(),
+ /* chosen_provider_has_exception */ finalPhaseMetric.isHasException(),
+ /* chosen_provider_available_entries */ finalPhaseMetric.getAvailableEntries()
+ .stream().mapToInt(i -> i).toArray(),
+ /* chosen_provider_action_entry_count */ finalPhaseMetric.getActionEntryCount(),
+ /* chosen_provider_credential_entry_count */
+ finalPhaseMetric.getCredentialEntryCount(),
+ /* chosen_provider_credential_entry_type_count */
+ finalPhaseMetric.getCredentialEntryTypeCount(),
+ /* chosen_provider_remote_entry_count */
+ finalPhaseMetric.getRemoteEntryCount(),
+ /* chosen_provider_authentication_entry_count */
+ finalPhaseMetric.getAuthenticationEntryCount(),
+ /* clicked_entries */ browsedClickedEntries,
+ /* provider_of_clicked_entry */ browsedProviderUid,
+ /* api_status */ apiStatus
+ );
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
+ }
+ }
+
+ /**
+ * A logging utility used primarily for the candidate phase of the current metric setup.
+ *
+ * @param providers a map with known providers and their held metric objects
+ * @param emitSequenceId an emitted sequence id for the current session
+ */
+ protected static void logApiCalled(Map<String, ProviderSession> providers,
+ int emitSequenceId) {
try {
var providerSessions = providers.values();
int providerSize = providerSessions.size();
+ int sessionId = -1;
+ boolean queryReturned = false;
int[] candidateUidList = new int[providerSize];
- int[] candidateQueryRoundTripTimeList = new int[providerSize];
+ int[] candidateQueryStartTimeStampList = new int[providerSize];
+ int[] candidateQueryEndTimeStampList = new int[providerSize];
int[] candidateStatusList = new int[providerSize];
+ boolean[] candidateHasExceptionList = new boolean[providerSize];
+ int[] candidateTotalEntryCountList = new int[providerSize];
+ int[] candidateCredentialEntryCountList = new int[providerSize];
+ int[] candidateCredentialTypeCountList = new int[providerSize];
+ int[] candidateActionEntryCountList = new int[providerSize];
+ int[] candidateAuthEntryCountList = new int[providerSize];
+ int[] candidateRemoteEntryCountList = new int[providerSize];
int index = 0;
for (var session : providerSessions) {
CandidatePhaseMetric metric = session.mCandidatePhasePerProviderMetric;
+ if (sessionId == -1) {
+ sessionId = metric.getSessionId();
+ }
+ if (!queryReturned) {
+ queryReturned = metric.isQueryReturned();
+ }
candidateUidList[index] = metric.getCandidateUid();
- candidateQueryRoundTripTimeList[index] = metric.getQueryLatencyMicroseconds();
+ candidateQueryStartTimeStampList[index] =
+ metric.getTimestampFromReferenceStartMicroseconds(
+ metric.getStartQueryTimeNanoseconds());
+ candidateQueryEndTimeStampList[index] =
+ metric.getTimestampFromReferenceStartMicroseconds(
+ metric.getQueryFinishTimeNanoseconds());
candidateStatusList[index] = metric.getProviderQueryStatus();
+ candidateHasExceptionList[index] = metric.isHasException();
+ candidateTotalEntryCountList[index] = metric.getNumEntriesTotal();
+ candidateCredentialEntryCountList[index] = metric.getCredentialEntryCount();
+ candidateCredentialTypeCountList[index] = metric.getCredentialEntryTypeCount();
+ candidateActionEntryCountList[index] = metric.getActionEntryCount();
+ candidateAuthEntryCountList[index] = metric.getAuthenticationEntryCount();
+ candidateRemoteEntryCountList[index] = metric.getRemoteEntryCount();
index++;
}
- FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED,
- /* api_name */apiName.getMetricCode(),
- /* caller_uid */ callingUid,
- /* api_status */ apiStatus.getMetricCode(),
- /* repeated_candidate_provider_uid */ candidateUidList,
- /* repeated_candidate_provider_round_trip_time_query_microseconds */
- candidateQueryRoundTripTimeList,
- /* repeated_candidate_provider_status */ candidateStatusList,
- /* chosen_provider_uid */ chosenProviderFinalPhaseMetric.getChosenUid(),
- /* chosen_provider_round_trip_time_overall_microseconds */
- chosenProviderFinalPhaseMetric.getEntireProviderLatencyMicroseconds(),
- /* chosen_provider_final_phase_microseconds (backwards compat only) */
- DEFAULT_INT_32,
- /* chosen_provider_status */ chosenProviderFinalPhaseMetric
- .getChosenProviderStatus());
+ FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_CANDIDATE_PHASE,
+ /* session_id */ sessionId,
+ /* sequence_num */ emitSequenceId,
+ /* query_returned */ queryReturned,
+ /* candidate_provider_uid_list */ candidateUidList,
+ /* candidate_provider_query_start_timestamp_microseconds */
+ candidateQueryStartTimeStampList,
+ /* candidate_provider_query_end_timestamp_microseconds */
+ candidateQueryEndTimeStampList,
+ /* candidate_provider_status */ candidateStatusList,
+ /* candidate_provider_has_exception */ candidateHasExceptionList,
+ /* candidate_provider_num_entries */ candidateTotalEntryCountList,
+ /* candidate_provider_action_entry_count */ candidateActionEntryCountList,
+ /* candidate_provider_credential_entry_count */
+ candidateCredentialEntryCountList,
+ /* candidate_provider_credential_entry_type_count */
+ candidateCredentialTypeCountList,
+ /* candidate_provider_remote_entry_count */ candidateRemoteEntryCountList,
+ /* candidate_provider_authentication_entry_count */ candidateAuthEntryCountList
+ );
} catch (Exception e) {
Log.w(TAG, "Unexpected error during metric logging: " + e);
}
@@ -164,14 +256,24 @@
* Handles the metric emit for the initial phase.
*
* @param initialPhaseMetric contains all the data for this emit
+ * @param sequenceNum the sequence number for this api call session emit
*/
- protected static void logApiCalled(InitialPhaseMetric initialPhaseMetric) {
- /*
- FrameworkStatsLog.write(FrameworkStatsLog.INITIAL_PHASE,
- .. session_id .. initialPhaseMetric.getSessionId(),
- ...
- TODO Immediately - Fill in asap now that the split atom is checked in.
- */
+ protected static void logApiCalled(InitialPhaseMetric initialPhaseMetric, int sequenceNum) {
+ try {
+ FrameworkStatsLog.write(FrameworkStatsLog.CREDENTIAL_MANAGER_INIT_PHASE,
+ /* api_name */ initialPhaseMetric.getApiName(),
+ /* caller_uid */ initialPhaseMetric.getCallerUid(),
+ /* session_id */ initialPhaseMetric.getSessionId(),
+ /* sequence_num */ sequenceNum,
+ /* initial_timestamp_reference_nanoseconds */
+ initialPhaseMetric.getCredentialServiceStartedTimeNanoseconds(),
+ /* count_credential_request_classtypes */
+ initialPhaseMetric.getCountRequestClassType()
+ // TODO(b/271135048) - add total count of request options
+ );
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
+ }
}
}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderClearSession.java b/services/credentials/java/com/android/server/credentials/ProviderClearSession.java
index 950cf4f..69a642d 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderClearSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderClearSession.java
@@ -33,7 +33,7 @@
*
* @hide
*/
-public final class ProviderClearSession extends ProviderSession<ClearCredentialStateRequest,
+public final class ProviderClearSession extends ProviderSession<ClearCredentialStateRequest,
Void>
implements
RemoteCredentialService.ProviderCallbacks<Void> {
@@ -42,7 +42,8 @@
private ClearCredentialStateException mProviderException;
/** Creates a new provider session to be used by the request session. */
- @Nullable public static ProviderClearSession createNewSession(
+ @Nullable
+ public static ProviderClearSession createNewSession(
Context context,
@UserIdInt int userId,
CredentialProviderInfo providerInfo,
@@ -53,7 +54,7 @@
clearRequestSession.mClientRequest,
clearRequestSession.mClientAppInfo);
return new ProviderClearSession(context, providerInfo, clearRequestSession, userId,
- remoteCredentialService, providerRequest);
+ remoteCredentialService, providerRequest);
}
@Nullable
@@ -90,6 +91,7 @@
if (exception instanceof ClearCredentialStateException) {
mProviderException = (ClearCredentialStateException) exception;
}
+ captureCandidateFailureInMetrics();
updateStatusAndInvokeCallback(toStatus(errorCode));
}
@@ -120,14 +122,7 @@
@Override
protected void invokeSession() {
if (mRemoteCredentialService != null) {
- /*
- InitialPhaseMetric initMetric = ((RequestSession)mCallbacks).initMetric;
- TODO immediately once the other change patched through
- mCandidateProviderMetric.setSessionId(initMetric
- .mInitialPhaseMetric.getSessionId());
- mCandidateProviderMetric.setStartTime(initMetric.getStartTime())
- */
- mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime());
+ startCandidateMetrics();
mRemoteCredentialService.onClearCredentialState(mProviderRequest, this);
}
}
diff --git a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
index 3ec0fc0..2ba9c22 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderCreateSession.java
@@ -40,6 +40,8 @@
import android.util.Pair;
import android.util.Slog;
+import com.android.server.credentials.metrics.EntryEnum;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
@@ -65,7 +67,8 @@
private final ProviderResponseDataHandler mProviderResponseDataHandler;
/** Creates a new provider session to be used by the request session. */
- @Nullable public static ProviderCreateSession createNewSession(
+ @Nullable
+ public static ProviderCreateSession createNewSession(
Context context,
@UserIdInt int userId,
CredentialProviderInfo providerInfo,
@@ -155,6 +158,7 @@
// Store query phase exception for aggregation with final response
mProviderException = (CreateCredentialException) exception;
}
+ captureCandidateFailureInMetrics();
updateStatusAndInvokeCallback(toStatus(errorCode));
}
@@ -175,14 +179,40 @@
mProviderResponseDataHandler.addResponseContent(response.getCreateEntries(),
response.getRemoteCreateEntry());
if (mProviderResponseDataHandler.isEmptyResponse(response)) {
+ gatherCandidateEntryMetrics(response);
updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE);
} else {
+ gatherCandidateEntryMetrics(response);
updateStatusAndInvokeCallback(Status.SAVE_ENTRIES_RECEIVED);
}
}
+ private void gatherCandidateEntryMetrics(BeginCreateCredentialResponse response) {
+ try {
+ var createEntries = response.getCreateEntries();
+ int numRemoteEntry = MetricUtilities.ZERO;
+ if (response.getRemoteCreateEntry() != null) {
+ numRemoteEntry = MetricUtilities.UNIT;
+ mCandidatePhasePerProviderMetric.addEntry(EntryEnum.REMOTE_ENTRY);
+ }
+ int numCreateEntries =
+ createEntries == null ? MetricUtilities.ZERO : createEntries.size();
+ if (numCreateEntries > MetricUtilities.ZERO) {
+ createEntries.forEach(c ->
+ mCandidatePhasePerProviderMetric.addEntry(EntryEnum.CREDENTIAL_ENTRY));
+ }
+ mCandidatePhasePerProviderMetric.setNumEntriesTotal(numCreateEntries + numRemoteEntry);
+ mCandidatePhasePerProviderMetric.setRemoteEntryCount(numRemoteEntry);
+ mCandidatePhasePerProviderMetric.setCredentialEntryCount(numCreateEntries);
+ mCandidatePhasePerProviderMetric.setCredentialEntryTypeCount(MetricUtilities.UNIT);
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
+ }
+ }
+
@Override
- @Nullable protected CreateCredentialProviderData prepareUiData()
+ @Nullable
+ protected CreateCredentialProviderData prepareUiData()
throws IllegalArgumentException {
Log.i(TAG, "In prepareUiData");
if (!ProviderSession.isUiInvokingStatus(getStatus())) {
@@ -226,14 +256,7 @@
@Override
protected void invokeSession() {
if (mRemoteCredentialService != null) {
- /*
- InitialPhaseMetric initMetric = ((RequestSession)mCallbacks).initMetric;
- TODO immediately once the other change patched through
- mCandidateProviderMetric.setSessionId(initMetric
- .mInitialPhaseMetric.getSessionId());
- mCandidateProviderMetric.setStartTime(initMetric.getStartTime())
- */
- mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime());
+ startCandidateMetrics();
mRemoteCredentialService.onCreateCredential(mProviderRequest, this);
}
}
@@ -305,12 +328,14 @@
}
private class ProviderResponseDataHandler {
- @Nullable private final ComponentName mExpectedRemoteEntryProviderService;
+ @Nullable
+ private final ComponentName mExpectedRemoteEntryProviderService;
@NonNull
private final Map<String, Pair<CreateEntry, Entry>> mUiCreateEntries = new HashMap<>();
- @Nullable private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
+ @Nullable
+ private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
ProviderResponseDataHandler(@Nullable ComponentName expectedRemoteEntryProviderService) {
mExpectedRemoteEntryProviderService = expectedRemoteEntryProviderService;
@@ -323,6 +348,7 @@
setRemoteEntry(remoteEntry);
}
}
+
public void addCreateEntry(CreateEntry createEntry) {
String id = generateUniqueId();
Entry entry = new Entry(SAVE_ENTRY_KEY,
@@ -373,6 +399,7 @@
private boolean isEmptyResponse() {
return mUiCreateEntries.isEmpty() && mUiRemoteEntry == null;
}
+
@Nullable
public RemoteEntry getRemoteEntry(String entryKey) {
return mUiRemoteEntry == null || mUiRemoteEntry
diff --git a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
index ec8bf22..95b0ff0 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderGetSession.java
@@ -43,11 +43,14 @@
import android.util.Pair;
import android.util.Slog;
+import com.android.server.credentials.metrics.EntryEnum;
+
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
+import java.util.stream.Collectors;
/**
* Central provider session that listens for provider callbacks, and maintains provider state.
@@ -82,7 +85,8 @@
private final ProviderResponseDataHandler mProviderResponseDataHandler;
/** Creates a new provider session to be used by the request session. */
- @Nullable public static ProviderGetSession createNewSession(
+ @Nullable
+ public static ProviderGetSession createNewSession(
Context context,
@UserIdInt int userId,
CredentialProviderInfo providerInfo,
@@ -90,7 +94,8 @@
RemoteCredentialService remoteCredentialService) {
android.credentials.GetCredentialRequest filteredRequest =
filterOptions(providerInfo.getCapabilities(),
- getRequestSession.mClientRequest);
+ getRequestSession.mClientRequest,
+ providerInfo.getComponentName());
if (filteredRequest != null) {
Map<String, CredentialOption> beginGetOptionToCredentialOptionMap =
new HashMap<>();
@@ -113,6 +118,7 @@
Log.i(TAG, "Unable to create provider session");
return null;
}
+
private static BeginGetCredentialRequest constructQueryPhaseRequest(
android.credentials.GetCredentialRequest filteredRequest,
CallingAppInfo callingAppInfo,
@@ -137,17 +143,19 @@
@Nullable
private static android.credentials.GetCredentialRequest filterOptions(
List<String> providerCapabilities,
- android.credentials.GetCredentialRequest clientRequest
+ android.credentials.GetCredentialRequest clientRequest,
+ ComponentName componentName
) {
List<CredentialOption> filteredOptions = new ArrayList<>();
for (CredentialOption option : clientRequest.getCredentialOptions()) {
- if (providerCapabilities.contains(option.getType())) {
+ if (providerCapabilities.contains(option.getType())
+ && isProviderAllowed(option, componentName)) {
Log.i(TAG, "In createProviderRequest - capability found : "
+ option.getType());
filteredOptions.add(option);
} else {
Log.i(TAG, "In createProviderRequest - capability not "
- + "found : " + option.getType());
+ + "found, or provider not allowed : " + option.getType());
}
}
if (!filteredOptions.isEmpty()) {
@@ -160,6 +168,16 @@
return null;
}
+ private static boolean isProviderAllowed(CredentialOption option, ComponentName componentName) {
+ if (!option.getAllowedProviders().isEmpty() && !option.getAllowedProviders().contains(
+ componentName)) {
+ Log.d(TAG, "Provider allow list specified but does not contain this provider: "
+ + componentName.flattenToString());
+ return false;
+ }
+ return true;
+ }
+
public ProviderGetSession(Context context,
CredentialProviderInfo info,
ProviderInternalCallback<GetCredentialResponse> callbacks,
@@ -169,7 +187,7 @@
CallingAppInfo callingAppInfo,
Map<String, CredentialOption> beginGetOptionToCredentialOptionMap,
String hybridService) {
- super(context, beginGetRequest, callbacks, info.getComponentName() ,
+ super(context, beginGetRequest, callbacks, info.getComponentName(),
userId, remoteCredentialService);
mCompleteRequest = completeGetRequest;
mCallingAppInfo = callingAppInfo;
@@ -191,6 +209,7 @@
if (exception instanceof GetCredentialException) {
mProviderException = (GetCredentialException) exception;
}
+ captureCandidateFailureInMetrics();
updateStatusAndInvokeCallback(toStatus(errorCode));
}
@@ -269,20 +288,14 @@
@Override
protected void invokeSession() {
if (mRemoteCredentialService != null) {
- /*
- InitialPhaseMetric initMetric = ((RequestSession)mCallbacks).initMetric;
- TODO immediately once the other change patched through
- mCandidateProviderMetric.setSessionId(initMetric
- .mInitialPhaseMetric.getSessionId());
- mCandidateProviderMetric.setStartTime(initMetric.getStartTime())
- */
- mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime());
+ startCandidateMetrics();
mRemoteCredentialService.onBeginGetCredential(mProviderRequest, this);
}
}
@Override // Call from request session to data to be shown on the UI
- @Nullable protected GetCredentialProviderData prepareUiData() throws IllegalArgumentException {
+ @Nullable
+ protected GetCredentialProviderData prepareUiData() throws IllegalArgumentException {
Log.i(TAG, "In prepareUiData");
if (!ProviderSession.isUiInvokingStatus(getStatus())) {
Log.i(TAG, "In prepareUiData - provider does not want to show UI: "
@@ -389,6 +402,7 @@
GetCredentialException exception = maybeGetPendingIntentException(
providerPendingIntentResponse);
if (exception != null) {
+ // TODO (b/271135048), for AuthenticationEntry callback selection, set error
invokeCallbackWithError(exception.getType(),
exception.getMessage());
// Additional content received is in the form of an exception which ends the flow.
@@ -439,11 +453,41 @@
updateStatusAndInvokeCallback(Status.EMPTY_RESPONSE);
return;
}
- // TODO immediately, add to Candidate Phase counts, repeat across all sessions
- // Use sets to dedup type counts
+ gatherCandidateEntryMetrics(response);
updateStatusAndInvokeCallback(Status.CREDENTIALS_RECEIVED);
}
+ private void gatherCandidateEntryMetrics(BeginGetCredentialResponse response) {
+ try {
+ int numCredEntries = response.getCredentialEntries().size();
+ int numActionEntries = response.getActions().size();
+ int numAuthEntries = response.getAuthenticationActions().size();
+ int numRemoteEntry = MetricUtilities.ZERO;
+ if (response.getRemoteCredentialEntry() != null) {
+ numRemoteEntry = MetricUtilities.UNIT;
+ mCandidatePhasePerProviderMetric.addEntry(EntryEnum.REMOTE_ENTRY);
+ }
+ response.getCredentialEntries().forEach(c ->
+ mCandidatePhasePerProviderMetric.addEntry(EntryEnum.CREDENTIAL_ENTRY));
+ response.getActions().forEach(c ->
+ mCandidatePhasePerProviderMetric.addEntry(EntryEnum.ACTION_ENTRY));
+ response.getAuthenticationActions().forEach(c ->
+ mCandidatePhasePerProviderMetric.addEntry(EntryEnum.AUTHENTICATION_ENTRY));
+ mCandidatePhasePerProviderMetric.setNumEntriesTotal(numCredEntries + numAuthEntries
+ + numActionEntries + numRemoteEntry);
+ mCandidatePhasePerProviderMetric.setCredentialEntryCount(numCredEntries);
+ int numTypes = (response.getCredentialEntries().stream()
+ .map(CredentialEntry::getType).collect(
+ Collectors.toSet())).size(); // Dedupe type strings
+ mCandidatePhasePerProviderMetric.setCredentialEntryTypeCount(numTypes);
+ mCandidatePhasePerProviderMetric.setActionEntryCount(numActionEntries);
+ mCandidatePhasePerProviderMetric.setAuthenticationEntryCount(numAuthEntries);
+ mCandidatePhasePerProviderMetric.setRemoteEntryCount(numRemoteEntry);
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
+ }
+ }
+
/**
* When an invalid state occurs, e.g. entry mismatch or no response from provider,
* we send back a TYPE_NO_CREDENTIAL error as to the developer.
@@ -471,11 +515,12 @@
.STATUS_UNLOCKED_BUT_EMPTY_LESS_RECENT
|| e.second.getStatus()
== AuthenticationEntry.STATUS_UNLOCKED_BUT_EMPTY_MOST_RECENT
- );
+ );
}
private class ProviderResponseDataHandler {
- @Nullable private final ComponentName mExpectedRemoteEntryProviderService;
+ @Nullable
+ private final ComponentName mExpectedRemoteEntryProviderService;
@NonNull
private final Map<String, Pair<CredentialEntry, Entry>> mUiCredentialEntries =
new HashMap<>();
@@ -485,7 +530,8 @@
private final Map<String, Pair<Action, AuthenticationEntry>> mUiAuthenticationEntries =
new HashMap<>();
- @Nullable private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
+ @Nullable
+ private Pair<String, Pair<RemoteEntry, Entry>> mUiRemoteEntry = null;
ProviderResponseDataHandler(@Nullable ComponentName expectedRemoteEntryProviderService) {
mExpectedRemoteEntryProviderService = expectedRemoteEntryProviderService;
@@ -509,6 +555,7 @@
setRemoteEntry(remoteEntry);
}
}
+
public void addCredentialEntry(CredentialEntry credentialEntry) {
String id = generateUniqueId();
Entry entry = new Entry(CREDENTIAL_ENTRY_KEY,
@@ -559,7 +606,6 @@
}
-
public GetCredentialProviderData toGetCredentialProviderData() {
return new GetCredentialProviderData.Builder(
mComponentName.flattenToString()).setActionChips(prepareActionEntries())
diff --git a/services/credentials/java/com/android/server/credentials/ProviderSession.java b/services/credentials/java/com/android/server/credentials/ProviderSession.java
index 77d4e77..64ac9b3 100644
--- a/services/credentials/java/com/android/server/credentials/ProviderSession.java
+++ b/services/credentials/java/com/android/server/credentials/ProviderSession.java
@@ -32,6 +32,7 @@
import android.util.Log;
import com.android.server.credentials.metrics.CandidatePhaseMetric;
+import com.android.server.credentials.metrics.InitialPhaseMetric;
import com.android.server.credentials.metrics.ProviderStatusForMetrics;
import java.util.UUID;
@@ -72,8 +73,9 @@
@NonNull
protected Boolean mProviderResponseSet = false;
// Specific candidate provider metric for the provider this session handles
- @Nullable
- protected CandidatePhaseMetric mCandidatePhasePerProviderMetric;
+ @NonNull
+ protected final CandidatePhaseMetric mCandidatePhasePerProviderMetric =
+ new CandidatePhaseMetric();
@NonNull
private int mProviderSessionUid;
@@ -143,7 +145,6 @@
mUserId = userId;
mComponentName = componentName;
mRemoteCredentialService = remoteCredentialService;
- mCandidatePhasePerProviderMetric = new CandidatePhaseMetric();
mProviderSessionUid = MetricUtilities.getPackageUid(mContext, mComponentName);
}
@@ -208,6 +209,10 @@
return mRemoteCredentialService;
}
+ protected void captureCandidateFailureInMetrics() {
+ mCandidatePhasePerProviderMetric.setHasException(true);
+ }
+
/** Updates the status . */
protected void updateStatusAndInvokeCallback(@NonNull Status status) {
setStatus(status);
@@ -216,18 +221,36 @@
}
private void updateCandidateMetric(Status status) {
- mCandidatePhasePerProviderMetric.setCandidateUid(mProviderSessionUid);
- // TODO immediately update the candidate phase here to have more new data
- mCandidatePhasePerProviderMetric
- .setQueryFinishTimeNanoseconds(System.nanoTime());
- if (isTerminatingStatus(status)) {
- mCandidatePhasePerProviderMetric.setProviderQueryStatus(
- ProviderStatusForMetrics.QUERY_FAILURE
- .getMetricCode());
- } else if (isCompletionStatus(status)) {
- mCandidatePhasePerProviderMetric.setProviderQueryStatus(
- ProviderStatusForMetrics.QUERY_SUCCESS
- .getMetricCode());
+ try {
+ mCandidatePhasePerProviderMetric.setCandidateUid(mProviderSessionUid);
+ mCandidatePhasePerProviderMetric
+ .setQueryFinishTimeNanoseconds(System.nanoTime());
+ if (isTerminatingStatus(status)) {
+ mCandidatePhasePerProviderMetric.setQueryReturned(false);
+ mCandidatePhasePerProviderMetric.setProviderQueryStatus(
+ ProviderStatusForMetrics.QUERY_FAILURE
+ .getMetricCode());
+ } else if (isCompletionStatus(status)) {
+ mCandidatePhasePerProviderMetric.setQueryReturned(true);
+ mCandidatePhasePerProviderMetric.setProviderQueryStatus(
+ ProviderStatusForMetrics.QUERY_SUCCESS
+ .getMetricCode());
+ }
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
+ }
+ }
+
+ // Common method to transfer metrics from the initial phase to the candidate phase per provider
+ protected void startCandidateMetrics() {
+ try {
+ InitialPhaseMetric initMetric = ((RequestSession) mCallbacks).mInitialPhaseMetric;
+ mCandidatePhasePerProviderMetric.setSessionId(initMetric.getSessionId());
+ mCandidatePhasePerProviderMetric.setServiceBeganTimeNanoseconds(
+ initMetric.getCredentialServiceStartedTimeNanoseconds());
+ mCandidatePhasePerProviderMetric.setStartQueryTimeNanoseconds(System.nanoTime());
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
}
}
diff --git a/services/credentials/java/com/android/server/credentials/RequestSession.java b/services/credentials/java/com/android/server/credentials/RequestSession.java
index 5dc7adf..0aa080b 100644
--- a/services/credentials/java/com/android/server/credentials/RequestSession.java
+++ b/services/credentials/java/com/android/server/credentials/RequestSession.java
@@ -34,13 +34,12 @@
import android.util.Log;
import com.android.internal.R;
-import com.android.server.credentials.metrics.ApiName;
-import com.android.server.credentials.metrics.ApiStatus;
import com.android.server.credentials.metrics.CandidateBrowsingPhaseMetric;
import com.android.server.credentials.metrics.CandidatePhaseMetric;
import com.android.server.credentials.metrics.ChosenProviderFinalPhaseMetric;
import com.android.server.credentials.metrics.EntryEnum;
import com.android.server.credentials.metrics.InitialPhaseMetric;
+import com.android.server.credentials.metrics.ProviderStatusForMetrics;
import java.util.ArrayList;
import java.util.HashMap;
@@ -78,8 +77,8 @@
protected final CancellationSignal mCancellationSignal;
protected final Map<String, ProviderSession> mProviders = new HashMap<>();
- protected InitialPhaseMetric mInitialPhaseMetric = new InitialPhaseMetric();
- protected ChosenProviderFinalPhaseMetric
+ protected final InitialPhaseMetric mInitialPhaseMetric = new InitialPhaseMetric();
+ protected final ChosenProviderFinalPhaseMetric
mChosenProviderFinalPhaseMetric = new ChosenProviderFinalPhaseMetric();
// TODO(b/271135048) - Group metrics used in a scope together, such as here in RequestSession
@@ -123,9 +122,17 @@
mUserId, this);
mHybridService = context.getResources().getString(
R.string.config_defaultCredentialManagerHybridService);
- mInitialPhaseMetric.setCredentialServiceStartedTimeNanoseconds(timestampStarted);
- mInitialPhaseMetric.setSessionId(mRequestId.hashCode());
- mInitialPhaseMetric.setCallerUid(mCallingUid);
+ initialPhaseMetricSetup(timestampStarted);
+ }
+
+ private void initialPhaseMetricSetup(long timestampStarted) {
+ try {
+ mInitialPhaseMetric.setCredentialServiceStartedTimeNanoseconds(timestampStarted);
+ mInitialPhaseMetric.setSessionId(mRequestId.hashCode());
+ mInitialPhaseMetric.setCallerUid(mCallingUid);
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
+ }
}
public abstract ProviderSession initiateProviderSession(CredentialProviderInfo providerInfo,
@@ -170,13 +177,17 @@
private void logBrowsingPhasePerSelect(UserSelectionDialogResult selection,
ProviderSession providerSession) {
- CandidateBrowsingPhaseMetric browsingPhaseMetric = new CandidateBrowsingPhaseMetric();
- browsingPhaseMetric.setSessionId(this.mInitialPhaseMetric.getSessionId());
- browsingPhaseMetric.setEntryEnum(
- EntryEnum.getMetricCodeFromString(selection.getEntryKey()));
- browsingPhaseMetric.setProviderUid(providerSession.mCandidatePhasePerProviderMetric
- .getCandidateUid());
- this.mCandidateBrowsingPhaseMetric.add(new CandidateBrowsingPhaseMetric());
+ try {
+ CandidateBrowsingPhaseMetric browsingPhaseMetric = new CandidateBrowsingPhaseMetric();
+ browsingPhaseMetric.setSessionId(this.mInitialPhaseMetric.getSessionId());
+ browsingPhaseMetric.setEntryEnum(
+ EntryEnum.getMetricCodeFromString(selection.getEntryKey()));
+ browsingPhaseMetric.setProviderUid(providerSession.mCandidatePhasePerProviderMetric
+ .getCandidateUid());
+ this.mCandidateBrowsingPhaseMetric.add(browsingPhaseMetric);
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
+ }
}
protected void finishSession(boolean propagateCancellation) {
@@ -197,16 +208,12 @@
return false;
}
- protected void logApiCall(ApiName apiName, ApiStatus apiStatus) {
- logApiCalled(apiName, apiStatus, mProviders, mCallingUid,
- mChosenProviderFinalPhaseMetric);
- }
-
protected void logApiCall(ChosenProviderFinalPhaseMetric finalPhaseMetric,
- List<CandidateBrowsingPhaseMetric> browsingPhaseMetrics) {
+ List<CandidateBrowsingPhaseMetric> browsingPhaseMetrics, int apiStatus) {
// TODO (b/270403549) - this browsing phase object is fine but also have a new emit
// For the returned types by authentication entries - i.e. a CandidatePhase During Browse
- // TODO call MetricUtilities with new setup
+ // Possibly think of adding in more atoms for other APIs as well.
+ logApiCalled(finalPhaseMetric, browsingPhaseMetrics, apiStatus, ++mSequenceCounter);
}
protected boolean isSessionCancelled() {
@@ -233,6 +240,7 @@
Log.i(TAG, "In getProviderDataAndInitiateUi providers size: " + mProviders.size());
if (isSessionCancelled()) {
+ MetricUtilities.logApiCalled(mProviders, ++mSequenceCounter);
finishSession(/*propagateCancellation=*/true);
return;
}
@@ -248,38 +256,59 @@
}
if (!providerDataList.isEmpty()) {
Log.i(TAG, "provider list not empty about to initiate ui");
- // TODO immediately Add paths to end it (say it fails)
- if (isSessionCancelled()) {
- Log.i(TAG, "In getProviderDataAndInitiateUi but session has been cancelled");
- // TODO immedaitely Add paths
- } else {
- launchUiWithProviderData(providerDataList);
- }
+ MetricUtilities.logApiCalled(mProviders, ++mSequenceCounter);
+ launchUiWithProviderData(providerDataList);
}
}
+ protected void collectFinalPhaseMetricStatus(boolean hasException,
+ ProviderStatusForMetrics finalSuccess) {
+ mChosenProviderFinalPhaseMetric.setHasException(hasException);
+ mChosenProviderFinalPhaseMetric.setChosenProviderStatus(
+ finalSuccess.getMetricCode());
+ }
+
/**
- * Called by RequestSession's upon chosen metric determination.
+ * Called by RequestSession's upon chosen metric determination. It's expected that most bits
+ * are transferred here. However, certain new information, such as the selected provider's final
+ * exception bit, the framework to ui and back latency, or the ui response bit are set at other
+ * locations. Other information, such browsing metrics, api_status, and the sequence id count
+ * are combined together during the final emit moment with the actual and official
+ * {@link com.android.internal.util.FrameworkStatsLog} metric generation.
*
* @param componentName the componentName to associate with a provider
*/
protected void setChosenMetric(ComponentName componentName) {
- CandidatePhaseMetric metric = this.mProviders.get(componentName.flattenToString())
- .mCandidatePhasePerProviderMetric;
+ try {
+ CandidatePhaseMetric metric = this.mProviders.get(componentName.flattenToString())
+ .mCandidatePhasePerProviderMetric;
- mChosenProviderFinalPhaseMetric.setSessionId(metric.getSessionId());
- mChosenProviderFinalPhaseMetric.setChosenUid(metric.getCandidateUid());
+ mChosenProviderFinalPhaseMetric.setSessionId(metric.getSessionId());
+ mChosenProviderFinalPhaseMetric.setChosenUid(metric.getCandidateUid());
- mChosenProviderFinalPhaseMetric.setQueryPhaseLatencyMicroseconds(
- metric.getQueryLatencyMicroseconds());
+ mChosenProviderFinalPhaseMetric.setQueryPhaseLatencyMicroseconds(
+ metric.getQueryLatencyMicroseconds());
- mChosenProviderFinalPhaseMetric.setServiceBeganTimeNanoseconds(
- metric.getServiceBeganTimeNanoseconds());
- mChosenProviderFinalPhaseMetric.setQueryStartTimeNanoseconds(
- metric.getStartQueryTimeNanoseconds());
+ mChosenProviderFinalPhaseMetric.setServiceBeganTimeNanoseconds(
+ metric.getServiceBeganTimeNanoseconds());
+ mChosenProviderFinalPhaseMetric.setQueryStartTimeNanoseconds(
+ metric.getStartQueryTimeNanoseconds());
+ mChosenProviderFinalPhaseMetric.setQueryEndTimeNanoseconds(metric
+ .getQueryFinishTimeNanoseconds());
- // TODO immediately update with the entry count numbers from the candidate metrics
-
- mChosenProviderFinalPhaseMetric.setFinalFinishTimeNanoseconds(System.nanoTime());
+ mChosenProviderFinalPhaseMetric.setNumEntriesTotal(metric.getNumEntriesTotal());
+ mChosenProviderFinalPhaseMetric.setCredentialEntryCount(metric
+ .getCredentialEntryCount());
+ mChosenProviderFinalPhaseMetric.setCredentialEntryTypeCount(
+ metric.getCredentialEntryTypeCount());
+ mChosenProviderFinalPhaseMetric.setActionEntryCount(metric.getActionEntryCount());
+ mChosenProviderFinalPhaseMetric.setRemoteEntryCount(metric.getRemoteEntryCount());
+ mChosenProviderFinalPhaseMetric.setAuthenticationEntryCount(
+ metric.getAuthenticationEntryCount());
+ mChosenProviderFinalPhaseMetric.setAvailableEntries(metric.getAvailableEntries());
+ mChosenProviderFinalPhaseMetric.setFinalFinishTimeNanoseconds(System.nanoTime());
+ } catch (Exception e) {
+ Log.w(TAG, "Unexpected error during metric logging: " + e);
+ }
}
}
diff --git a/services/credentials/java/com/android/server/credentials/metrics/ApiName.java b/services/credentials/java/com/android/server/credentials/metrics/ApiName.java
index d4b51df..abd749c 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/ApiName.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/ApiName.java
@@ -16,19 +16,19 @@
package com.android.server.credentials.metrics;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CLEAR_CREDENTIAL;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CREATE_CREDENTIAL;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_GET_CREDENTIAL;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_CLEAR_CREDENTIAL;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_CREATE_CREDENTIAL;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_GET_CREDENTIAL;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_UNKNOWN;
public enum ApiName {
- UNKNOWN(CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_UNKNOWN),
- GET_CREDENTIAL(CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_GET_CREDENTIAL),
- CREATE_CREDENTIAL(CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CREATE_CREDENTIAL),
- CLEAR_CREDENTIAL(CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CLEAR_CREDENTIAL),
+ UNKNOWN(CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_UNKNOWN),
+ GET_CREDENTIAL(CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_GET_CREDENTIAL),
+ CREATE_CREDENTIAL(CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_CREATE_CREDENTIAL),
+ CLEAR_CREDENTIAL(CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_CLEAR_CREDENTIAL),
IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE(
- CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE
+ CREDENTIAL_MANAGER_INITIAL_PHASE__API_NAME__API_NAME_IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE
);
private final int mInnerMetricCode;
diff --git a/services/credentials/java/com/android/server/credentials/metrics/ApiStatus.java b/services/credentials/java/com/android/server/credentials/metrics/ApiStatus.java
index 22cab70..8fea369 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/ApiStatus.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/ApiStatus.java
@@ -16,18 +16,18 @@
package com.android.server.credentials.metrics;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_CLIENT_CANCELED;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_FAILURE;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_SUCCESS;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_USER_CANCELED;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__API_STATUS__API_STATUS_CLIENT_CANCELED;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__API_STATUS__API_STATUS_FAILURE;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__API_STATUS__API_STATUS_SUCCESS;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__API_STATUS__API_STATUS_USER_CANCELED;
public enum ApiStatus {
- SUCCESS(CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_SUCCESS),
- FAILURE(CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_FAILURE),
+ SUCCESS(CREDENTIAL_MANAGER_FINAL_PHASE__API_STATUS__API_STATUS_SUCCESS),
+ FAILURE(CREDENTIAL_MANAGER_FINAL_PHASE__API_STATUS__API_STATUS_FAILURE),
CLIENT_CANCELED(
- CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_CLIENT_CANCELED),
+ CREDENTIAL_MANAGER_FINAL_PHASE__API_STATUS__API_STATUS_CLIENT_CANCELED),
USER_CANCELED(
- CREDENTIAL_MANAGER_API_CALLED__API_STATUS__API_STATUS_USER_CANCELED);
+ CREDENTIAL_MANAGER_FINAL_PHASE__API_STATUS__API_STATUS_USER_CANCELED);
private final int mInnerMetricCode;
diff --git a/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java
index c392d78..4053294 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/CandidatePhaseMetric.java
@@ -20,6 +20,9 @@
import com.android.server.credentials.MetricUtilities;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* The central candidate provider metric object that mimics our defined metric setup.
* Some types are redundant across these metric collectors, but that has debug use-cases as
@@ -66,6 +69,8 @@
private int mRemoteEntryCount = -1;
// The count of authentication entries from this provider, defaults to -1
private int mAuthenticationEntryCount = -1;
+ // Gathered to pass on to chosen provider when required
+ private final List<Integer> mAvailableEntries = new ArrayList<>();
public CandidatePhaseMetric() {
}
@@ -236,4 +241,28 @@
public int getAuthenticationEntryCount() {
return mAuthenticationEntryCount;
}
+
+ /* -------------- The Entries Gathered ---------------- */
+
+ /**
+ * Allows adding an entry record to this metric collector, which can then be propagated to
+ * the final phase to retain information on the data available to the candidate.
+ *
+ * @param e the entry enum collected by the candidate provider associated with this metric
+ * collector
+ */
+ public void addEntry(EntryEnum e) {
+ this.mAvailableEntries.add(e.getMetricCode());
+ }
+
+ /**
+ * Returns a safely copied list of the entries captured by this metric collector associated
+ * with a particular candidate provider.
+ *
+ * @return the full collection of entries encountered by the candidate provider associated with
+ * this metric
+ */
+ public List<Integer> getAvailableEntries() {
+ return new ArrayList<>(this.mAvailableEntries); // no alias copy
+ }
}
diff --git a/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java b/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java
index 32fe204..2eef197 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/ChosenProviderFinalPhaseMetric.java
@@ -20,6 +20,9 @@
import com.android.server.credentials.MetricUtilities;
+import java.util.ArrayList;
+import java.util.List;
+
/**
* The central chosen provider metric object that mimics our defined metric setup. This is used
* in the final phase of the flow and emits final status metrics.
@@ -27,14 +30,13 @@
* these data-types are available at different moments of the flow (and typically, one can feed
* into the next).
* TODO(b/270403549) - iterate on this in V3+
- * TODO(Immediately) - finalize V3 only types
*/
public class ChosenProviderFinalPhaseMetric {
// TODO(b/270403549) - applies elsewhere, likely removed or replaced w/ some hashed/count index
private static final String TAG = "ChosenFinalPhaseMetric";
// The session id associated with this API call, used to unite split emits
- private long mSessionId = -1;
+ private int mSessionId = -1;
// Reveals if the UI was returned, false by default
private boolean mUiReturned = false;
private int mChosenUid = -1;
@@ -52,6 +54,8 @@
// The first query timestamp, which upon emit is normalized to microseconds using the reference
// start timestamp
private long mQueryStartTimeNanoseconds = -1;
+ // The timestamp at query end, which upon emit will be normalized to microseconds with reference
+ private long mQueryEndTimeNanoseconds = -1;
// The UI call timestamp, which upon emit will be normalized to microseconds using reference
private long mUiCallStartTimeNanoseconds = -1;
// The UI return timestamp, which upon emit will be normalized to microseconds using reference
@@ -63,8 +67,23 @@
// Other General Information, such as final api status, provider status, entry info, etc...
private int mChosenProviderStatus = -1;
- // TODO add remaining properties based on the Atom ; specifically, migrate the candidate
- // Entry information, and store final status here
+ // Indicates if an exception was thrown by this provider, false by default
+ private boolean mHasException = false;
+ // Indicates the number of total entries available, defaults to -1. Not presently emitted, but
+ // left as a utility
+ private int mNumEntriesTotal = -1;
+ // The count of action entries from this provider, defaults to -1
+ private int mActionEntryCount = -1;
+ // The count of credential entries from this provider, defaults to -1
+ private int mCredentialEntryCount = -1;
+ // The *type-count* of the credential entries, defaults to -1
+ private int mCredentialEntryTypeCount = -1;
+ // The count of remote entries from this provider, defaults to -1
+ private int mRemoteEntryCount = -1;
+ // The count of authentication entries from this provider, defaults to -1
+ private int mAuthenticationEntryCount = -1;
+ // Gathered to pass on to chosen provider when required
+ private List<Integer> mAvailableEntries = new ArrayList<>();
public ChosenProviderFinalPhaseMetric() {
@@ -159,6 +178,10 @@
mQueryStartTimeNanoseconds = queryStartTimeNanoseconds;
}
+ public void setQueryEndTimeNanoseconds(long queryEndTimeNanoseconds) {
+ mQueryEndTimeNanoseconds = queryEndTimeNanoseconds;
+ }
+
public void setUiCallStartTimeNanoseconds(long uiCallStartTimeNanoseconds) {
this.mUiCallStartTimeNanoseconds = uiCallStartTimeNanoseconds;
}
@@ -179,6 +202,10 @@
return mQueryStartTimeNanoseconds;
}
+ public long getQueryEndTimeNanoseconds() {
+ return mQueryEndTimeNanoseconds;
+ }
+
public long getUiCallStartTimeNanoseconds() {
return mUiCallStartTimeNanoseconds;
}
@@ -222,11 +249,11 @@
/* ----------- Session ID -------------- */
- public void setSessionId(long sessionId) {
+ public void setSessionId(int sessionId) {
mSessionId = sessionId;
}
- public long getSessionId() {
+ public int getSessionId() {
return mSessionId;
}
@@ -239,4 +266,95 @@
public boolean isUiReturned() {
return mUiReturned;
}
+
+ /* -------------- Number of Entries ---------------- */
+
+ public void setNumEntriesTotal(int numEntriesTotal) {
+ mNumEntriesTotal = numEntriesTotal;
+ }
+
+ public int getNumEntriesTotal() {
+ return mNumEntriesTotal;
+ }
+
+ /* -------------- Count of Action Entries ---------------- */
+
+ public void setActionEntryCount(int actionEntryCount) {
+ mActionEntryCount = actionEntryCount;
+ }
+
+ public int getActionEntryCount() {
+ return mActionEntryCount;
+ }
+
+ /* -------------- Count of Credential Entries ---------------- */
+
+ public void setCredentialEntryCount(int credentialEntryCount) {
+ mCredentialEntryCount = credentialEntryCount;
+ }
+
+ public int getCredentialEntryCount() {
+ return mCredentialEntryCount;
+ }
+
+ /* -------------- Count of Credential Entry Types ---------------- */
+
+ public void setCredentialEntryTypeCount(int credentialEntryTypeCount) {
+ mCredentialEntryTypeCount = credentialEntryTypeCount;
+ }
+
+ public int getCredentialEntryTypeCount() {
+ return mCredentialEntryTypeCount;
+ }
+
+ /* -------------- Count of Remote Entries ---------------- */
+
+ public void setRemoteEntryCount(int remoteEntryCount) {
+ mRemoteEntryCount = remoteEntryCount;
+ }
+
+ public int getRemoteEntryCount() {
+ return mRemoteEntryCount;
+ }
+
+ /* -------------- Count of Authentication Entries ---------------- */
+
+ public void setAuthenticationEntryCount(int authenticationEntryCount) {
+ mAuthenticationEntryCount = authenticationEntryCount;
+ }
+
+ public int getAuthenticationEntryCount() {
+ return mAuthenticationEntryCount;
+ }
+
+ /* -------------- The Entries Gathered ---------------- */
+
+ /**
+ * Sets the collected list of entries from the candidate phase to be retrievable in the
+ * chosen phase in a semantically correct way.
+ */
+ public void setAvailableEntries(List<Integer> entries) {
+ this.mAvailableEntries = new ArrayList<>(entries); // no alias copy
+ }
+
+ /**
+ * Returns a list of the entries captured by this metric collector associated
+ * with a particular chosen provider.
+ *
+ * @return the full collection of entries encountered by the chosen provider during the
+ * candidate phase.
+ */
+ public List<Integer> getAvailableEntries() {
+ return new ArrayList<>(this.mAvailableEntries); // no alias copy
+ }
+
+ /* -------------- Has Exception ---------------- */
+
+ public void setHasException(boolean hasException) {
+ mHasException = hasException;
+ }
+
+ public boolean isHasException() {
+ return mHasException;
+ }
}
diff --git a/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java b/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java
index 73403a6..440ac51 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/EntryEnum.java
@@ -16,11 +16,11 @@
package com.android.server.credentials.metrics;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CLEAR_CREDENTIAL;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CREATE_CREDENTIAL;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_GET_CREDENTIAL;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__ACTION_ENTRY;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__AUTHENTICATION_ENTRY;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__CREDENTIAL_ENTRY;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__REMOTE_ENTRY;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__UNKNOWN;
import static com.android.server.credentials.ProviderGetSession.ACTION_ENTRY_KEY;
import static com.android.server.credentials.ProviderGetSession.AUTHENTICATION_ACTION_ENTRY_KEY;
import static com.android.server.credentials.ProviderGetSession.CREDENTIAL_ENTRY_KEY;
@@ -32,13 +32,12 @@
import java.util.Map;
public enum EntryEnum {
- // TODO immediately, update with built entries
- UNKNOWN(CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_UNKNOWN),
- ACTION_ENTRY(CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_GET_CREDENTIAL),
- CREDENTIAL_ENTRY(CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CREATE_CREDENTIAL),
- REMOTE_ENTRY(CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_CLEAR_CREDENTIAL),
+ UNKNOWN(CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__UNKNOWN),
+ ACTION_ENTRY(CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__ACTION_ENTRY),
+ CREDENTIAL_ENTRY(CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__CREDENTIAL_ENTRY),
+ REMOTE_ENTRY(CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__REMOTE_ENTRY),
AUTHENTICATION_ENTRY(
- CREDENTIAL_MANAGER_API_CALLED__API_NAME__API_NAME_IS_ENABLED_CREDENTIAL_PROVIDER_SERVICE
+ CREDENTIAL_MANAGER_FINAL_PHASE__CLICKED_ENTRIES__AUTHENTICATION_ENTRY
);
private static final String TAG = "EntryEnum";
diff --git a/services/credentials/java/com/android/server/credentials/metrics/ProviderStatusForMetrics.java b/services/credentials/java/com/android/server/credentials/metrics/ProviderStatusForMetrics.java
index 08f1afa..83713ab 100644
--- a/services/credentials/java/com/android/server/credentials/metrics/ProviderStatusForMetrics.java
+++ b/services/credentials/java/com/android/server/credentials/metrics/ProviderStatusForMetrics.java
@@ -16,24 +16,24 @@
package com.android.server.credentials.metrics;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_FINAL_FAILURE;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_FINAL_SUCCESS;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_QUERY_FAILURE;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_QUERY_SUCCESS;
-import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_UNKNOWN;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_FINAL_FAILURE;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_FINAL_SUCCESS;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_QUERY_FAILURE;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_QUERY_SUCCESS;
+import static com.android.internal.util.FrameworkStatsLog.CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_UNKNOWN;
public enum ProviderStatusForMetrics {
UNKNOWN(
- CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_UNKNOWN),
+ CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_UNKNOWN),
FINAL_FAILURE(
- CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_FINAL_FAILURE),
+ CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_FINAL_FAILURE),
QUERY_FAILURE(
- CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_QUERY_FAILURE),
+ CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_QUERY_FAILURE),
FINAL_SUCCESS(
- CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_FINAL_SUCCESS),
+ CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_FINAL_SUCCESS),
QUERY_SUCCESS(
- CREDENTIAL_MANAGER_API_CALLED__CANDIDATE_PROVIDER_STATUS__PROVIDER_QUERY_SUCCESS);
+ CREDENTIAL_MANAGER_FINAL_PHASE__CHOSEN_PROVIDER_STATUS__PROVIDER_QUERY_SUCCESS);
private final int mInnerMetricCode;
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
index d73f5a5..7a01b1c 100644
--- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
+++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java
@@ -77,6 +77,7 @@
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WINDOWS;
import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIPE_DATA;
+import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS;
import static android.Manifest.permission.QUERY_ADMIN_POLICY;
import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY;
import static android.Manifest.permission.SET_TIME;
@@ -95,6 +96,7 @@
import static android.app.admin.DeviceAdminReceiver.EXTRA_TRANSFER_OWNERSHIP_ADMIN_EXTRAS_BUNDLE;
import static android.app.admin.DevicePolicyIdentifiers.AUTO_TIMEZONE_POLICY;
import static android.app.admin.DevicePolicyManager.ACTION_CHECK_POLICY_COMPLIANCE;
+import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_FINANCING_STATE_CHANGED;
import static android.app.admin.DevicePolicyManager.ACTION_DEVICE_POLICY_RESOURCE_UPDATED;
import static android.app.admin.DevicePolicyManager.ACTION_MANAGED_PROFILE_PROVISIONED;
import static android.app.admin.DevicePolicyManager.ACTION_PROVISION_MANAGED_DEVICE;
@@ -223,6 +225,7 @@
import static android.net.ConnectivityManager.PROFILE_NETWORK_PREFERENCE_ENTERPRISE_NO_FALLBACK;
import static android.net.NetworkStack.PERMISSION_MAINLINE_NETWORK_STACK;
import static android.provider.DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER;
+import static android.provider.DeviceConfig.NAMESPACE_TELEPHONY;
import static android.provider.Settings.Global.PRIVATE_DNS_SPECIFIER;
import static android.provider.Settings.Secure.MANAGED_PROVISIONING_DPC_DOWNLOADED;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
@@ -424,6 +427,7 @@
import android.security.keystore.KeyGenParameterSpec;
import android.security.keystore.ParcelableKeyGenParameterSpec;
import android.stats.devicepolicy.DevicePolicyEnums;
+import android.telecom.TelecomManager;
import android.telephony.SubscriptionManager;
import android.telephony.TelephonyManager;
import android.telephony.data.ApnSetting;
@@ -3322,7 +3326,7 @@
onLockSettingsReady();
loadAdminDataAsync();
mOwners.systemReady();
- if (isWorkProfileTelephonyFlagEnabled()) {
+ if (isWorkProfileTelephonyEnabled()) {
applyManagedSubscriptionsPolicyIfRequired();
}
break;
@@ -3532,26 +3536,21 @@
userId == UserHandle.USER_SYSTEM ? UserHandle.USER_ALL : userId);
updatePermissionPolicyCache(userId);
updateAdminCanGrantSensorsPermissionCache(userId);
- final List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs;
- boolean isManagedSubscription;
+ final List<PreferentialNetworkServiceConfig> preferentialNetworkServiceConfigs;
synchronized (getLockObject()) {
ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userId);
preferentialNetworkServiceConfigs = owner != null
? owner.mPreferentialNetworkServiceConfigs
: List.of(PreferentialNetworkServiceConfig.DEFAULT);
-
- isManagedSubscription = owner != null && owner.mManagedSubscriptionsPolicy != null
- && owner.mManagedSubscriptionsPolicy.getPolicyType()
- == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS;
}
updateNetworkPreferenceForUser(userId, preferentialNetworkServiceConfigs);
- if (isManagedSubscription) {
- String defaultDialerPackageName = getDefaultRoleHolderPackageName(
- com.android.internal.R.string.config_defaultDialer);
- String defaultSmsPackageName = getDefaultRoleHolderPackageName(
- com.android.internal.R.string.config_defaultSms);
+ if (isProfileOwnerOfOrganizationOwnedDevice(userId)
+ && getManagedSubscriptionsPolicy().getPolicyType()
+ == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS) {
+ String defaultDialerPackageName = getOemDefaultDialerPackage();
+ String defaultSmsPackageName = getOemDefaultSmsPackage();
updateDialerAndSmsManagedShortcutsOverrideCache(defaultDialerPackageName,
defaultSmsPackageName);
}
@@ -3578,6 +3577,8 @@
mInjector.binderWithCleanCallingIdentity(() ->
mInjector.getPackageManagerInternal().setOwnerProtectedPackages(
targetUserId, protectedPackages));
+ mUsageStatsManagerInternal.setAdminProtectedPackages(new ArraySet(protectedPackages),
+ targetUserId);
}
void handleUnlockUser(int userId) {
@@ -3964,7 +3965,7 @@
}
Objects.requireNonNull(adminReceiver, "ComponentName is null");
Preconditions.checkCallAuthorization(isAdb(getCallerIdentity())
- || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS),
+ || hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS),
"Caller must be shell or hold MANAGE_PROFILE_AND_DEVICE_OWNERS to call "
+ "forceRemoveActiveAdmin");
mInjector.binderWithCleanCallingIdentity(() -> {
@@ -7636,7 +7637,7 @@
}
mLockSettingsInternal.refreshStrongAuthTimeout(parentId);
- if (isWorkProfileTelephonyFlagEnabled()) {
+ if (isWorkProfileTelephonyEnabled()) {
clearManagedSubscriptionsPolicy();
clearLauncherShortcutOverrides();
updateTelephonyCrossProfileIntentFilters(parentId, UserHandle.USER_NULL, false);
@@ -9478,7 +9479,7 @@
Preconditions.checkCallAuthorization(
isDefaultDeviceOwner(caller) || canManageUsers(caller) || isFinancedDeviceOwner(
caller) || hasCallingOrSelfPermission(
- permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ MANAGE_PROFILE_AND_DEVICE_OWNERS));
return mOwners.hasDeviceOwner();
}
@@ -9647,7 +9648,7 @@
}
if (!callingUserOnly) {
Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())
- || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ || hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
}
synchronized (getLockObject()) {
if (!mOwners.hasDeviceOwner()) {
@@ -9697,7 +9698,7 @@
return null;
}
Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())
- || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ || hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
synchronized (getLockObject()) {
if (!mOwners.hasDeviceOwner()) {
@@ -10101,7 +10102,7 @@
}
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(canManageUsers(caller)
- || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ || hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
if (userHandle != caller.getUserId()) {
Preconditions.checkCallAuthorization(canManageUsers(caller)
@@ -10119,7 +10120,7 @@
return;
}
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
final CallerIdentity caller = getCallerIdentity();
final long id = mInjector.binderClearCallingIdentity();
@@ -10432,7 +10433,7 @@
return null;
}
Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())
- || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ || hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
return getProfileOwnerNameUnchecked(userHandle);
}
@@ -10639,7 +10640,7 @@
return;
}
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
if ((mIsWatch || hasUserSetupCompleted(userHandle))) {
Preconditions.checkState(isSystemUid(caller),
@@ -10663,7 +10664,7 @@
boolean hasIncompatibleAccountsOrNonAdb) {
if (!isAdb(caller)) {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
}
final int code = checkDeviceOwnerProvisioningPreConditionLocked(owner,
@@ -10987,8 +10988,10 @@
synchronized (mSubscriptionsChangedListenerLock) {
pw.println("Subscription changed listener : " + mSubscriptionsChangedListener);
}
- pw.println(
- "Flag enable_work_profile_telephony : " + isWorkProfileTelephonyFlagEnabled());
+ pw.println("DPM Flag enable_work_profile_telephony : "
+ + isWorkProfileTelephonyDevicePolicyManagerFlagEnabled());
+ pw.println("Telephony Flag enable_work_profile_telephony : "
+ + isWorkProfileTelephonySubscriptionManagerFlagEnabled());
mHandler.post(() -> handleDump(pw));
dumpResources(pw);
@@ -11776,8 +11779,9 @@
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(canManageUsers(caller) || canQueryAdminPolicy(caller));
+ List<String> result = null;
+
synchronized (getLockObject()) {
- List<String> result = null;
// If we have multiple profiles we return the intersection of the
// permitted lists. This can happen in cases where we have a device
// and profile owner.
@@ -11799,35 +11803,37 @@
}
}
}
+ }
- // If we have a permitted list add all system accessibility services.
- if (result != null) {
- long id = mInjector.binderClearCallingIdentity();
- try {
- UserInfo user = getUserInfo(userId);
- if (user.isManagedProfile()) {
- userId = user.profileGroupId;
- }
- final List<AccessibilityServiceInfo> installedServices =
- withAccessibilityManager(userId,
- AccessibilityManager::getInstalledAccessibilityServiceList);
+ // If we have a permitted list add all system accessibility services.
+ if (result != null) {
+ long id = mInjector.binderClearCallingIdentity();
+ try {
+ UserInfo user = getUserInfo(userId);
+ if (user.isManagedProfile()) {
+ userId = user.profileGroupId;
+ }
+ // Move AccessibilityManager out of {@link getLockObject} to prevent potential
+ // deadlock.
+ final List<AccessibilityServiceInfo> installedServices =
+ withAccessibilityManager(userId,
+ AccessibilityManager::getInstalledAccessibilityServiceList);
- if (installedServices != null) {
- for (AccessibilityServiceInfo service : installedServices) {
- ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo;
- ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
- if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
- result.add(serviceInfo.packageName);
- }
+ if (installedServices != null) {
+ for (AccessibilityServiceInfo service : installedServices) {
+ ServiceInfo serviceInfo = service.getResolveInfo().serviceInfo;
+ ApplicationInfo applicationInfo = serviceInfo.applicationInfo;
+ if ((applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ result.add(serviceInfo.packageName);
}
}
- } finally {
- mInjector.binderRestoreCallingIdentity(id);
}
+ } finally {
+ mInjector.binderRestoreCallingIdentity(id);
}
-
- return result;
}
+
+ return result;
}
@Override
@@ -15440,7 +15446,8 @@
Slogf.i(LOG_TAG, "Sending %s broadcast to manifest receivers.", intent.getAction());
broadcastIntentToCrossProfileManifestReceivers(
intent, parentHandle, requiresPermission);
- broadcastIntentToDevicePolicyManagerRoleHolder(intent, parentHandle);
+ broadcastExplicitIntentToRoleHolder(
+ intent, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT, parentHandle);
}
@Override
@@ -15481,36 +15488,6 @@
}
}
- private void broadcastIntentToDevicePolicyManagerRoleHolder(
- Intent intent, UserHandle userHandle) {
- final int userId = userHandle.getIdentifier();
- final String packageName = getDevicePolicyManagementRoleHolderPackageName(mContext);
- if (packageName == null) {
- return;
- }
- try {
- final Intent packageIntent = new Intent(intent)
- .setPackage(packageName);
- final List<ResolveInfo> receivers = mIPackageManager.queryIntentReceivers(
- packageIntent,
- /* resolvedType= */ null,
- STOCK_PM_FLAGS,
- userId).getList();
- if (receivers.isEmpty()) {
- return;
- }
- for (ResolveInfo receiver : receivers) {
- final Intent componentIntent = new Intent(packageIntent)
- .setComponent(receiver.getComponentInfo().getComponentName())
- .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
- mContext.sendBroadcastAsUser(componentIntent, userHandle);
- }
- } catch (RemoteException ex) {
- Slogf.w(LOG_TAG, "Cannot get list of broadcast receivers for %s because: %s.",
- intent.getAction(), ex);
- }
- }
-
/**
* Checks whether the package {@code packageName} has the {@code MODIFY_QUIET_MODE}
* permission granted for the user {@code userId}.
@@ -15949,7 +15926,7 @@
private boolean canWriteCredentialManagerPolicy(CallerIdentity caller) {
return (isProfileOwner(caller) && isManagedProfile(caller.getUserId()))
|| isDefaultDeviceOwner(caller)
- || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS);
+ || hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS);
}
@Override
@@ -16452,7 +16429,7 @@
Objects.requireNonNull(packageName, "packageName is null");
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
long originalId = mInjector.binderClearCallingIdentity();
try {
@@ -17182,7 +17159,7 @@
// Only adb or system apps with the right permission can mark a profile owner on
// organization-owned device.
if (!(isAdb(caller) || hasCallingPermission(permission.MARK_DEVICE_ORGANIZATION_OWNED)
- || hasCallingPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS))) {
+ || hasCallingPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS))) {
throw new SecurityException(
"Only the system can mark a profile owner of organization-owned device.");
}
@@ -17783,7 +17760,7 @@
@Override
public void forceUpdateUserSetupComplete(@UserIdInt int userId) {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
boolean isUserCompleted = mInjector.settingsSecureGetIntForUser(
Settings.Secure.USER_SETUP_COMPLETE, 0, userId) != 0;
@@ -18721,7 +18698,7 @@
public List<String> getDisallowedSystemApps(ComponentName admin, int userId,
String provisioningAction) throws RemoteException {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
return new ArrayList<>(
mOverlayPackagesProvider.getNonRequiredApps(admin, userId, provisioningAction));
@@ -19538,7 +19515,7 @@
return false;
}
Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())
- || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ || hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
long id = mInjector.binderClearCallingIdentity();
try {
@@ -19565,7 +19542,7 @@
return false;
}
Preconditions.checkCallAuthorization(canManageUsers(getCallerIdentity())
- || hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ || hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
return mInjector.binderWithCleanCallingIdentity(() -> isUnattendedManagedKioskUnchecked());
}
@@ -20546,7 +20523,7 @@
@Override
public void clearOrganizationIdForUser(int userHandle) {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
synchronized (getLockObject()) {
final ActiveAdmin owner = getDeviceOrProfileOwnerAdminLocked(userHandle);
@@ -20568,7 +20545,7 @@
final CallerIdentity caller = getCallerIdentity(callerPackage);
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
provisioningParams.logParams(callerPackage);
@@ -20666,7 +20643,7 @@
public void finalizeWorkProfileProvisioning(UserHandle managedProfileUser,
Account migratedAccount) {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
if (!isManagedProfile(managedProfileUser.getIdentifier())) {
throw new IllegalStateException("Given user is not a managed profile");
@@ -20716,7 +20693,7 @@
private void maybeInstallDevicePolicyManagementRoleHolderInUser(int targetUserId) {
String devicePolicyManagerRoleHolderPackageName =
- getDevicePolicyManagementRoleHolderPackageName(mContext);
+ getRoleHolderPackageName(mContext, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT);
if (devicePolicyManagerRoleHolderPackageName == null) {
Slogf.d(LOG_TAG, "No device policy management role holder specified.");
return;
@@ -20742,14 +20719,24 @@
}
}
+ /**
+ * If multiple packages hold the role, returns the first package in the list.
+ */
+ @Nullable
+ private String getRoleHolderPackageName(Context context, String role) {
+ return getRoleHolderPackageNameOnUser(context, role, Process.myUserHandle());
+ }
- private String getDevicePolicyManagementRoleHolderPackageName(Context context) {
+ /**
+ * If multiple packages hold the role, returns the first package in the list.
+ */
+ @Nullable
+ private String getRoleHolderPackageNameOnUser(Context context, String role, UserHandle user) {
RoleManager roleManager = context.getSystemService(RoleManager.class);
// Calling identity needs to be cleared as this method is used in the permissions checks.
return mInjector.binderWithCleanCallingIdentity(() -> {
- List<String> roleHolders =
- roleManager.getRoleHolders(RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT);
+ List<String> roleHolders = roleManager.getRoleHoldersAsUser(role, user);
if (roleHolders.isEmpty()) {
return null;
}
@@ -20758,15 +20745,65 @@
}
private boolean isCallerDevicePolicyManagementRoleHolder(CallerIdentity caller) {
+ return doesCallerHoldRole(caller, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT);
+ }
+
+ private boolean isCallerSystemSupervisionRoleHolder(CallerIdentity caller) {
+ return doesCallerHoldRole(caller, RoleManager.ROLE_SYSTEM_SUPERVISION);
+ }
+
+ /**
+ * Check if the caller is holding the given role on the calling user.
+ *
+ * @param caller the caller you wish to check
+ * @param role the name of the role to check for.
+ * @return {@code true} if the caller holds the role, {@code false} otherwise.
+ */
+ private boolean doesCallerHoldRole(CallerIdentity caller, String role) {
int callerUid = caller.getUid();
- String devicePolicyManagementRoleHolderPackageName =
- getDevicePolicyManagementRoleHolderPackageName(mContext);
+ String roleHolderPackageName =
+ getRoleHolderPackageNameOnUser(role, caller.getUserId());
int roleHolderUid = mInjector.getPackageManagerInternal().getPackageUid(
- devicePolicyManagementRoleHolderPackageName, 0, caller.getUserId());
+ roleHolderPackageName, 0, caller.getUserId());
return callerUid == roleHolderUid;
}
+ /**
+ * Return the package name of the role holder on the given user.
+ *
+ * <p>If the userId passed in is {@link UserHandle.USER_ALL} then every user will be checked and
+ * the package name of the role holder on the first user where there is a role holder is
+ * returned.
+ *
+ * @param role the name of the role to check for.
+ * @param userId the userId to check for the role holder on.
+ * @return the package name of the role holder
+ */
+ @Nullable
+ private String getRoleHolderPackageNameOnUser(String role, int userId) {
+ RoleManager roleManager = mContext.getSystemService(RoleManager.class);
+
+ // Clear calling identity as the RoleManager APIs require privileged permissions.
+ return mInjector.binderWithCleanCallingIdentity(() -> {
+ List<UserInfo> users;
+ // Interpret USER_ALL as meaning "any" user.
+ if (userId == UserHandle.USER_ALL) {
+ users = mInjector.getUserManagerInternal().getUsers(/*excludeDying=*/ true);
+ } else {
+ users = List.of(new UserInfo(userId, /*name=*/ null, /*flags=*/ 0));
+ }
+ for (UserInfo user : users) {
+ List<String> roleHolders =
+ roleManager.getRoleHoldersAsUser(role, user.getUserHandle());
+ if (!roleHolders.isEmpty()) {
+ return roleHolders.get(0);
+ }
+ }
+ return null;
+ });
+ }
+
private void resetInteractAcrossProfilesAppOps(@UserIdInt int userId) {
mInjector.getCrossProfileApps(userId).clearInteractAcrossProfilesAppOps();
pregrantDefaultInteractAcrossProfilesAppOps(userId);
@@ -20993,7 +21030,7 @@
final CallerIdentity caller = getCallerIdentity();
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS)
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS)
|| (hasCallingOrSelfPermission(permission.PROVISION_DEMO_DEVICE)
&& provisioningParams.isDemoDevice()));
@@ -21181,7 +21218,7 @@
@Override
public void resetDefaultCrossProfileIntentFilters(@UserIdInt int userId) {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
mInjector.binderWithCleanCallingIdentity(() -> {
try {
@@ -21320,7 +21357,7 @@
public void setDeviceOwnerType(@NonNull ComponentName admin,
@DeviceOwnerType int deviceOwnerType) {
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
- permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ MANAGE_PROFILE_AND_DEVICE_OWNERS));
synchronized (getLockObject()) {
setDeviceOwnerTypeLocked(admin, deviceOwnerType);
@@ -21708,7 +21745,7 @@
public boolean isDpcDownloaded() {
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ MANAGE_PROFILE_AND_DEVICE_OWNERS));
ContentResolver cr = mContext.getContentResolver();
@@ -21720,7 +21757,7 @@
public void setDpcDownloaded(boolean downloaded) {
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ MANAGE_PROFILE_AND_DEVICE_OWNERS));
int setTo = downloaded ? 1 : 0;
@@ -21828,15 +21865,23 @@
}
public void register() {
- mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.SYSTEM);
+ mRm.addOnRoleHoldersChangedListenerAsUser(mExecutor, this, UserHandle.ALL);
}
@Override
public void onRoleHoldersChanged(@NonNull String roleName, @NonNull UserHandle user) {
- if (!RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) {
+ if (RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT.equals(roleName)) {
+ handleDevicePolicyManagementRoleChange(user);
return;
}
- String newRoleHolder = getRoleHolder();
+ if (RoleManager.ROLE_FINANCED_DEVICE_KIOSK.equals(roleName)) {
+ handleFinancedDeviceKioskRoleChange();
+ return;
+ }
+ }
+
+ private void handleDevicePolicyManagementRoleChange(UserHandle user) {
+ String newRoleHolder = getDeviceManagementRoleHolder(user);
if (isDefaultRoleHolder(newRoleHolder)) {
Slogf.i(LOG_TAG,
"onRoleHoldersChanged: Default role holder is set, returning early");
@@ -21871,9 +21916,44 @@
}
}
- private String getRoleHolder() {
- return DevicePolicyManagerService.this.getDevicePolicyManagementRoleHolderPackageName(
- mContext);
+ private void handleFinancedDeviceKioskRoleChange() {
+ if (!isDevicePolicyEngineEnabled()) {
+ return;
+ }
+ Slog.i(LOG_TAG, "Handling action " + ACTION_DEVICE_FINANCING_STATE_CHANGED);
+ Intent intent = new Intent(ACTION_DEVICE_FINANCING_STATE_CHANGED);
+ mInjector.binderWithCleanCallingIdentity(() -> {
+ for (UserInfo userInfo : mUserManager.getUsers()) {
+ UserHandle user = userInfo.getUserHandle();
+ broadcastExplicitIntentToRoleHolder(
+ intent, RoleManager.ROLE_SYSTEM_SUPERVISION, user);
+ broadcastExplicitIntentToRoleHolder(
+ intent, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT, user);
+ ActiveAdmin admin = getDeviceOrProfileOwnerAdminLocked(user.getIdentifier());
+ if (admin == null) {
+ continue;
+ }
+ if (!isProfileOwnerOfOrganizationOwnedDevice(
+ admin.info.getComponent(), user.getIdentifier())
+ && !isDeviceOwner(admin)
+ && !(isProfileOwner(admin.info.getComponent(), user.getIdentifier())
+ && admin.getUserHandle().isSystem())) {
+ continue;
+ }
+ // Don't send the broadcast twice if the DPC is the same package as the
+ // DMRH
+ if (admin.info.getPackageName().equals(getDeviceManagementRoleHolder(user))) {
+ continue;
+ }
+ broadcastExplicitIntentToPackage(
+ intent, admin.info.getPackageName(), admin.getUserHandle());
+ }
+ });
+ }
+
+ private String getDeviceManagementRoleHolder(UserHandle user) {
+ return DevicePolicyManagerService.this.getRoleHolderPackageNameOnUser(
+ mContext, RoleManager.ROLE_DEVICE_POLICY_MANAGEMENT, user);
}
private boolean isDefaultRoleHolder(String packageName) {
@@ -21933,10 +22013,44 @@
}
}
+ private void broadcastExplicitIntentToRoleHolder(
+ Intent intent, String role, UserHandle userHandle) {
+ String packageName = getRoleHolderPackageNameOnUser(mContext, role, userHandle);
+ if (packageName == null) {
+ return;
+ }
+ broadcastExplicitIntentToPackage(intent, packageName, userHandle);
+ }
+
+ private void broadcastExplicitIntentToPackage(
+ Intent intent, String packageName, UserHandle userHandle) {
+ int userId = userHandle.getIdentifier();
+ if (packageName == null) {
+ return;
+ }
+ Intent packageIntent = new Intent(intent)
+ .setPackage(packageName);
+ List<ResolveInfo> receivers = mContext.getPackageManager().queryBroadcastReceiversAsUser(
+ packageIntent,
+ PackageManager.ResolveInfoFlags.of(PackageManager.GET_RECEIVERS),
+ userId);
+ if (receivers.isEmpty()) {
+ Slog.i(LOG_TAG, "Found no receivers to handle intent " + intent
+ + " in package " + packageName);
+ return;
+ }
+ for (ResolveInfo receiver : receivers) {
+ Intent componentIntent = new Intent(packageIntent)
+ .setComponent(receiver.getComponentInfo().getComponentName())
+ .addFlags(Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
+ mContext.sendBroadcastAsUser(componentIntent, userHandle);
+ }
+ }
+
@Override
public List<UserHandle> getPolicyManagedProfiles(@NonNull UserHandle user) {
Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(
- android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ MANAGE_PROFILE_AND_DEVICE_OWNERS));
int userId = user.getIdentifier();
return mInjector.binderWithCleanCallingIdentity(() -> {
List<UserInfo> userProfiles = mUserManager.getProfiles(userId);
@@ -22588,17 +22702,30 @@
DEFAULT_KEEP_PROFILES_RUNNING_FLAG);
}
- private static boolean isWorkProfileTelephonyFlagEnabled() {
- return DeviceConfig.getBoolean(
- NAMESPACE_DEVICE_POLICY_MANAGER,
- ENABLE_WORK_PROFILE_TELEPHONY_FLAG,
- DEFAULT_WORK_PROFILE_TELEPHONY_FLAG);
+ private boolean isWorkProfileTelephonyEnabled() {
+ return isWorkProfileTelephonyDevicePolicyManagerFlagEnabled()
+ && isWorkProfileTelephonySubscriptionManagerFlagEnabled();
+ }
+
+ private boolean isWorkProfileTelephonyDevicePolicyManagerFlagEnabled() {
+ return DeviceConfig.getBoolean(NAMESPACE_DEVICE_POLICY_MANAGER,
+ ENABLE_WORK_PROFILE_TELEPHONY_FLAG, DEFAULT_WORK_PROFILE_TELEPHONY_FLAG);
+ }
+
+ private boolean isWorkProfileTelephonySubscriptionManagerFlagEnabled() {
+ final long ident = mInjector.binderClearCallingIdentity();
+ try {
+ return DeviceConfig.getBoolean(NAMESPACE_TELEPHONY, ENABLE_WORK_PROFILE_TELEPHONY_FLAG,
+ false);
+ } finally {
+ mInjector.binderRestoreCallingIdentity(ident);
+ }
}
@Override
public void setOverrideKeepProfilesRunning(boolean enabled) {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
mKeepProfilesRunning = enabled;
Slog.i(LOG_TAG, "Keep profiles running overridden to: " + enabled);
}
@@ -22705,7 +22832,7 @@
@Override
public ManagedSubscriptionsPolicy getManagedSubscriptionsPolicy() {
- if (isWorkProfileTelephonyFlagEnabled()) {
+ if (isWorkProfileTelephonyEnabled()) {
synchronized (getLockObject()) {
ActiveAdmin admin = getProfileOwnerOfOrganizationOwnedDeviceLocked();
if (admin != null && admin.mManagedSubscriptionsPolicy != null) {
@@ -22719,7 +22846,7 @@
@Override
public void setManagedSubscriptionsPolicy(ManagedSubscriptionsPolicy policy) {
- if (!isWorkProfileTelephonyFlagEnabled()) {
+ if (!isWorkProfileTelephonyEnabled()) {
throw new UnsupportedOperationException("This api is not enabled");
}
CallerIdentity caller = getCallerIdentity();
@@ -22727,9 +22854,10 @@
"This policy can only be set by a profile owner on an organization-owned "
+ "device.");
+ int parentUserId = getProfileParentId(caller.getUserId());
synchronized (getLockObject()) {
final ActiveAdmin admin = getProfileOwnerLocked(caller.getUserId());
- if (hasUserSetupCompleted(UserHandle.USER_SYSTEM) && !isAdminTestOnlyLocked(
+ if (hasUserSetupCompleted(parentUserId) && !isAdminTestOnlyLocked(
admin.info.getComponent(), caller.getUserId())) {
throw new IllegalStateException("Not allowed to apply this policy after setup");
}
@@ -22751,7 +22879,6 @@
if (policyType == ManagedSubscriptionsPolicy.TYPE_ALL_MANAGED_SUBSCRIPTIONS) {
final long id = mInjector.binderClearCallingIdentity();
try {
- int parentUserId = getProfileParentId(caller.getUserId());
installOemDefaultDialerAndSmsApp(caller.getUserId());
updateTelephonyCrossProfileIntentFilters(parentUserId, caller.getUserId(), true);
} finally {
@@ -22762,10 +22889,8 @@
private void installOemDefaultDialerAndSmsApp(int targetUserId) {
try {
- String defaultDialerPackageName = getDefaultRoleHolderPackageName(
- com.android.internal.R.string.config_defaultDialer);
- String defaultSmsPackageName = getDefaultRoleHolderPackageName(
- com.android.internal.R.string.config_defaultSms);
+ String defaultDialerPackageName = getOemDefaultDialerPackage();
+ String defaultSmsPackageName = getOemDefaultSmsPackage();
if (defaultDialerPackageName != null) {
mIPackageManager.installExistingPackageAsUser(defaultDialerPackageName,
@@ -22791,6 +22916,15 @@
}
}
+ private String getOemDefaultDialerPackage() {
+ TelecomManager telecomManager = mContext.getSystemService(TelecomManager.class);
+ return telecomManager.getSystemDialerPackage();
+ }
+
+ private String getOemDefaultSmsPackage() {
+ return mContext.getString(R.string.config_defaultSms);
+ }
+
private void updateDialerAndSmsManagedShortcutsOverrideCache(
String defaultDialerPackageName, String defaultSmsPackageName) {
@@ -22865,14 +22999,14 @@
@Override
public DevicePolicyState getDevicePolicyState() {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
return mInjector.binderWithCleanCallingIdentity(mDevicePolicyEngine::getDevicePolicyState);
}
@Override
public boolean triggerDevicePolicyEngineMigration(boolean forceMigration) {
Preconditions.checkCallAuthorization(
- hasCallingOrSelfPermission(permission.MANAGE_PROFILE_AND_DEVICE_OWNERS));
+ hasCallingOrSelfPermission(MANAGE_PROFILE_AND_DEVICE_OWNERS));
return mInjector.binderWithCleanCallingIdentity(() -> {
boolean canForceMigration = forceMigration && !hasNonTestOnlyActiveAdmins();
if (!canForceMigration && !shouldMigrateToDevicePolicyEngine()) {
@@ -23231,4 +23365,28 @@
// if the policy engine was ever used?
return !mDevicePolicyEngine.hasActivePolicies();
}
+
+ @Override
+ public boolean isDeviceFinanced(String callerPackageName) {
+ CallerIdentity caller = getCallerIdentity(callerPackageName);
+ Preconditions.checkCallAuthorization(isDeviceOwner(caller)
+ || isProfileOwnerOfOrganizationOwnedDevice(caller)
+ || isProfileOwnerOnUser0(caller)
+ || isCallerDevicePolicyManagementRoleHolder(caller)
+ || isCallerSystemSupervisionRoleHolder(caller));
+ return getFinancedDeviceKioskRoleHolderOnAnyUser() != null;
+ };
+
+ @Override
+ public String getFinancedDeviceKioskRoleHolder(String callerPackageName) {
+ CallerIdentity caller = getCallerIdentity(callerPackageName);
+ enforcePermission(MANAGE_PROFILE_AND_DEVICE_OWNERS, caller.getPackageName(),
+ caller.getUserId());
+ return getFinancedDeviceKioskRoleHolderOnAnyUser();
+ }
+
+ private String getFinancedDeviceKioskRoleHolderOnAnyUser() {
+ return getRoleHolderPackageNameOnUser(
+ RoleManager.ROLE_FINANCED_DEVICE_KIOSK, UserHandle.USER_ALL);
+ }
}
diff --git a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
index 6673dc6..8682a65 100644
--- a/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/AppIdPermissionPolicy.kt
@@ -769,6 +769,7 @@
setPermissionFlags(appId, userId, permissionName, newFlags)
} else if (permission.isRuntime) {
var newFlags = oldFlags and PermissionFlags.MASK_RUNTIME
+ val wasRevoked = newFlags != 0 && !PermissionFlags.isPermissionGranted(newFlags)
if (getAppIdTargetSdkVersion(appId, permissionName) < Build.VERSION_CODES.M) {
if (permission.isRuntimeOnly) {
// Different from the old implementation, which simply skips a runtime-only
@@ -778,6 +779,9 @@
newFlags = newFlags and PermissionFlags.MASK_EXEMPT
} else {
newFlags = newFlags or PermissionFlags.LEGACY_GRANTED
+ if (wasRevoked) {
+ newFlags = newFlags or PermissionFlags.APP_OP_REVOKED
+ }
// Explicitly check against the old state to determine if this permission is
// new.
val isNewPermission =
@@ -808,16 +812,23 @@
(isImplicitPermission && isAnySourcePermissionNonRuntime)
if (shouldGrantByImplicit) {
newFlags = newFlags or PermissionFlags.IMPLICIT_GRANTED
+ if (wasRevoked) {
+ newFlags = newFlags or PermissionFlags.APP_OP_REVOKED
+ }
} else {
newFlags = newFlags andInv PermissionFlags.IMPLICIT_GRANTED
- }
- if ((wasGrantedByLegacy || wasGrantedByImplicit) && !shouldGrantByImplicit) {
- // The permission was granted from a compatibility grant or an implicit grant,
- // however this flag might still be set if the user denied this permission in
- // the settings. Hence upon app upgrade and when this permission is no longer
- // LEGACY_GRANTED or IMPLICIT_GRANTED and we revoke the permission, we want to
- // remove this flag so that the app can request the permission again.
- newFlags = newFlags andInv PermissionFlags.APP_OP_REVOKED
+ if ((wasGrantedByLegacy || wasGrantedByImplicit) &&
+ newFlags.hasBits(PermissionFlags.APP_OP_REVOKED)) {
+ // The permission was granted from a compatibility grant or an implicit
+ // grant, however this flag might still be set if the user denied this
+ // permission in the settings. Hence upon app upgrade and when this
+ // permission is no longer LEGACY_GRANTED or IMPLICIT_GRANTED and we revoke
+ // the permission, we want to remove this flag so that the app can request
+ // the permission again.
+ newFlags = newFlags andInv (
+ PermissionFlags.RUNTIME_GRANTED or PermissionFlags.APP_OP_REVOKED
+ )
+ }
}
val hasImplicitFlag = newFlags.hasBits(PermissionFlags.IMPLICIT)
if (!isImplicitPermission && hasImplicitFlag) {
diff --git a/services/permission/java/com/android/server/permission/access/permission/Permission.kt b/services/permission/java/com/android/server/permission/access/permission/Permission.kt
index 714480c..39b4eaf 100644
--- a/services/permission/java/com/android/server/permission/access/permission/Permission.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/Permission.kt
@@ -140,9 +140,7 @@
get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_SOFT_RESTRICTED)
inline val isHardOrSoftRestricted: Boolean
- get() = permissionInfo.flags.hasBits(
- PermissionInfo.FLAG_HARD_RESTRICTED or PermissionInfo.FLAG_SOFT_RESTRICTED
- )
+ get() = isHardRestricted || isSoftRestricted
inline val isImmutablyRestricted: Boolean
get() = permissionInfo.flags.hasBits(PermissionInfo.FLAG_IMMUTABLY_RESTRICTED)
diff --git a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
index 9b69362..84ced1f 100644
--- a/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
+++ b/services/permission/java/com/android/server/permission/access/permission/PermissionService.kt
@@ -142,6 +142,12 @@
userManagerInternal = LocalServices.getService(UserManagerInternal::class.java)
userManagerService = UserManagerService.getInstance()
+ // The package info cache is the cache for package and permission information.
+ // Disable the package info and package permission caches locally but leave the
+ // checkPermission cache active.
+ PackageManager.invalidatePackageInfoCache();
+ PermissionManager.disablePackageNamePermissionCache();
+
handlerThread = ServiceThread(LOG_TAG, Process.THREAD_PRIORITY_BACKGROUND, true)
.apply { start() }
handler = Handler(handlerThread.looper)
@@ -1570,27 +1576,33 @@
return@forEachIndexed
}
- val wasAllowlisted = oldFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT)
- val isAllowlisted = newFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT)
+ val isExempt = newFlags.hasAnyBit(PermissionFlags.MASK_EXEMPT)
// If the permission is policy fixed as granted but it is no longer
// on any of the allowlists we need to clear the policy fixed flag
// as allowlisting trumps policy i.e. policy cannot grant a non
// grantable permission.
if (oldFlags.hasBits(PermissionFlags.POLICY_FIXED)) {
- if (!isAllowlisted && wasGranted) {
+ if (!isExempt && wasGranted) {
mask = mask or PermissionFlags.POLICY_FIXED
newFlags = newFlags andInv PermissionFlags.POLICY_FIXED
}
}
- // If we are allowlisting an app that does not support runtime permissions
- // we need to make sure it goes through the permission review UI at launch.
- if (androidPackage.targetSdkVersion < Build.VERSION_CODES.M &&
- !wasAllowlisted && isAllowlisted) {
- mask = mask or PermissionFlags.IMPLICIT
- newFlags = newFlags or PermissionFlags.IMPLICIT
+ val isHardRestricted = permission.isHardRestricted && !isExempt
+ newFlags = if (isHardRestricted) {
+ newFlags or PermissionFlags.RESTRICTION_REVOKED
+ } else {
+ newFlags andInv PermissionFlags.RESTRICTION_REVOKED
}
+ val isSoftRestricted = permission.isSoftRestricted && !isExempt
+ newFlags = if (isSoftRestricted) {
+ newFlags or PermissionFlags.SOFT_RESTRICTED
+ } else {
+ newFlags andInv PermissionFlags.SOFT_RESTRICTED
+ }
+ mask = mask or PermissionFlags.RESTRICTION_REVOKED or
+ PermissionFlags.SOFT_RESTRICTED
updatePermissionFlags(
appId, userId, requestedPermission, mask, newFlags
diff --git a/services/robotests/backup/Android.bp b/services/robotests/backup/Android.bp
index fbc0282..e04dd68 100644
--- a/services/robotests/backup/Android.bp
+++ b/services/robotests/backup/Android.bp
@@ -36,7 +36,7 @@
"services.backup",
"services.core",
"services.net",
- "service-permission.impl",
+ "service-permission.stubs.system_server",
],
libs: ["android.net.ipsec.ike.stubs.system"],
diff --git a/services/robotests/backup/src/com/android/server/backup/FullBackupJobTest.java b/services/robotests/backup/src/com/android/server/backup/FullBackupJobTest.java
index c8797e2..da0adb5 100644
--- a/services/robotests/backup/src/com/android/server/backup/FullBackupJobTest.java
+++ b/services/robotests/backup/src/com/android/server/backup/FullBackupJobTest.java
@@ -19,10 +19,13 @@
import static com.google.common.truth.Truth.assertThat;
import static org.mockito.Mockito.when;
+import static org.robolectric.Shadows.shadowOf;
import android.annotation.UserIdInt;
+import android.app.job.JobInfo;
import android.app.job.JobScheduler;
import android.content.Context;
+import android.content.pm.PackageManager;
import android.os.Handler;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
@@ -87,6 +90,25 @@
}
@Test
+ public void testSchedule_notWatch_requiresDeviceIdle() {
+ shadowOf(mContext.getPackageManager())
+ .setSystemFeature(PackageManager.FEATURE_WATCH, false);
+ FullBackupJob.schedule(mUserOneId, mContext, 0, mUserBackupManagerService);
+
+ JobInfo pendingJob = mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserOneId));
+ assertThat(pendingJob.isRequireDeviceIdle()).isTrue();
+ }
+
+ @Test
+ public void testSchedule_isWatch_doesNotRequireDeviceIdle() {
+ shadowOf(mContext.getPackageManager()).setSystemFeature(PackageManager.FEATURE_WATCH, true);
+ FullBackupJob.schedule(mUserOneId, mContext, 0, mUserBackupManagerService);
+
+ JobInfo pendingJob = mShadowJobScheduler.getPendingJob(getJobIdForUserId(mUserOneId));
+ assertThat(pendingJob.isRequireDeviceIdle()).isFalse();
+ }
+
+ @Test
public void testCancel_afterCancelling_jobDoesntExist() {
FullBackupJob.schedule(mUserOneId, mContext, 0, mUserBackupManagerService);
FullBackupJob.schedule(mUserTwoId, mContext, 0, mUserBackupManagerService);
diff --git a/services/tests/InputMethodSystemServerTests/Android.bp b/services/tests/InputMethodSystemServerTests/Android.bp
index 07ddda3..36446f6 100644
--- a/services/tests/InputMethodSystemServerTests/Android.bp
+++ b/services/tests/InputMethodSystemServerTests/Android.bp
@@ -41,6 +41,7 @@
"mockito-target-extended-minus-junit4",
"platform-test-annotations",
"services.core",
+ "service-permission.stubs.system_server",
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
"truth-prebuilt",
@@ -88,6 +89,7 @@
"mockito-target-extended-minus-junit4",
"platform-test-annotations",
"services.core",
+ "service-permission.stubs.system_server",
"servicestests-core-utils",
"servicestests-utils-mockito-extended",
"truth-prebuilt",
diff --git a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
index 7e44049..7d4f87d 100644
--- a/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
+++ b/services/tests/InputMethodSystemServerTests/src/com/android/server/inputmethod/DefaultImeVisibilityApplierTest.java
@@ -17,6 +17,7 @@
package com.android.server.inputmethod;
import static android.inputmethodservice.InputMethodService.IME_ACTIVE;
+import static android.view.WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE;
import static com.android.internal.inputmethod.SoftInputShowHideReason.HIDE_SOFT_INPUT;
import static com.android.internal.inputmethod.SoftInputShowHideReason.SHOW_SOFT_INPUT;
@@ -35,11 +36,16 @@
import static org.mockito.Mockito.verify;
import android.os.Binder;
+import android.os.IBinder;
import android.os.RemoteException;
import android.view.inputmethod.InputMethodManager;
import androidx.test.ext.junit.runners.AndroidJUnit4;
+import com.android.internal.inputmethod.InputBindResult;
+import com.android.internal.inputmethod.StartInputFlags;
+import com.android.internal.inputmethod.StartInputReason;
+
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
@@ -60,8 +66,8 @@
super.setUp();
mVisibilityApplier =
(DefaultImeVisibilityApplier) mInputMethodManagerService.getVisibilityApplier();
- mInputMethodManagerService.mCurFocusedWindowClient = mock(
- InputMethodManagerService.ClientState.class);
+ mInputMethodManagerService.setAttachedClientForTesting(
+ mock(InputMethodManagerService.ClientState.class));
}
@Test
@@ -119,4 +125,38 @@
mVisibilityApplier.applyImeVisibility(mWindowToken, null, STATE_SHOW_IME_IMPLICIT);
verifyShowSoftInput(true, true, InputMethodManager.SHOW_IMPLICIT);
}
+
+ @Test
+ public void testApplyImeVisibility_hideImeFromTargetOnSecondaryDisplay() {
+ // Init a IME target client on the secondary display to show IME.
+ mInputMethodManagerService.addClient(mMockInputMethodClient, mMockRemoteInputConnection,
+ 10 /* selfReportedDisplayId */);
+ mInputMethodManagerService.setAttachedClientForTesting(null);
+ startInputOrWindowGainedFocus(mWindowToken, SOFT_INPUT_STATE_ALWAYS_VISIBLE);
+
+ synchronized (ImfLock.class) {
+ final int displayIdToShowIme = mInputMethodManagerService.getDisplayIdToShowImeLocked();
+ // Verify hideIme will apply the expected displayId when the default IME
+ // visibility applier app STATE_HIDE_IME.
+ mVisibilityApplier.applyImeVisibility(mWindowToken, null, STATE_HIDE_IME);
+ verify(mInputMethodManagerService.mWindowManagerInternal).hideIme(
+ eq(mWindowToken), eq(displayIdToShowIme), eq(null));
+ }
+ }
+
+ private InputBindResult startInputOrWindowGainedFocus(IBinder windowToken, int softInputMode) {
+ return mInputMethodManagerService.startInputOrWindowGainedFocus(
+ StartInputReason.WINDOW_FOCUS_GAIN /* startInputReason */,
+ mMockInputMethodClient /* client */,
+ windowToken /* windowToken */,
+ StartInputFlags.VIEW_HAS_FOCUS | StartInputFlags.IS_TEXT_EDITOR,
+ softInputMode /* softInputMode */,
+ 0 /* windowFlags */,
+ mEditorInfo /* editorInfo */,
+ mMockRemoteInputConnection /* inputConnection */,
+ mMockRemoteAccessibilityInputConnection /* remoteAccessibilityInputConnection */,
+ mTargetSdkVersion /* unverifiedTargetSdkVersion */,
+ mCallingUserId /* userId */,
+ mMockImeOnBackInvokedDispatcher /* imeDispatcher */);
+ }
}
diff --git a/services/tests/PackageManagerComponentOverrideTests/Android.bp b/services/tests/PackageManagerComponentOverrideTests/Android.bp
index 5c09e73..bc36970 100644
--- a/services/tests/PackageManagerComponentOverrideTests/Android.bp
+++ b/services/tests/PackageManagerComponentOverrideTests/Android.bp
@@ -35,7 +35,7 @@
"androidx.test.runner",
"mockito-target-extended-minus-junit4",
"services.core",
- "service-permission.impl",
+ "service-permission.stubs.system_server",
"servicestests-utils-mockito-extended",
"testng", // TODO: remove once Android migrates to JUnit 4.12, which provides assertThrows
"truth-prebuilt",
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_cur_freq
deleted file mode 100644
index 80b164d..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-"1.23
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_max_freq
deleted file mode 100644
index 582d8c8..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-+2.5
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_max_freq
deleted file mode 100644
index 749fce6..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/corrupted_cpufreq/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_cur_freq
deleted file mode 100644
index dadd973..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-1230000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_max_freq
deleted file mode 100644
index a93d6f7..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_cur_freq
index 573541a..dadd973 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_cur_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_cur_freq
@@ -1 +1 @@
-0
+1230000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_max_freq
index 573541a..a93d6f7 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_max_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy0/scaling_max_freq
@@ -1 +1 @@
-0
+2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/scaling_max_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/cpuinfo_max_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy1/scaling_max_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_cur_freq
deleted file mode 100644
index 749fce6..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_max_freq
deleted file mode 100644
index a93d6f7..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_cur_freq
index 573541a..749fce6 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_cur_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_cur_freq
@@ -1 +1 @@
-0
+1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_max_freq
index 573541a..a93d6f7 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_max_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy0/scaling_max_freq
@@ -1 +1 @@
-0
+2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/scaling_max_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/cpuinfo_max_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy1/scaling_max_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_time_in_state_2/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_cur_freq
deleted file mode 100644
index dadd973..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-1230000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_max_freq
deleted file mode 100644
index a93d6f7..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_cur_freq
index 573541a..dadd973 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_cur_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_cur_freq
@@ -1 +1 @@
-0
+1230000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_max_freq
index 573541a..a93d6f7 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_max_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy0/scaling_max_freq
@@ -1 +1 @@
-0
+2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/scaling_max_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/cpuinfo_max_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy1/scaling_max_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_cur_freq
deleted file mode 100644
index 749fce6..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_cur_freq
+++ /dev/null
@@ -1 +0,0 @@
-1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_max_freq
deleted file mode 100644
index a93d6f7..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/cpuinfo_max_freq
+++ /dev/null
@@ -1 +0,0 @@
-2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_cur_freq
index 573541a..749fce6 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_cur_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_cur_freq
@@ -1 +1 @@
-0
+1000000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_max_freq
index 573541a..a93d6f7 100644
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_max_freq
+++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy0/scaling_max_freq
@@ -1 +1 @@
-0
+2500000
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/scaling_cur_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/cpuinfo_cur_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/scaling_cur_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/scaling_max_freq
similarity index 100%
rename from services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/cpuinfo_max_freq
rename to services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy1/scaling_max_freq
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_cur_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_cur_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_max_freq
deleted file mode 100644
index e69de29..0000000
--- a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_without_time_in_state_2/policy2/cpuinfo_max_freq
+++ /dev/null
diff --git a/services/tests/mockingservicestests/src/android/service/dreams/DreamOverlayConnectionHandlerTest.java b/services/tests/mockingservicestests/src/android/service/dreams/DreamOverlayConnectionHandlerTest.java
new file mode 100644
index 0000000..22d7e73
--- /dev/null
+++ b/services/tests/mockingservicestests/src/android/service/dreams/DreamOverlayConnectionHandlerTest.java
@@ -0,0 +1,245 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.service.dreams;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import static org.mockito.Mockito.atLeastOnce;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+
+import android.content.Context;
+import android.content.Intent;
+import android.os.Handler;
+import android.os.RemoteException;
+import android.os.test.TestLooper;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.SmallTest;
+
+import com.android.internal.util.ObservableServiceConnection;
+import com.android.internal.util.PersistentServiceConnection;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.mockito.ArgumentCaptor;
+import org.mockito.Mock;
+import org.mockito.Mockito;
+import org.mockito.MockitoAnnotations;
+
+import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
+
+@SmallTest
+@RunWith(AndroidJUnit4.class)
+public class DreamOverlayConnectionHandlerTest {
+ private static final int MIN_CONNECTION_DURATION_MS = 100;
+ private static final int MAX_RECONNECT_ATTEMPTS = 3;
+ private static final int BASE_RECONNECT_DELAY_MS = 50;
+
+ @Mock
+ private Context mContext;
+ @Mock
+ private PersistentServiceConnection<IDreamOverlay> mConnection;
+ @Mock
+ private Intent mServiceIntent;
+ @Mock
+ private IDreamOverlay mOverlayService;
+ @Mock
+ private IDreamOverlayClient mOverlayClient;
+
+ private TestLooper mTestLooper;
+ private DreamOverlayConnectionHandler mDreamOverlayConnectionHandler;
+
+ @Before
+ public void setUp() {
+ MockitoAnnotations.initMocks(this);
+ mTestLooper = new TestLooper();
+ mDreamOverlayConnectionHandler = new DreamOverlayConnectionHandler(
+ mContext,
+ mTestLooper.getLooper(),
+ mServiceIntent,
+ MIN_CONNECTION_DURATION_MS,
+ MAX_RECONNECT_ATTEMPTS,
+ BASE_RECONNECT_DELAY_MS,
+ new TestInjector(mConnection));
+ }
+
+ @Test
+ public void consumerShouldRunImmediatelyWhenClientAvailable() throws RemoteException {
+ mDreamOverlayConnectionHandler.bind();
+ connectService();
+ provideClient();
+
+ final Consumer<IDreamOverlayClient> consumer = Mockito.mock(Consumer.class);
+ mDreamOverlayConnectionHandler.addConsumer(consumer);
+ mTestLooper.dispatchAll();
+ verify(consumer).accept(mOverlayClient);
+ }
+
+ @Test
+ public void consumerShouldRunAfterClientAvailable() throws RemoteException {
+ mDreamOverlayConnectionHandler.bind();
+ connectService();
+
+ final Consumer<IDreamOverlayClient> consumer = Mockito.mock(Consumer.class);
+ mDreamOverlayConnectionHandler.addConsumer(consumer);
+ mTestLooper.dispatchAll();
+ // No client yet, so we shouldn't have executed
+ verify(consumer, never()).accept(mOverlayClient);
+
+ provideClient();
+ mTestLooper.dispatchAll();
+ verify(consumer).accept(mOverlayClient);
+ }
+
+ @Test
+ public void consumerShouldNeverRunIfClientConnectsAndDisconnects() throws RemoteException {
+ mDreamOverlayConnectionHandler.bind();
+ connectService();
+
+ final Consumer<IDreamOverlayClient> consumer = Mockito.mock(Consumer.class);
+ mDreamOverlayConnectionHandler.addConsumer(consumer);
+ mTestLooper.dispatchAll();
+ // No client yet, so we shouldn't have executed
+ verify(consumer, never()).accept(mOverlayClient);
+
+ provideClient();
+ // Service disconnected before looper could handle the message.
+ disconnectService();
+ mTestLooper.dispatchAll();
+ verify(consumer, never()).accept(mOverlayClient);
+ }
+
+ @Test
+ public void consumerShouldNeverRunIfUnbindCalled() throws RemoteException {
+ mDreamOverlayConnectionHandler.bind();
+ connectService();
+ provideClient();
+
+ final Consumer<IDreamOverlayClient> consumer = Mockito.mock(Consumer.class);
+ mDreamOverlayConnectionHandler.addConsumer(consumer);
+ mDreamOverlayConnectionHandler.unbind();
+ mTestLooper.dispatchAll();
+ // We unbinded immediately after adding consumer, so should never have run.
+ verify(consumer, never()).accept(mOverlayClient);
+ }
+
+ @Test
+ public void consumersOnlyRunOnceIfUnbound() throws RemoteException {
+ mDreamOverlayConnectionHandler.bind();
+ connectService();
+ provideClient();
+
+ AtomicInteger counter = new AtomicInteger();
+ // Add 10 consumers in a row which call unbind within the consumer.
+ for (int i = 0; i < 10; i++) {
+ mDreamOverlayConnectionHandler.addConsumer(client -> {
+ counter.getAndIncrement();
+ mDreamOverlayConnectionHandler.unbind();
+ });
+ }
+ mTestLooper.dispatchAll();
+ // Only the first consumer should have run, since we unbinded.
+ assertThat(counter.get()).isEqualTo(1);
+ }
+
+ @Test
+ public void consumerShouldRunAgainAfterReconnect() throws RemoteException {
+ mDreamOverlayConnectionHandler.bind();
+ connectService();
+ provideClient();
+
+ final Consumer<IDreamOverlayClient> consumer = Mockito.mock(Consumer.class);
+ mDreamOverlayConnectionHandler.addConsumer(consumer);
+ mTestLooper.dispatchAll();
+ verify(consumer, times(1)).accept(mOverlayClient);
+
+ disconnectService();
+ mTestLooper.dispatchAll();
+ // No new calls should happen when service disconnected.
+ verify(consumer, times(1)).accept(mOverlayClient);
+
+ connectService();
+ provideClient();
+ mTestLooper.dispatchAll();
+ // We should trigger the consumer again once the server reconnects.
+ verify(consumer, times(2)).accept(mOverlayClient);
+ }
+
+ @Test
+ public void consumerShouldNeverRunIfRemovedImmediately() throws RemoteException {
+ mDreamOverlayConnectionHandler.bind();
+ connectService();
+ provideClient();
+
+ final Consumer<IDreamOverlayClient> consumer = Mockito.mock(Consumer.class);
+ mDreamOverlayConnectionHandler.addConsumer(consumer);
+ mDreamOverlayConnectionHandler.removeConsumer(consumer);
+ mTestLooper.dispatchAll();
+ verify(consumer, never()).accept(mOverlayClient);
+ }
+
+ private void connectService() {
+ final ObservableServiceConnection.Callback<IDreamOverlay> callback =
+ captureConnectionCallback();
+ callback.onConnected(mConnection, mOverlayService);
+ }
+
+ private void disconnectService() {
+ final ObservableServiceConnection.Callback<IDreamOverlay> callback =
+ captureConnectionCallback();
+ callback.onDisconnected(mConnection, /* reason= */ 0);
+ }
+
+ private void provideClient() throws RemoteException {
+ final IDreamOverlayClientCallback callback = captureClientCallback();
+ callback.onDreamOverlayClient(mOverlayClient);
+ }
+
+ private ObservableServiceConnection.Callback<IDreamOverlay> captureConnectionCallback() {
+ ArgumentCaptor<ObservableServiceConnection.Callback<IDreamOverlay>>
+ callbackCaptor =
+ ArgumentCaptor.forClass(ObservableServiceConnection.Callback.class);
+ verify(mConnection).addCallback(callbackCaptor.capture());
+ return callbackCaptor.getValue();
+ }
+
+ private IDreamOverlayClientCallback captureClientCallback() throws RemoteException {
+ ArgumentCaptor<IDreamOverlayClientCallback> callbackCaptor =
+ ArgumentCaptor.forClass(IDreamOverlayClientCallback.class);
+ verify(mOverlayService, atLeastOnce()).getClient(callbackCaptor.capture());
+ return callbackCaptor.getValue();
+ }
+
+ static class TestInjector extends DreamOverlayConnectionHandler.Injector {
+ private final PersistentServiceConnection<IDreamOverlay> mConnection;
+
+ TestInjector(PersistentServiceConnection<IDreamOverlay> connection) {
+ mConnection = connection;
+ }
+
+ @Override
+ public PersistentServiceConnection<IDreamOverlay> buildConnection(Context context,
+ Handler handler, Intent serviceIntent, int minConnectionDurationMs,
+ int maxReconnectAttempts, int baseReconnectDelayMs) {
+ return mConnection;
+ }
+ }
+}
diff --git a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
index 31cfa78..47ae97f 100644
--- a/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/AppStateTrackerTest.java
@@ -1365,8 +1365,8 @@
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- verify(l, times(0)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).removeAlarmsForUid(anyInt());
+ verify(l, times(0)).handleUidCachedChanged(anyInt(), anyBoolean());
reset(l);
mIUidObserver.onUidGone(UID_10_1, true);
@@ -1385,7 +1385,7 @@
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
verify(l, times(1)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).handleUidCachedChanged(anyInt(), anyBoolean());
reset(l);
mIUidObserver.onUidActive(UID_10_1);
@@ -1403,8 +1403,8 @@
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- verify(l, times(0)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).removeAlarmsForUid(anyInt());
+ verify(l, times(0)).handleUidCachedChanged(anyInt(), anyBoolean());
reset(l);
mIUidObserver.onUidIdle(UID_10_1, true);
@@ -1423,7 +1423,7 @@
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
verify(l, times(1)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).handleUidCachedChanged(anyInt(), anyBoolean());
reset(l);
mIUidObserver.onUidCachedChanged(UID_10_1, true);
@@ -1441,8 +1441,8 @@
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- verify(l, times(0)).removeAlarmsForUid(UID_10_1);
- verify(l, times(1)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).removeAlarmsForUid(anyInt());
+ verify(l, times(1)).handleUidCachedChanged(UID_10_1, true);
reset(l);
mIUidObserver.onUidCachedChanged(UID_10_1, false);
@@ -1460,8 +1460,8 @@
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- verify(l, times(0)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).removeAlarmsForUid(anyInt());
+ verify(l, times(1)).handleUidCachedChanged(UID_10_1, false);
reset(l);
@@ -1481,8 +1481,8 @@
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- verify(l, times(0)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).removeAlarmsForUid(anyInt());
+ verify(l, times(0)).handleUidCachedChanged(anyInt(), anyBoolean());
reset(l);
mIUidObserver.onUidActive(UID_10_1);
@@ -1500,8 +1500,8 @@
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- verify(l, times(0)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).removeAlarmsForUid(anyInt());
+ verify(l, times(0)).handleUidCachedChanged(anyInt(), anyBoolean());
reset(l);
mIUidObserver.onUidGone(UID_10_1, true);
@@ -1520,7 +1520,7 @@
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
verify(l, times(1)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).handleUidCachedChanged(anyInt(), anyBoolean());
reset(l);
mIUidObserver.onUidActive(UID_10_1);
@@ -1538,8 +1538,8 @@
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(1)).unblockAlarmsForUid(eq(UID_10_1));
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- verify(l, times(0)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).removeAlarmsForUid(anyInt());
+ verify(l, times(0)).handleUidCachedChanged(anyInt(), anyBoolean());
reset(l);
mIUidObserver.onUidIdle(UID_10_1, true);
@@ -1558,7 +1558,7 @@
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
verify(l, times(1)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).handleUidCachedChanged(anyInt(), anyBoolean());
reset(l);
mIUidObserver.onUidCachedChanged(UID_10_1, true);
@@ -1576,8 +1576,8 @@
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- verify(l, times(0)).removeAlarmsForUid(UID_10_1);
- verify(l, times(1)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).removeAlarmsForUid(anyInt());
+ verify(l, times(1)).handleUidCachedChanged(UID_10_1, true);
reset(l);
mIUidObserver.onUidCachedChanged(UID_10_1, false);
@@ -1595,8 +1595,8 @@
verify(l, times(0)).unblockAllUnrestrictedAlarms();
verify(l, times(0)).unblockAlarmsForUid(anyInt());
verify(l, times(0)).unblockAlarmsForUidPackage(anyInt(), anyString());
- verify(l, times(0)).removeAlarmsForUid(UID_10_1);
- verify(l, times(0)).removeListenerAlarmsForCachedUid(UID_10_1);
+ verify(l, times(0)).removeAlarmsForUid(anyInt());
+ verify(l, times(1)).handleUidCachedChanged(UID_10_1, false);
reset(l);
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
index 5377ee7..3a47b47 100644
--- a/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/DeviceIdleControllerTest.java
@@ -50,7 +50,6 @@
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;
@@ -624,8 +623,7 @@
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
verifyStateConditions(STATE_INACTIVE);
- verify(mDeviceIdleController)
- .scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT), eq(false));
+ verify(mDeviceIdleController).scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT));
}
@Test
@@ -643,8 +641,7 @@
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
verifyStateConditions(STATE_INACTIVE);
- verify(mDeviceIdleController)
- .scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT), eq(false));
+ verify(mDeviceIdleController).scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT));
// The device configuration doesn't require a motion sensor to proceed with idling.
// This should be the case on TVs or other such devices. We should set an alarm to move
// forward if the motion sensor is missing in this case.
@@ -669,8 +666,7 @@
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
verifyStateConditions(STATE_INACTIVE);
- verify(mDeviceIdleController)
- .scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT), eq(false));
+ verify(mDeviceIdleController).scheduleAlarmLocked(eq(mConstants.INACTIVE_TIMEOUT));
// The device configuration requires a motion sensor to proceed with idling,
// so we should never set an alarm to move forward if the motion sensor is
// missing in this case.
@@ -699,7 +695,7 @@
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
verifyStateConditions(STATE_INACTIVE);
inOrder.verify(mDeviceIdleController)
- .scheduleAlarmLocked(eq(timeUntilAlarm + mConstants.INACTIVE_TIMEOUT), eq(false));
+ .scheduleAlarmLocked(eq(timeUntilAlarm + mConstants.INACTIVE_TIMEOUT));
enterDeepState(STATE_ACTIVE);
setQuickDozeEnabled(true);
@@ -709,7 +705,7 @@
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
verifyStateConditions(STATE_QUICK_DOZE_DELAY);
inOrder.verify(mDeviceIdleController).scheduleAlarmLocked(
- eq(timeUntilAlarm + mConstants.QUICK_DOZE_DELAY_TIMEOUT), eq(false));
+ eq(timeUntilAlarm + mConstants.QUICK_DOZE_DELAY_TIMEOUT));
}
@Test
@@ -736,59 +732,56 @@
setScreenOn(false);
verifyStateConditions(STATE_QUICK_DOZE_DELAY);
inOrder.verify(mDeviceIdleController)
- .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT), eq(false));
+ .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
enterDeepState(STATE_INACTIVE);
setQuickDozeEnabled(true);
verifyStateConditions(STATE_QUICK_DOZE_DELAY);
inOrder.verify(mDeviceIdleController)
- .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT), eq(false));
+ .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
enterDeepState(STATE_IDLE_PENDING);
setQuickDozeEnabled(true);
verifyStateConditions(STATE_QUICK_DOZE_DELAY);
inOrder.verify(mDeviceIdleController)
- .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT), eq(false));
+ .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
enterDeepState(STATE_SENSING);
setQuickDozeEnabled(true);
verifyStateConditions(STATE_QUICK_DOZE_DELAY);
inOrder.verify(mDeviceIdleController)
- .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT), eq(false));
+ .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
enterDeepState(STATE_LOCATING);
setQuickDozeEnabled(true);
verifyStateConditions(STATE_QUICK_DOZE_DELAY);
inOrder.verify(mDeviceIdleController)
- .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT), eq(false));
+ .scheduleAlarmLocked(eq(mConstants.QUICK_DOZE_DELAY_TIMEOUT));
// IDLE should stay as IDLE.
enterDeepState(STATE_IDLE);
// Clear out any alarm setting from the order before checking for this section.
- inOrder.verify(mDeviceIdleController, atLeastOnce())
- .scheduleAlarmLocked(anyLong(), anyBoolean());
+ inOrder.verify(mDeviceIdleController, atLeastOnce()).scheduleAlarmLocked(anyLong());
setQuickDozeEnabled(true);
verifyStateConditions(STATE_IDLE);
- inOrder.verify(mDeviceIdleController, never()).scheduleAlarmLocked(anyLong(), anyBoolean());
+ inOrder.verify(mDeviceIdleController, never()).scheduleAlarmLocked(anyLong());
// IDLE_MAINTENANCE should stay as IDLE_MAINTENANCE.
enterDeepState(STATE_IDLE_MAINTENANCE);
// Clear out any alarm setting from the order before checking for this section.
- inOrder.verify(mDeviceIdleController, atLeastOnce())
- .scheduleAlarmLocked(anyLong(), anyBoolean());
+ inOrder.verify(mDeviceIdleController, atLeastOnce()).scheduleAlarmLocked(anyLong());
setQuickDozeEnabled(true);
verifyStateConditions(STATE_IDLE_MAINTENANCE);
- inOrder.verify(mDeviceIdleController, never()).scheduleAlarmLocked(anyLong(), anyBoolean());
+ inOrder.verify(mDeviceIdleController, never()).scheduleAlarmLocked(anyLong());
// State is already QUICK_DOZE_DELAY. No work should be done.
enterDeepState(STATE_QUICK_DOZE_DELAY);
// Clear out any alarm setting from the order before checking for this section.
- inOrder.verify(mDeviceIdleController, atLeastOnce())
- .scheduleAlarmLocked(anyLong(), anyBoolean());
+ inOrder.verify(mDeviceIdleController, atLeastOnce()).scheduleAlarmLocked(anyLong());
setQuickDozeEnabled(true);
mDeviceIdleController.becomeInactiveIfAppropriateLocked();
verifyStateConditions(STATE_QUICK_DOZE_DELAY);
- inOrder.verify(mDeviceIdleController, never()).scheduleAlarmLocked(anyLong(), anyBoolean());
+ inOrder.verify(mDeviceIdleController, never()).scheduleAlarmLocked(anyLong());
}
@Test
@@ -2685,17 +2678,12 @@
if (ret == mDeviceIdleController.SET_IDLE_FACTOR_RESULT_OK) {
enterDeepState(STATE_IDLE);
long now = SystemClock.elapsedRealtime();
- long alarm = mDeviceIdleController.getNextAlarmTime();
mDeviceIdleController.setIdleStartTimeForTest(
now - (long) (mConstants.IDLE_TIMEOUT * 0.6));
- long newAlarm = mDeviceIdleController.getNextAlarmTime();
- assertTrue("maintenance not reschedule IDLE_TIMEOUT * 0.6",
- newAlarm == alarm);
+ verifyStateConditions(STATE_IDLE);
mDeviceIdleController.setIdleStartTimeForTest(
now - (long) (mConstants.IDLE_TIMEOUT * 1.2));
- newAlarm = mDeviceIdleController.getNextAlarmTime();
- assertTrue("maintenance not reschedule IDLE_TIMEOUT * 1.2",
- (newAlarm - now) < minuteInMillis);
+ verifyStateConditions(STATE_IDLE_MAINTENANCE);
mDeviceIdleController.resetPreIdleTimeoutMode();
}
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
index e7e26a1..f9f5325 100644
--- a/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/alarm/AlarmManagerServiceTest.java
@@ -28,7 +28,6 @@
import static android.app.AlarmManager.FLAG_WAKE_FROM_IDLE;
import static android.app.AlarmManager.RTC;
import static android.app.AlarmManager.RTC_WAKEUP;
-import static android.app.AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT;
import static android.app.AlarmManager.WINDOW_EXACT;
import static android.app.AlarmManager.WINDOW_HEURISTIC;
import static android.app.AppOpsManager.MODE_ALLOWED;
@@ -66,6 +65,7 @@
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.EXACT_ALARM_DENY_LIST_PACKAGES_REMOVED;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REFRESH_EXACT_ALARM_CANDIDATES;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_ALARMS;
+import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.REMOVE_FOR_CANCELED;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.TARE_AFFORDABILITY_CHANGED;
import static com.android.server.alarm.AlarmManagerService.AlarmHandler.TEMPORARY_QUOTA_CHANGED;
@@ -126,7 +126,6 @@
import android.app.IAlarmManager;
import android.app.PendingIntent;
import android.app.compat.CompatChanges;
-import android.app.role.RoleManager;
import android.app.tare.EconomyManager;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ContentResolver;
@@ -134,7 +133,6 @@
import android.content.Intent;
import android.content.PermissionChecker;
import android.content.pm.PackageManagerInternal;
-import android.database.ContentObserver;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Bundle;
@@ -192,7 +190,6 @@
import org.mockito.stubbing.Answer;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
@@ -246,8 +243,6 @@
@Mock
private PackageManagerInternal mPackageManagerInternal;
@Mock
- private RoleManager mRoleManager;
- @Mock
private AppStateTrackerImpl mAppStateTracker;
@Mock
private AlarmManagerService.ClockReceiver mClockReceiver;
@@ -393,11 +388,6 @@
}
@Override
- void registerContentObserver(ContentObserver observer, Uri uri) {
- // Do nothing.
- }
-
- @Override
void registerDeviceConfigListener(DeviceConfig.OnPropertiesChangedListener listener) {
// Do nothing.
// The tests become flaky with an error message of
@@ -484,10 +474,12 @@
doReturn(PermissionChecker.PERMISSION_HARD_DENIED).when(
() -> PermissionChecker.checkPermissionForPreflight(any(),
eq(Manifest.permission.USE_EXACT_ALARM), anyInt(), anyInt(), anyString()));
+ doReturn(PermissionChecker.PERMISSION_HARD_DENIED).when(
+ () -> PermissionChecker.checkPermissionForPreflight(any(), eq(SCHEDULE_EXACT_ALARM),
+ anyInt(), anyInt(), anyString()));
when(mMockContext.getSystemService(Context.APP_OPS_SERVICE)).thenReturn(mAppOpsManager);
when(mMockContext.getSystemService(BatteryManager.class)).thenReturn(mBatteryManager);
- when(mMockContext.getSystemService(RoleManager.class)).thenReturn(mRoleManager);
registerAppIds(new String[]{TEST_CALLING_PACKAGE},
new Integer[]{UserHandle.getAppId(TEST_CALLING_UID)});
@@ -2181,40 +2173,6 @@
}
}
- @Test
- public void hasScheduleExactAlarmBinderCallNotDenyListed() throws RemoteException {
- mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
-
- mockScheduleExactAlarmState(true, false, MODE_DEFAULT);
- assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
-
- mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
- assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
-
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
- assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
-
- mockScheduleExactAlarmState(true, false, MODE_IGNORED);
- assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
- }
-
- @Test
- public void hasScheduleExactAlarmBinderCallDenyListed() throws RemoteException {
- mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
-
- mockScheduleExactAlarmState(true, true, MODE_ERRORED);
- assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
-
- mockScheduleExactAlarmState(true, true, MODE_DEFAULT);
- assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
-
- mockScheduleExactAlarmState(true, true, MODE_IGNORED);
- assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
-
- mockScheduleExactAlarmState(true, true, MODE_ALLOWED);
- assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
- }
-
private void mockChangeEnabled(long changeId, boolean enabled) {
doReturn(enabled).when(() -> CompatChanges.isChangeEnabled(eq(changeId), anyString(),
any(UserHandle.class)));
@@ -2222,16 +2180,62 @@
}
@Test
- public void hasScheduleExactAlarmBinderCallNotDeclared() throws RemoteException {
+ public void hasScheduleExactAlarmBinderCall() throws RemoteException {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+ mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
+
+ mockScheduleExactAlarmState(true);
+ assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+
+ mockScheduleExactAlarmState(false);
+ assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+ }
+
+ @Test
+ public void hasScheduleExactAlarmBinderCallNotDenyListedPreT() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
- mockScheduleExactAlarmState(false, false, MODE_DEFAULT);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_DEFAULT);
+ assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
+ assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
- mockScheduleExactAlarmState(false, false, MODE_ALLOWED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_IGNORED);
+ assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+ }
+
+ @Test
+ public void hasScheduleExactAlarmBinderCallDenyListedPreT() throws RemoteException {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
+ mockScheduleExactAlarmStatePreT(true, true, MODE_ERRORED);
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
- mockScheduleExactAlarmState(false, true, MODE_ALLOWED);
+ mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT);
+ assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+
+ mockScheduleExactAlarmStatePreT(true, true, MODE_IGNORED);
+ assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+
+ mockScheduleExactAlarmStatePreT(true, true, MODE_ALLOWED);
+ assertTrue(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+ }
+
+ @Test
+ public void hasScheduleExactAlarmBinderCallNotDeclaredPreT() throws RemoteException {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+
+ mockScheduleExactAlarmStatePreT(false, false, MODE_DEFAULT);
+ assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+
+ mockScheduleExactAlarmStatePreT(false, false, MODE_ALLOWED);
+ assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
+
+ mockScheduleExactAlarmStatePreT(false, true, MODE_ALLOWED);
assertFalse(mBinder.hasScheduleExactAlarm(TEST_CALLING_PACKAGE, TEST_CALLING_USER));
}
@@ -2240,61 +2244,94 @@
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
// canScheduleExactAlarms should be true regardless of any permission state.
- mockUseExactAlarmState(true);
+ // Both SEA and UEA are denied in setUp.
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
mockUseExactAlarmState(false);
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
- mockScheduleExactAlarmState(false, true, MODE_DEFAULT);
- assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
-
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmState(false);
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
}
@Test
- public void canScheduleExactAlarmsBinderCall() throws RemoteException {
+ public void canScheduleExactAlarmsBinderCallPreT() throws RemoteException {
// Policy permission is denied in setUp().
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
// No permission, no exemption.
- mockScheduleExactAlarmState(true, true, MODE_DEFAULT);
+ mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT);
assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
// No permission, no exemption.
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
// Policy permission only, no exemption.
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
mockUseExactAlarmState(true);
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
mockUseExactAlarmState(false);
// User permission only, no exemption.
- mockScheduleExactAlarmState(true, false, MODE_DEFAULT);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_DEFAULT);
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
// User permission only, no exemption.
- mockScheduleExactAlarmState(true, true, MODE_ALLOWED);
+ mockScheduleExactAlarmStatePreT(true, true, MODE_ALLOWED);
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
// No permission, exemption.
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(true);
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
// No permission, exemption.
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(false);
doReturn(true).when(() -> UserHandle.isCore(TEST_CALLING_UID));
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
// Both permissions and exemption.
- mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
+ mockUseExactAlarmState(true);
+ assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+ }
+
+ @Test
+ public void canScheduleExactAlarmsBinderCall() throws RemoteException {
+ // Both permissions are denied in setUp().
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+ mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
+ mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
+
+ // No permission, no exemption.
+ assertFalse(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+ // Policy permission only, no exemption.
+ mockUseExactAlarmState(true);
+ assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+ mockUseExactAlarmState(false);
+
+ // User permission only, no exemption.
+ mockScheduleExactAlarmState(true);
+ assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+ // No permission, exemption.
+ mockScheduleExactAlarmState(false);
+ when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(true);
+ assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+ // No permission, core uid exemption.
+ when(mDeviceIdleInternal.isAppOnWhitelist(TEST_CALLING_UID)).thenReturn(false);
+ doReturn(true).when(() -> UserHandle.isCore(TEST_CALLING_UID));
+ assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
+
+ // Both permissions and core uid exemption.
+ mockScheduleExactAlarmState(true);
mockUseExactAlarmState(true);
assertTrue(mBinder.canScheduleExactAlarms(TEST_CALLING_PACKAGE));
}
@@ -2404,8 +2441,9 @@
@Test
public void alarmClockBinderCallWithSEAPermission() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+ mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
- mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
+ mockScheduleExactAlarmState(true);
final PendingIntent alarmPi = getNewMockPendingIntent();
final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class);
@@ -2431,9 +2469,10 @@
public void alarmClockBinderCallWithUEAPermission() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
+ mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
mockUseExactAlarmState(true);
- mockScheduleExactAlarmState(false, false, MODE_ERRORED);
+ mockScheduleExactAlarmState(false);
final PendingIntent alarmPi = getNewMockPendingIntent();
final AlarmManager.AlarmClockInfo alarmClock = mock(AlarmManager.AlarmClockInfo.class);
@@ -2455,7 +2494,7 @@
assertEquals(TEMPORARY_ALLOWLIST_TYPE_FOREGROUND_SERVICE_ALLOWED, type);
}
- private void mockScheduleExactAlarmState(boolean declared, boolean denyList, int mode) {
+ private void mockScheduleExactAlarmStatePreT(boolean declared, boolean denyList, int mode) {
String[] requesters = declared ? new String[]{TEST_CALLING_PACKAGE} : EmptyArray.STRING;
when(mPermissionManagerInternal.getAppOpPermissionPackages(SCHEDULE_EXACT_ALARM))
.thenReturn(requesters);
@@ -2470,6 +2509,20 @@
TEST_CALLING_PACKAGE)).thenReturn(mode);
}
+ private void mockScheduleExactAlarmState(boolean granted) {
+ String[] requesters = granted ? new String[]{TEST_CALLING_PACKAGE} : EmptyArray.STRING;
+ when(mPermissionManagerInternal.getAppOpPermissionPackages(SCHEDULE_EXACT_ALARM))
+ .thenReturn(requesters);
+ mService.refreshExactAlarmCandidates();
+
+ final int result = granted ? PermissionChecker.PERMISSION_GRANTED
+ : PermissionChecker.PERMISSION_HARD_DENIED;
+ doReturn(result).when(
+ () -> PermissionChecker.checkPermissionForPreflight(eq(mMockContext),
+ eq(SCHEDULE_EXACT_ALARM), anyInt(), eq(TEST_CALLING_UID),
+ eq(TEST_CALLING_PACKAGE)));
+ }
+
private void mockUseExactAlarmState(boolean granted) {
final int result = granted ? PermissionChecker.PERMISSION_GRANTED
: PermissionChecker.PERMISSION_HARD_DENIED;
@@ -2483,7 +2536,7 @@
public void alarmClockBinderCallWithoutPermission() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
final PendingIntent alarmPi = getNewMockPendingIntent();
@@ -2504,8 +2557,9 @@
@Test
public void exactBinderCallWithSEAPermission() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+ mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
- mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
+ mockScheduleExactAlarmState(true);
final PendingIntent alarmPi = getNewMockPendingIntent();
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
0, alarmPi, null, null, null, null);
@@ -2529,9 +2583,10 @@
public void exactBinderCallWithUEAPermission() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
+ mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
mockUseExactAlarmState(true);
- mockScheduleExactAlarmState(false, false, MODE_ERRORED);
+ mockScheduleExactAlarmState(false);
final PendingIntent alarmPi = getNewMockPendingIntent();
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
0, alarmPi, null, null, null, null);
@@ -2555,7 +2610,7 @@
public void exactBinderCallWithAllowlist() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
// If permission is denied, only then allowlist will be checked.
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
final PendingIntent alarmPi = getNewMockPendingIntent();
@@ -2575,7 +2630,7 @@
public void exactAllowWhileIdleBinderCallWithSEAPermission() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
- mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
final PendingIntent alarmPi = getNewMockPendingIntent();
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null);
@@ -2601,7 +2656,7 @@
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
mockUseExactAlarmState(true);
- mockScheduleExactAlarmState(false, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(false, false, MODE_ERRORED);
final PendingIntent alarmPi = getNewMockPendingIntent();
mBinder.set(TEST_CALLING_PACKAGE, ELAPSED_REALTIME_WAKEUP, 1234, WINDOW_EXACT, 0,
FLAG_ALLOW_WHILE_IDLE, alarmPi, null, null, null, null);
@@ -2625,7 +2680,7 @@
public void exactAllowWhileIdleBinderCallWithAllowlist() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
// If permission is denied, only then allowlist will be checked.
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
final PendingIntent alarmPi = getNewMockPendingIntent();
@@ -2651,7 +2706,7 @@
public void exactBinderCallsWithoutPermissionWithoutAllowlist() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(false);
final PendingIntent alarmPi = getNewMockPendingIntent();
@@ -2701,7 +2756,7 @@
public void binderCallWithUserAllowlist() throws RemoteException {
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
when(mDeviceIdleInternal.isAppOnWhitelist(anyInt())).thenReturn(true);
when(mAppStateTracker.isUidPowerSaveUserExempt(TEST_CALLING_UID)).thenReturn(true);
@@ -3026,7 +3081,7 @@
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ALLOWED);
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
assertAndHandleMessageSync(REMOVE_EXACT_ALARMS);
@@ -3039,7 +3094,7 @@
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ALLOWED);
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
@@ -3052,7 +3107,7 @@
mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ERRORED);
- mockScheduleExactAlarmState(true, true, MODE_DEFAULT);
+ mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT);
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
@@ -3068,7 +3123,7 @@
when(mActivityManagerInternal.getBootTimeTempAllowListDuration()).thenReturn(durationMs);
mService.mLastOpScheduleExactAlarm.put(TEST_CALLING_UID, MODE_ERRORED);
- mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
mIAppOpsCallback.opChanged(OP_SCHEDULE_EXACT_ALARM, TEST_CALLING_UID, TEST_CALLING_PACKAGE);
final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
@@ -3328,7 +3383,7 @@
.putExtra(Intent.EXTRA_REPLACING, true);
mockUseExactAlarmState(false);
- mockScheduleExactAlarmState(true, false, MODE_ALLOWED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
mPackageChangesReceiver.onReceive(mMockContext, packageReplacedIntent);
assertAndHandleMessageSync(CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE);
@@ -3336,7 +3391,7 @@
assertEquals(5, mService.mAlarmStore.size());
mockUseExactAlarmState(true);
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
mPackageChangesReceiver.onReceive(mMockContext, packageReplacedIntent);
assertAndHandleMessageSync(CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE);
@@ -3344,7 +3399,7 @@
assertEquals(5, mService.mAlarmStore.size());
mockUseExactAlarmState(false);
- mockScheduleExactAlarmState(true, false, MODE_ERRORED);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
mPackageChangesReceiver.onReceive(mMockContext, packageReplacedIntent);
assertAndHandleMessageSync(CHECK_EXACT_ALARM_PERMISSION_ON_UPDATE);
@@ -3363,55 +3418,6 @@
}
@Test
- public void isScheduleExactAlarmAllowedByDefault() {
- final String package1 = "priv";
- final String package2 = "signed";
- final String package3 = "normal";
- final String package4 = "wellbeing";
- final int uid1 = 1294;
- final int uid2 = 8321;
- final int uid3 = 3412;
- final int uid4 = 4591;
-
- when(mPackageManagerInternal.isUidPrivileged(uid1)).thenReturn(true);
- when(mPackageManagerInternal.isUidPrivileged(uid2)).thenReturn(false);
- when(mPackageManagerInternal.isUidPrivileged(uid3)).thenReturn(false);
- when(mPackageManagerInternal.isUidPrivileged(uid4)).thenReturn(false);
-
- when(mPackageManagerInternal.isPlatformSigned(package1)).thenReturn(false);
- when(mPackageManagerInternal.isPlatformSigned(package2)).thenReturn(true);
- when(mPackageManagerInternal.isPlatformSigned(package3)).thenReturn(false);
- when(mPackageManagerInternal.isPlatformSigned(package4)).thenReturn(false);
-
- when(mRoleManager.getRoleHolders(RoleManager.ROLE_SYSTEM_WELLBEING)).thenReturn(
- Arrays.asList(package4));
-
- mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false);
- mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{
- package1,
- package3,
- });
-
- // Deny listed packages will be false.
- assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1));
- assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2));
- assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3));
- assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4));
-
- mockChangeEnabled(SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
- mService.mConstants.EXACT_ALARM_DENY_LIST = new ArraySet<>(new String[]{
- package1,
- package3,
- });
-
- // Deny list doesn't matter now, only exemptions should be true.
- assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package1, uid1));
- assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package2, uid2));
- assertFalse(mService.isScheduleExactAlarmAllowedByDefault(package3, uid3));
- assertTrue(mService.isScheduleExactAlarmAllowedByDefault(package4, uid4));
- }
-
- @Test
public void alarmScheduledAtomPushed() {
for (int i = 0; i < 10; i++) {
final PendingIntent pi = getNewMockPendingIntent();
@@ -3510,7 +3516,7 @@
}
@Test
- public void hasUseExactAlarmPermission() {
+ public void hasUseExactAlarmInternal() {
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, true);
mockUseExactAlarmState(true);
@@ -3521,7 +3527,7 @@
}
@Test
- public void hasUseExactAlarmPermissionChangeDisabled() {
+ public void hasUseExactAlarmInternalChangeDisabled() {
mockChangeEnabled(AlarmManager.ENABLE_USE_EXACT_ALARM, false);
mockUseExactAlarmState(true);
@@ -3532,6 +3538,49 @@
}
@Test
+ public void hasScheduleExactAlarmInternal() {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+ mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, true);
+
+ mockScheduleExactAlarmState(false);
+ assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+
+ mockScheduleExactAlarmState(true);
+ assertTrue(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+ }
+
+ @Test
+ public void hasScheduleExactAlarmInternalPreT() {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, true);
+ mockChangeEnabled(AlarmManager.SCHEDULE_EXACT_ALARM_DENIED_BY_DEFAULT, false);
+
+ mockScheduleExactAlarmStatePreT(true, true, MODE_DEFAULT);
+ assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+
+ mockScheduleExactAlarmStatePreT(false, false, MODE_ALLOWED);
+ assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
+ assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
+ assertTrue(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+ }
+
+ @Test
+ public void hasScheduleExactAlarmInternalPreS() {
+ mockChangeEnabled(AlarmManager.REQUIRE_EXACT_ALARM_PERMISSION, false);
+
+ mockScheduleExactAlarmState(true);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ALLOWED);
+ assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+
+ mockScheduleExactAlarmState(false);
+ mockScheduleExactAlarmStatePreT(true, false, MODE_ERRORED);
+ assertFalse(mService.hasScheduleExactAlarmInternal(TEST_CALLING_PACKAGE, TEST_CALLING_UID));
+ }
+
+ @Test
public void temporaryQuotaReserve_hasQuota() {
final int quotaToFill = 5;
final String package1 = "package1";
@@ -3763,10 +3812,12 @@
assertEquals(8, mService.mAlarmStore.size());
- mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID);
+ mListener.handleUidCachedChanged(TEST_CALLING_UID, true);
+ assertAndHandleMessageSync(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED);
assertEquals(7, mService.mAlarmStore.size());
- mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID_2);
+ mListener.handleUidCachedChanged(TEST_CALLING_UID_2, true);
+ assertAndHandleMessageSync(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED);
assertEquals(6, mService.mAlarmStore.size());
}
@@ -3797,10 +3848,12 @@
assertEquals(numExactListenerUid1 + 3, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
assertEquals(numExactListenerUid2 + 2, mService.mAlarmsPerUid.get(TEST_CALLING_UID_2));
- mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID);
+ mListener.handleUidCachedChanged(TEST_CALLING_UID, true);
+ assertAndHandleMessageSync(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED);
assertEquals(3, mService.mAlarmsPerUid.get(TEST_CALLING_UID));
- mListener.removeListenerAlarmsForCachedUid(TEST_CALLING_UID_2);
+ mListener.handleUidCachedChanged(TEST_CALLING_UID_2, true);
+ assertAndHandleMessageSync(REMOVE_EXACT_LISTENER_ALARMS_ON_CACHED);
assertEquals(2, mService.mAlarmsPerUid.get(TEST_CALLING_UID_2));
}
}
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 8a5d3a6..63e8e56 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueModernImplTest.java
@@ -50,6 +50,7 @@
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
@@ -1078,7 +1079,7 @@
eq(getUidForPackage(PACKAGE_GREEN)), anyInt(), eq(Intent.ACTION_TIME_TICK),
eq(BROADCAST_DELIVERY_EVENT_REPORTED__RECEIVER_TYPE__MANIFEST),
eq(BROADCAST_DELIVERY_EVENT_REPORTED__PROC_START_TYPE__PROCESS_START_TYPE_COLD),
- anyLong(), anyLong(), anyLong(), anyInt()), times(1));
+ anyLong(), anyLong(), anyLong(), anyInt(), anyString(), anyString()), times(1));
}
private Intent createPackageChangedIntent(int uid, List<String> componentNameList) {
diff --git a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
index cf8460b..bca39ae 100644
--- a/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/am/BroadcastQueueTest.java
@@ -53,6 +53,7 @@
import android.app.BackgroundStartPrivileges;
import android.app.BroadcastOptions;
import android.app.IApplicationThread;
+import android.app.UidObserver;
import android.app.usage.UsageEvents.Event;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ComponentName;
@@ -83,6 +84,7 @@
import androidx.test.filters.MediumTest;
import androidx.test.platform.app.InstrumentationRegistry;
+import com.android.server.AlarmManagerInternal;
import com.android.server.DropBoxManagerInternal;
import com.android.server.LocalServices;
import com.android.server.am.ActivityManagerService.Injector;
@@ -153,11 +155,14 @@
private PackageManagerInternal mPackageManagerInt;
@Mock
private UsageStatsManagerInternal mUsageStatsManagerInt;
+ @Mock
+ private AlarmManagerInternal mAlarmManagerInt;
private ActivityManagerService mAms;
private BroadcastQueue mQueue;
BroadcastConstants mConstants;
private BroadcastSkipPolicy mSkipPolicy;
+ private UidObserver mUidObserver;
/**
* Desired behavior of the next
@@ -204,6 +209,8 @@
LocalServices.addService(DropBoxManagerInternal.class, mDropBoxManagerInt);
LocalServices.removeServiceForTest(PackageManagerInternal.class);
LocalServices.addService(PackageManagerInternal.class, mPackageManagerInt);
+ LocalServices.removeServiceForTest(AlarmManagerInternal.class);
+ LocalServices.addService(AlarmManagerInternal.class, mAlarmManagerInt);
doReturn(new ComponentName("", "")).when(mPackageManagerInt).getSystemUiServiceComponent();
doNothing().when(mPackageManagerInt).setPackageStoppedState(any(), anyBoolean(), anyInt());
doAnswer((invocation) -> {
@@ -281,6 +288,11 @@
}).when(mAms).getProcessRecordLocked(any(), anyInt());
doNothing().when(mAms).appNotResponding(any(), any());
+ doAnswer((invocation) -> {
+ mUidObserver = invocation.getArgument(0);
+ return null;
+ }).when(mAms).registerUidObserver(any(), anyInt(), anyInt(), any());
+
mConstants = new BroadcastConstants(Settings.Global.BROADCAST_FG_CONSTANTS);
mConstants.TIMEOUT = 100;
mConstants.ALLOW_BG_ACTIVITY_START_TIMEOUT = 0;
@@ -305,6 +317,8 @@
} else {
throw new UnsupportedOperationException();
}
+
+ mQueue.start(mContext.getContentResolver());
}
@After
@@ -683,12 +697,22 @@
anyInt(), anyInt(), any());
}
- private void verifyScheduleRegisteredReceiver(ProcessRecord app,
+ private void verifyScheduleRegisteredReceiver(ProcessRecord app, Intent intent)
+ throws Exception {
+ verifyScheduleRegisteredReceiver(times(1), app, intent, UserHandle.USER_SYSTEM);
+ }
+
+ private void verifyScheduleRegisteredReceiver(VerificationMode mode, ProcessRecord app,
Intent intent) throws Exception {
- verify(app.getThread()).scheduleRegisteredReceiver(
+ verifyScheduleRegisteredReceiver(mode, app, intent, UserHandle.USER_SYSTEM);
+ }
+
+ private void verifyScheduleRegisteredReceiver(VerificationMode mode, ProcessRecord app,
+ Intent intent, int userId) throws Exception {
+ verify(app.getThread(), mode).scheduleRegisteredReceiver(
any(), argThat(filterEqualsIgnoringComponent(intent)),
anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(),
- eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any());
+ eq(userId), anyInt(), anyInt(), any());
}
private void verifyScheduleRegisteredReceiver(VerificationMode mode, ProcessRecord app,
@@ -1622,6 +1646,79 @@
}
/**
+ * Verify prioritized receivers work as expected with deferrable broadcast - broadcast to
+ * app in cached state should be deferred and the rest should be delivered as per the priority
+ * order.
+ */
+ @Test
+ public void testPrioritized_withDeferrableBroadcasts() throws Exception {
+ // Legacy stack doesn't support deferral
+ Assume.assumeTrue(mImpl == Impl.MODERN);
+
+ final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED);
+ final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN);
+ final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE);
+ final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW);
+ final ProcessRecord receiverOrangeApp = makeActiveProcessRecord(PACKAGE_ORANGE);
+
+ receiverGreenApp.setCached(true);
+ receiverBlueApp.setCached(true);
+
+ final Intent timeTick = new Intent(Intent.ACTION_TIME_TICK);
+ final BroadcastOptions opts = BroadcastOptions.makeBasic()
+ .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
+ final List receivers = List.of(
+ makeRegisteredReceiver(callerApp, 10),
+ makeRegisteredReceiver(receiverGreenApp, 9),
+ makeRegisteredReceiver(receiverBlueApp, 8),
+ makeRegisteredReceiver(receiverYellowApp, 8),
+ makeRegisteredReceiver(receiverOrangeApp, 7)
+ );
+ enqueueBroadcast(makeBroadcastRecord(timeTick, callerApp, opts, receivers));
+ waitForIdle();
+
+ // Green ignored since it's in cached state
+ verifyScheduleRegisteredReceiver(never(), receiverGreenApp, timeTick);
+ // Blue ignored since it's in cached state
+ verifyScheduleRegisteredReceiver(never(), receiverBlueApp, timeTick);
+
+ final IApplicationThread redThread = mAms.getProcessRecordLocked(PACKAGE_RED,
+ getUidForPackage(PACKAGE_RED)).getThread();
+ final IApplicationThread yellowThread = mAms.getProcessRecordLocked(PACKAGE_YELLOW,
+ getUidForPackage(PACKAGE_YELLOW)).getThread();
+ final IApplicationThread orangeThread = mAms.getProcessRecordLocked(PACKAGE_ORANGE,
+ getUidForPackage(PACKAGE_ORANGE)).getThread();
+
+ // Verify apps that are not in cached state will receive the broadcast in the order
+ // we expect.
+ final InOrder inOrder = inOrder(redThread, yellowThread, orangeThread);
+ inOrder.verify(redThread).scheduleRegisteredReceiver(
+ any(), argThat(filterEqualsIgnoringComponent(timeTick)),
+ anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(),
+ eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any());
+ inOrder.verify(yellowThread).scheduleRegisteredReceiver(
+ any(), argThat(filterEqualsIgnoringComponent(timeTick)),
+ anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(),
+ eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any());
+ inOrder.verify(orangeThread).scheduleRegisteredReceiver(
+ any(), argThat(filterEqualsIgnoringComponent(timeTick)),
+ anyInt(), any(), any(), anyBoolean(), anyBoolean(), anyBoolean(),
+ eq(UserHandle.USER_SYSTEM), anyInt(), anyInt(), any());
+
+ // Shift blue to be active and confirm that deferred broadcast is delivered
+ receiverBlueApp.setCached(false);
+ mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_BLUE), false);
+ waitForIdle();
+ verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, timeTick);
+
+ // Shift green to be active and confirm that deferred broadcast is delivered
+ receiverGreenApp.setCached(false);
+ mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), false);
+ waitForIdle();
+ verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, timeTick);
+ }
+
+ /**
* Verify that we handle replacing a pending broadcast.
*/
@Test
@@ -1934,4 +2031,49 @@
getUidForPackage(PACKAGE_ORANGE));
assertNull(receiverOrangeApp);
}
+
+ /**
+ * Verify broadcasts to runtime receivers in cached processes are deferred
+ * until that process leaves the cached state.
+ */
+ @Test
+ public void testDeferralPolicy_UntilActive() throws Exception {
+ // Legacy stack doesn't support deferral
+ Assume.assumeTrue(mImpl == Impl.MODERN);
+
+ final ProcessRecord callerApp = makeActiveProcessRecord(PACKAGE_RED);
+ final ProcessRecord receiverGreenApp = makeActiveProcessRecord(PACKAGE_GREEN);
+ final ProcessRecord receiverBlueApp = makeActiveProcessRecord(PACKAGE_BLUE);
+ final ProcessRecord receiverYellowApp = makeActiveProcessRecord(PACKAGE_YELLOW);
+
+ receiverGreenApp.setCached(true);
+ receiverBlueApp.setCached(true);
+ receiverYellowApp.setCached(false);
+
+ final Intent airplane = new Intent(Intent.ACTION_AIRPLANE_MODE_CHANGED);
+ final BroadcastOptions opts = BroadcastOptions.makeBasic()
+ .setDeferralPolicy(BroadcastOptions.DEFERRAL_POLICY_UNTIL_ACTIVE);
+ enqueueBroadcast(makeBroadcastRecord(airplane, callerApp, opts,
+ List.of(makeRegisteredReceiver(receiverGreenApp),
+ makeRegisteredReceiver(receiverBlueApp),
+ makeManifestReceiver(PACKAGE_BLUE, CLASS_BLUE),
+ makeRegisteredReceiver(receiverYellowApp))));
+ waitForIdle();
+
+ // Green ignored since it's in cached state
+ verifyScheduleRegisteredReceiver(never(), receiverGreenApp, airplane);
+
+ // Blue delivered both since it has a manifest receiver
+ verifyScheduleReceiver(times(1), receiverBlueApp, airplane);
+ verifyScheduleRegisteredReceiver(times(1), receiverBlueApp, airplane);
+
+ // Yellow delivered since it's not cached
+ verifyScheduleRegisteredReceiver(times(1), receiverYellowApp, airplane);
+
+ // Shift green to be active and confirm that deferred broadcast is delivered
+ receiverGreenApp.setCached(false);
+ mUidObserver.onUidCachedChanged(getUidForPackage(PACKAGE_GREEN), false);
+ waitForIdle();
+ verifyScheduleRegisteredReceiver(times(1), receiverGreenApp, airplane);
+ }
}
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
index 1ced95b..51dcc03 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerController2Test.java
@@ -148,6 +148,8 @@
mCdsiMock).when(() -> LocalServices.getService(
ColorDisplayService.ColorDisplayServiceInternal.class));
doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
+ doAnswer((Answer<Boolean>) invocationOnMock -> true).when(() ->
+ Settings.System.putFloatForUser(any(), any(), anyFloat(), anyInt()));
setUpSensors();
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
@@ -287,73 +289,6 @@
eq(mProxSensor), anyInt(), any(Handler.class));
}
- /**
- * Creates a mock and registers it to {@link LocalServices}.
- */
- private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
- LocalServices.removeServiceForTest(clazz);
- LocalServices.addService(clazz, mock);
- }
-
- private void advanceTime(long timeMs) {
- mClock.fastForward(timeMs);
- mTestLooper.dispatchAll();
- }
-
- private void setUpSensors() throws Exception {
- mProxSensor = TestUtils.createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY,
- PROX_SENSOR_MAX_RANGE);
- Sensor screenOffBrightnessSensor = TestUtils.createSensor(
- Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
- when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
- .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor));
- }
-
- private SensorEventListener getSensorEventListener(Sensor sensor) {
- verify(mSensorManagerMock).registerListener(mSensorEventListenerCaptor.capture(),
- eq(sensor), eq(SensorManager.SENSOR_DELAY_NORMAL), isA(Handler.class));
- return mSensorEventListenerCaptor.getValue();
- }
-
- private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
- DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock,
- boolean isEnabled) {
- DisplayInfo info = new DisplayInfo();
- DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
- deviceInfo.uniqueId = uniqueId;
-
- when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
- when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
- when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
- when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
- when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
- when(logicalDisplayMock.getBrightnessThrottlingDataIdLocked()).thenReturn(
- DisplayDeviceConfig.DEFAULT_ID);
- when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
- when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
- when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock);
- when(displayDeviceConfigMock.getProximitySensor()).thenReturn(
- new DisplayDeviceConfig.SensorData() {
- {
- type = Sensor.STRING_TYPE_PROXIMITY;
- name = null;
- }
- });
- when(displayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
- when(displayDeviceConfigMock.isAutoBrightnessAvailable()).thenReturn(true);
- when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
- new DisplayDeviceConfig.SensorData());
- when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
- new DisplayDeviceConfig.SensorData() {
- {
- type = Sensor.STRING_TYPE_LIGHT;
- name = null;
- }
- });
- when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
- .thenReturn(new int[0]);
- }
-
@Test
public void testDisplayBrightnessFollowers_BothDpcsSupportNits() {
DisplayPowerControllerHolder followerDpc =
@@ -482,6 +417,32 @@
verify(followerDpc.animator).animateTo(eq(brightness), anyFloat(), anyFloat());
}
+ @Test
+ public void testDisplayBrightnessFollowers_AutomaticBrightness() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+ final float brightness = 0.4f;
+ final float nits = 300;
+ final float ambientLux = 3000;
+ when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness())
+ .thenReturn(0.3f);
+ when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+ when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ DisplayPowerController followerDpc = mock(DisplayPowerController.class);
+
+ mHolder.dpc.addDisplayBrightnessFollower(followerDpc);
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(followerDpc).setBrightnessToFollow(brightness, nits, ambientLux);
+ }
@Test
public void testDisplayBrightnessFollowersRemoval() {
@@ -750,6 +711,73 @@
verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat());
}
+ /**
+ * Creates a mock and registers it to {@link LocalServices}.
+ */
+ private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
+ LocalServices.removeServiceForTest(clazz);
+ LocalServices.addService(clazz, mock);
+ }
+
+ private void advanceTime(long timeMs) {
+ mClock.fastForward(timeMs);
+ mTestLooper.dispatchAll();
+ }
+
+ private void setUpSensors() throws Exception {
+ mProxSensor = TestUtils.createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY,
+ PROX_SENSOR_MAX_RANGE);
+ Sensor screenOffBrightnessSensor = TestUtils.createSensor(
+ Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
+ when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
+ .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor));
+ }
+
+ private SensorEventListener getSensorEventListener(Sensor sensor) {
+ verify(mSensorManagerMock).registerListener(mSensorEventListenerCaptor.capture(),
+ eq(sensor), eq(SensorManager.SENSOR_DELAY_NORMAL), isA(Handler.class));
+ return mSensorEventListenerCaptor.getValue();
+ }
+
+ private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
+ DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock,
+ boolean isEnabled) {
+ DisplayInfo info = new DisplayInfo();
+ DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
+ deviceInfo.uniqueId = uniqueId;
+
+ when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
+ when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
+ when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
+ when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
+ when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
+ when(logicalDisplayMock.getBrightnessThrottlingDataIdLocked()).thenReturn(
+ DisplayDeviceConfig.DEFAULT_ID);
+ when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
+ when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
+ when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock);
+ when(displayDeviceConfigMock.getProximitySensor()).thenReturn(
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = Sensor.STRING_TYPE_PROXIMITY;
+ name = null;
+ }
+ });
+ when(displayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
+ when(displayDeviceConfigMock.isAutoBrightnessAvailable()).thenReturn(true);
+ when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
+ new DisplayDeviceConfig.SensorData());
+ when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = Sensor.STRING_TYPE_LIGHT;
+ name = null;
+ }
+ });
+ when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
+ .thenReturn(new int[0]);
+ }
+
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
String uniqueId) {
return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true);
diff --git a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
index 53fcdad..0a1bf1c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/display/DisplayPowerControllerTest.java
@@ -149,6 +149,8 @@
mCdsiMock).when(() -> LocalServices.getService(
ColorDisplayService.ColorDisplayServiceInternal.class));
doAnswer((Answer<Void>) invocationOnMock -> null).when(BatteryStatsService::getService);
+ doAnswer((Answer<Boolean>) invocationOnMock -> true).when(() ->
+ Settings.System.putFloatForUser(any(), any(), anyFloat(), anyInt()));
setUpSensors();
mHolder = createDisplayPowerController(DISPLAY_ID, UNIQUE_ID);
@@ -290,73 +292,6 @@
eq(mProxSensor), anyInt(), any(Handler.class));
}
- /**
- * Creates a mock and registers it to {@link LocalServices}.
- */
- private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
- LocalServices.removeServiceForTest(clazz);
- LocalServices.addService(clazz, mock);
- }
-
- private void advanceTime(long timeMs) {
- mClock.fastForward(timeMs);
- mTestLooper.dispatchAll();
- }
-
- private void setUpSensors() throws Exception {
- mProxSensor = TestUtils.createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY,
- PROX_SENSOR_MAX_RANGE);
- Sensor screenOffBrightnessSensor = TestUtils.createSensor(
- Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
- when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
- .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor));
- }
-
- private SensorEventListener getSensorEventListener(Sensor sensor) {
- verify(mSensorManagerMock).registerListener(mSensorEventListenerCaptor.capture(),
- eq(sensor), eq(SensorManager.SENSOR_DELAY_NORMAL), isA(Handler.class));
- return mSensorEventListenerCaptor.getValue();
- }
-
- private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
- DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock,
- boolean isEnabled) {
- DisplayInfo info = new DisplayInfo();
- DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
- deviceInfo.uniqueId = uniqueId;
-
- when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
- when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
- when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
- when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
- when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
- when(logicalDisplayMock.getBrightnessThrottlingDataIdLocked()).thenReturn(
- DisplayDeviceConfig.DEFAULT_ID);
- when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
- when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
- when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock);
- when(displayDeviceConfigMock.getProximitySensor()).thenReturn(
- new DisplayDeviceConfig.SensorData() {
- {
- type = Sensor.STRING_TYPE_PROXIMITY;
- name = null;
- }
- });
- when(displayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
- when(displayDeviceConfigMock.isAutoBrightnessAvailable()).thenReturn(true);
- when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
- new DisplayDeviceConfig.SensorData());
- when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
- new DisplayDeviceConfig.SensorData() {
- {
- type = Sensor.STRING_TYPE_LIGHT;
- name = null;
- }
- });
- when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
- .thenReturn(new int[0]);
- }
-
@Test
public void testDisplayBrightnessFollowers_BothDpcsSupportNits() {
DisplayPowerControllerHolder followerDpc =
@@ -486,6 +421,33 @@
}
@Test
+ public void testDisplayBrightnessFollowers_AutomaticBrightness() {
+ doAnswer((Answer<Integer>) invocationOnMock ->
+ Settings.System.SCREEN_BRIGHTNESS_MODE_AUTOMATIC)
+ .when(() -> Settings.System.getIntForUser(any(ContentResolver.class),
+ eq(Settings.System.SCREEN_BRIGHTNESS_MODE), anyInt(),
+ eq(UserHandle.USER_CURRENT)));
+ final float brightness = 0.4f;
+ final float nits = 300;
+ final float ambientLux = 3000;
+ when(mHolder.automaticBrightnessController.getRawAutomaticScreenBrightness())
+ .thenReturn(brightness);
+ when(mHolder.automaticBrightnessController.getAutomaticScreenBrightness())
+ .thenReturn(0.3f);
+ when(mHolder.automaticBrightnessController.convertToNits(brightness)).thenReturn(nits);
+ when(mHolder.automaticBrightnessController.getAmbientLux()).thenReturn(ambientLux);
+ when(mHolder.displayPowerState.getScreenState()).thenReturn(Display.STATE_ON);
+ DisplayPowerController followerDpc = mock(DisplayPowerController.class);
+
+ mHolder.dpc.addDisplayBrightnessFollower(followerDpc);
+ DisplayPowerRequest dpr = new DisplayPowerRequest();
+ mHolder.dpc.requestPowerState(dpr, /* waitForNegativeProximity= */ false);
+ advanceTime(1); // Run updatePowerState
+
+ verify(followerDpc).setBrightnessToFollow(brightness, nits, ambientLux);
+ }
+
+ @Test
public void testDisplayBrightnessFollowersRemoval() {
DisplayPowerControllerHolder followerHolder =
createDisplayPowerController(FOLLOWER_DISPLAY_ID, FOLLOWER_UNIQUE_DISPLAY_ID);
@@ -517,7 +479,6 @@
verify(followerHolder.animator).animateTo(eq(initialFollowerBrightness),
anyFloat(), anyFloat());
-
mHolder.dpc.addDisplayBrightnessFollower(followerHolder.dpc);
mHolder.dpc.addDisplayBrightnessFollower(secondFollowerHolder.dpc);
clearInvocations(followerHolder.animator);
@@ -754,6 +715,73 @@
verify(mHolder.animator, times(2)).animateTo(eq(newBrightness), anyFloat(), anyFloat());
}
+ /**
+ * Creates a mock and registers it to {@link LocalServices}.
+ */
+ private static <T> void addLocalServiceMock(Class<T> clazz, T mock) {
+ LocalServices.removeServiceForTest(clazz);
+ LocalServices.addService(clazz, mock);
+ }
+
+ private void advanceTime(long timeMs) {
+ mClock.fastForward(timeMs);
+ mTestLooper.dispatchAll();
+ }
+
+ private void setUpSensors() throws Exception {
+ mProxSensor = TestUtils.createSensor(Sensor.TYPE_PROXIMITY, Sensor.STRING_TYPE_PROXIMITY,
+ PROX_SENSOR_MAX_RANGE);
+ Sensor screenOffBrightnessSensor = TestUtils.createSensor(
+ Sensor.TYPE_LIGHT, Sensor.STRING_TYPE_LIGHT);
+ when(mSensorManagerMock.getSensorList(eq(Sensor.TYPE_ALL)))
+ .thenReturn(List.of(mProxSensor, screenOffBrightnessSensor));
+ }
+
+ private SensorEventListener getSensorEventListener(Sensor sensor) {
+ verify(mSensorManagerMock).registerListener(mSensorEventListenerCaptor.capture(),
+ eq(sensor), eq(SensorManager.SENSOR_DELAY_NORMAL), isA(Handler.class));
+ return mSensorEventListenerCaptor.getValue();
+ }
+
+ private void setUpDisplay(int displayId, String uniqueId, LogicalDisplay logicalDisplayMock,
+ DisplayDevice displayDeviceMock, DisplayDeviceConfig displayDeviceConfigMock,
+ boolean isEnabled) {
+ DisplayInfo info = new DisplayInfo();
+ DisplayDeviceInfo deviceInfo = new DisplayDeviceInfo();
+ deviceInfo.uniqueId = uniqueId;
+
+ when(logicalDisplayMock.getDisplayIdLocked()).thenReturn(displayId);
+ when(logicalDisplayMock.getPrimaryDisplayDeviceLocked()).thenReturn(displayDeviceMock);
+ when(logicalDisplayMock.getDisplayInfoLocked()).thenReturn(info);
+ when(logicalDisplayMock.isEnabledLocked()).thenReturn(isEnabled);
+ when(logicalDisplayMock.isInTransitionLocked()).thenReturn(false);
+ when(logicalDisplayMock.getBrightnessThrottlingDataIdLocked()).thenReturn(
+ DisplayDeviceConfig.DEFAULT_ID);
+ when(displayDeviceMock.getDisplayDeviceInfoLocked()).thenReturn(deviceInfo);
+ when(displayDeviceMock.getUniqueId()).thenReturn(uniqueId);
+ when(displayDeviceMock.getDisplayDeviceConfig()).thenReturn(displayDeviceConfigMock);
+ when(displayDeviceConfigMock.getProximitySensor()).thenReturn(
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = Sensor.STRING_TYPE_PROXIMITY;
+ name = null;
+ }
+ });
+ when(displayDeviceConfigMock.getNits()).thenReturn(new float[]{2, 500});
+ when(displayDeviceConfigMock.isAutoBrightnessAvailable()).thenReturn(true);
+ when(displayDeviceConfigMock.getAmbientLightSensor()).thenReturn(
+ new DisplayDeviceConfig.SensorData());
+ when(displayDeviceConfigMock.getScreenOffBrightnessSensor()).thenReturn(
+ new DisplayDeviceConfig.SensorData() {
+ {
+ type = Sensor.STRING_TYPE_LIGHT;
+ name = null;
+ }
+ });
+ when(displayDeviceConfigMock.getScreenOffBrightnessSensorValueToLux())
+ .thenReturn(new int[0]);
+ }
+
private DisplayPowerControllerHolder createDisplayPowerController(int displayId,
String uniqueId) {
return createDisplayPowerController(displayId, uniqueId, /* isEnabled= */ true);
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
index 8b420a3..ba70c584 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/JobSchedulerServiceTest.java
@@ -50,6 +50,7 @@
import android.app.job.JobInfo;
import android.app.job.JobParameters;
import android.app.job.JobScheduler;
+import android.app.job.JobWorkItem;
import android.app.usage.UsageStatsManagerInternal;
import android.content.ComponentName;
import android.content.Context;
@@ -91,6 +92,7 @@
public class JobSchedulerServiceTest {
private static final String TAG = JobSchedulerServiceTest.class.getSimpleName();
+ private static final int TEST_UID = 10123;
private JobSchedulerService mService;
@@ -177,6 +179,9 @@
if (mMockingSession != null) {
mMockingSession.finishMocking();
}
+ mService.cancelJobsForUid(TEST_UID, true,
+ JobParameters.STOP_REASON_UNDEFINED, JobParameters.INTERNAL_STOP_REASON_UNKNOWN,
+ "test cleanup");
}
private Clock getAdvancedClock(Clock clock, long incrementMs) {
@@ -257,9 +262,10 @@
ConnectivityController connectivityController = mService.getConnectivityController();
spyOn(connectivityController);
mService.mConstants.RUNTIME_MIN_GUARANTEE_MS = 10 * MINUTE_IN_MILLIS;
- mService.mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR = 1.5f;
- mService.mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS = HOUR_IN_MILLIS;
- mService.mConstants.RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS = 6 * HOUR_IN_MILLIS;
+ mService.mConstants.RUNTIME_MIN_UI_GUARANTEE_MS = 2 * HOUR_IN_MILLIS;
+ mService.mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR = 1.5f;
+ mService.mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS = HOUR_IN_MILLIS;
+ mService.mConstants.RUNTIME_UI_LIMIT_MS = 6 * HOUR_IN_MILLIS;
assertEquals(mService.mConstants.RUNTIME_MIN_EJ_GUARANTEE_MS,
mService.getMinJobExecutionGuaranteeMs(ejMax));
@@ -278,27 +284,31 @@
// Permission isn't granted, so it should just be treated as a regular job.
assertEquals(mService.mConstants.RUNTIME_MIN_GUARANTEE_MS,
mService.getMinJobExecutionGuaranteeMs(jobUIDT));
+
grantRunUserInitiatedJobsPermission(true); // With permission
- assertEquals(mService.mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS,
- mService.getMinJobExecutionGuaranteeMs(jobUIDT));
+ mService.mConstants.RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS = true;
doReturn(ConnectivityController.UNKNOWN_TIME)
.when(connectivityController).getEstimatedTransferTimeMs(any());
- assertEquals(mService.mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS,
+ assertEquals(mService.mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS,
mService.getMinJobExecutionGuaranteeMs(jobUIDT));
- doReturn(mService.mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS / 2)
+ doReturn(mService.mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS / 2)
.when(connectivityController).getEstimatedTransferTimeMs(any());
- assertEquals(mService.mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS,
+ assertEquals(mService.mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS,
mService.getMinJobExecutionGuaranteeMs(jobUIDT));
- doReturn(mService.mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS * 2)
+ final long estimatedTransferTimeMs =
+ mService.mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_MS * 2;
+ doReturn(estimatedTransferTimeMs)
.when(connectivityController).getEstimatedTransferTimeMs(any());
- assertEquals(
- (long) (mService.mConstants.RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_MS
- * 2 * mService.mConstants
- .RUNTIME_MIN_USER_INITIATED_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR),
+ assertEquals((long) (estimatedTransferTimeMs
+ * mService.mConstants.RUNTIME_MIN_UI_DATA_TRANSFER_GUARANTEE_BUFFER_FACTOR),
mService.getMinJobExecutionGuaranteeMs(jobUIDT));
- doReturn(mService.mConstants.RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS * 2)
+ doReturn(mService.mConstants.RUNTIME_UI_LIMIT_MS * 2)
.when(connectivityController).getEstimatedTransferTimeMs(any());
- assertEquals(mService.mConstants.RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS,
+ assertEquals(mService.mConstants.RUNTIME_UI_LIMIT_MS,
+ mService.getMinJobExecutionGuaranteeMs(jobUIDT));
+
+ mService.mConstants.RUNTIME_USE_DATA_ESTIMATES_FOR_LIMITS = false;
+ assertEquals(mService.mConstants.RUNTIME_MIN_UI_GUARANTEE_MS,
mService.getMinJobExecutionGuaranteeMs(jobUIDT));
}
@@ -320,7 +330,7 @@
.when(quotaController).getMaxJobExecutionTimeMsLocked(any());
grantRunUserInitiatedJobsPermission(true);
- assertEquals(mService.mConstants.RUNTIME_USER_INITIATED_DATA_TRANSFER_LIMIT_MS,
+ assertEquals(mService.mConstants.RUNTIME_UI_LIMIT_MS,
mService.getMaxJobExecutionTimeMs(jobUIDT));
grantRunUserInitiatedJobsPermission(false);
assertEquals(mService.mConstants.RUNTIME_FREE_QUOTA_MAX_LIMIT_MS,
@@ -1170,7 +1180,7 @@
i < 300 ? JobScheduler.RESULT_SUCCESS : JobScheduler.RESULT_FAILURE;
assertEquals("Got unexpected result for schedule #" + (i + 1),
expected,
- mService.scheduleAsPackage(job, null, 10123, null, 0, "JSSTest", ""));
+ mService.scheduleAsPackage(job, null, TEST_UID, null, 0, "JSSTest", ""));
}
}
@@ -1191,7 +1201,7 @@
for (int i = 0; i < 500; ++i) {
assertEquals("Got unexpected result for schedule #" + (i + 1),
JobScheduler.RESULT_SUCCESS,
- mService.scheduleAsPackage(job, null, 10123, null, 0, "JSSTest", ""));
+ mService.scheduleAsPackage(job, null, TEST_UID, null, 0, "JSSTest", ""));
}
}
@@ -1212,7 +1222,7 @@
for (int i = 0; i < 500; ++i) {
assertEquals("Got unexpected result for schedule #" + (i + 1),
JobScheduler.RESULT_SUCCESS,
- mService.scheduleAsPackage(job, null, 10123, "proxied.package", 0, "JSSTest",
+ mService.scheduleAsPackage(job, null, TEST_UID, "proxied.package", 0, "JSSTest",
""));
}
}
@@ -1236,11 +1246,63 @@
i < 300 ? JobScheduler.RESULT_SUCCESS : JobScheduler.RESULT_FAILURE;
assertEquals("Got unexpected result for schedule #" + (i + 1),
expected,
- mService.scheduleAsPackage(job, null, 10123, job.getService().getPackageName(),
+ mService.scheduleAsPackage(job, null, TEST_UID,
+ job.getService().getPackageName(),
0, "JSSTest", ""));
}
}
+ /**
+ * Tests that the number of persisted JobWorkItems is capped.
+ */
+ @Test
+ public void testScheduleLimiting_JobWorkItems_Nonpersisted() {
+ mService.mConstants.MAX_NUM_PERSISTED_JOB_WORK_ITEMS = 500;
+ mService.mConstants.ENABLE_API_QUOTAS = false;
+ mService.mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION = false;
+ mService.mConstants.API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = false;
+ mService.updateQuotaTracker();
+
+ final JobInfo job = createJobInfo().setPersisted(false).build();
+ final JobWorkItem item = new JobWorkItem.Builder().build();
+ for (int i = 0; i < 1000; ++i) {
+ assertEquals("Got unexpected result for schedule #" + (i + 1),
+ JobScheduler.RESULT_SUCCESS,
+ mService.scheduleAsPackage(job, item, TEST_UID,
+ job.getService().getPackageName(),
+ 0, "JSSTest", ""));
+ }
+ }
+
+ /**
+ * Tests that the number of persisted JobWorkItems is capped.
+ */
+ @Test
+ public void testScheduleLimiting_JobWorkItems_Persisted() {
+ mService.mConstants.MAX_NUM_PERSISTED_JOB_WORK_ITEMS = 500;
+ mService.mConstants.ENABLE_API_QUOTAS = false;
+ mService.mConstants.API_QUOTA_SCHEDULE_THROW_EXCEPTION = false;
+ mService.mConstants.API_QUOTA_SCHEDULE_RETURN_FAILURE_RESULT = false;
+ mService.updateQuotaTracker();
+
+ final JobInfo job = createJobInfo().setPersisted(true).build();
+ final JobWorkItem item = new JobWorkItem.Builder().build();
+ for (int i = 0; i < 500; ++i) {
+ assertEquals("Got unexpected result for schedule #" + (i + 1),
+ JobScheduler.RESULT_SUCCESS,
+ mService.scheduleAsPackage(job, item, TEST_UID,
+ job.getService().getPackageName(),
+ 0, "JSSTest", ""));
+ }
+ try {
+ mService.scheduleAsPackage(job, item, TEST_UID, job.getService().getPackageName(),
+ 0, "JSSTest", "");
+ fail("Added more items than allowed");
+ } catch (IllegalStateException expected) {
+ // Success
+ }
+ }
+
/** Tests that jobs are removed from the pending list if the user stops the app. */
@Test
public void testUserStopRemovesPending() {
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
index 32e5c83..a3ae834 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/ConnectivityControllerTest.java
@@ -840,8 +840,9 @@
final JobStatus blue = createJobStatus(createJob()
.setEstimatedNetworkBytes(DataUnit.MEBIBYTES.toBytes(1), 0)
.setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY), UID_BLUE);
+ // Unmetered preference is disabled for now.
assertFalse(red.getPreferUnmetered());
- assertTrue(blue.getPreferUnmetered());
+ assertFalse(blue.getPreferUnmetered());
controller.maybeStartTrackingJobLocked(red, null);
controller.maybeStartTrackingJobLocked(blue, null);
@@ -895,7 +896,7 @@
generalCallback.onLost(meteredNet);
assertTrue(red.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
- assertFalse(red.getHasAccessToUnmetered());
+ assertTrue(red.getHasAccessToUnmetered());
assertTrue(blue.isConstraintSatisfied(JobStatus.CONSTRAINT_CONNECTIVITY));
assertTrue(blue.getHasAccessToUnmetered());
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
index 6bc552c..4b19bbb 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/FlexibilityControllerTest.java
@@ -189,7 +189,10 @@
}
private static JobInfo.Builder createJob(int id) {
- return new JobInfo.Builder(id, new ComponentName("foo", "bar"));
+ return new JobInfo.Builder(id, new ComponentName("foo", "bar"))
+ .setPrefersBatteryNotLow(true)
+ .setPrefersCharging(true)
+ .setPrefersDeviceIdle(true);
}
private JobStatus createJobStatus(String testTag, JobInfo.Builder job) {
@@ -533,12 +536,15 @@
jb = createJob(i);
if (i > 0) {
jb.setRequiresDeviceIdle(true);
+ jb.setPrefersDeviceIdle(false);
}
if (i > 1) {
jb.setRequiresBatteryNotLow(true);
+ jb.setPrefersBatteryNotLow(false);
}
if (i > 2) {
jb.setRequiresCharging(true);
+ jb.setPrefersCharging(false);
}
jobs[i] = createJobStatus("", jb);
flexTracker.add(jobs[i]);
@@ -547,53 +553,55 @@
synchronized (mFlexibilityController.mLock) {
ArrayList<ArraySet<JobStatus>> trackedJobs = flexTracker.getArrayList();
assertEquals(1, trackedJobs.get(0).size());
- assertEquals(0, trackedJobs.get(1).size());
- assertEquals(0, trackedJobs.get(2).size());
- assertEquals(3, trackedJobs.get(3).size());
- assertEquals(0, trackedJobs.get(4).size());
-
- flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME);
- assertEquals(1, trackedJobs.get(0).size());
- assertEquals(0, trackedJobs.get(1).size());
+ assertEquals(1, trackedJobs.get(1).size());
assertEquals(1, trackedJobs.get(2).size());
- assertEquals(2, trackedJobs.get(3).size());
+ assertEquals(1, trackedJobs.get(3).size());
assertEquals(0, trackedJobs.get(4).size());
flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME);
assertEquals(1, trackedJobs.get(0).size());
assertEquals(1, trackedJobs.get(1).size());
- assertEquals(0, trackedJobs.get(2).size());
- assertEquals(2, trackedJobs.get(3).size());
+ assertEquals(2, trackedJobs.get(2).size());
+ assertEquals(0, trackedJobs.get(3).size());
+ assertEquals(0, trackedJobs.get(4).size());
+
+ flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME);
+ assertEquals(1, trackedJobs.get(0).size());
+ assertEquals(2, trackedJobs.get(1).size());
+ assertEquals(1, trackedJobs.get(2).size());
+ assertEquals(0, trackedJobs.get(3).size());
assertEquals(0, trackedJobs.get(4).size());
flexTracker.adjustJobsRequiredConstraints(jobs[0], -1, FROZEN_TIME);
assertEquals(2, trackedJobs.get(0).size());
- assertEquals(0, trackedJobs.get(1).size());
- assertEquals(0, trackedJobs.get(2).size());
- assertEquals(2, trackedJobs.get(3).size());
+ assertEquals(1, trackedJobs.get(1).size());
+ assertEquals(1, trackedJobs.get(2).size());
+ assertEquals(0, trackedJobs.get(3).size());
assertEquals(0, trackedJobs.get(4).size());
flexTracker.remove(jobs[1]);
assertEquals(2, trackedJobs.get(0).size());
- assertEquals(0, trackedJobs.get(1).size());
+ assertEquals(1, trackedJobs.get(1).size());
assertEquals(0, trackedJobs.get(2).size());
- assertEquals(1, trackedJobs.get(3).size());
+ assertEquals(0, trackedJobs.get(3).size());
assertEquals(0, trackedJobs.get(4).size());
flexTracker.resetJobNumDroppedConstraints(jobs[0], FROZEN_TIME);
assertEquals(1, trackedJobs.get(0).size());
- assertEquals(0, trackedJobs.get(1).size());
- assertEquals(0, trackedJobs.get(2).size());
- assertEquals(2, trackedJobs.get(3).size());
- assertEquals(0, trackedJobs.get(4).size());
-
- flexTracker.adjustJobsRequiredConstraints(jobs[0], -2, FROZEN_TIME);
- assertEquals(1, trackedJobs.get(0).size());
assertEquals(1, trackedJobs.get(1).size());
assertEquals(0, trackedJobs.get(2).size());
assertEquals(1, trackedJobs.get(3).size());
assertEquals(0, trackedJobs.get(4).size());
+ flexTracker.adjustJobsRequiredConstraints(jobs[0], -2, FROZEN_TIME);
+ assertEquals(1, trackedJobs.get(0).size());
+ assertEquals(2, trackedJobs.get(1).size());
+ assertEquals(0, trackedJobs.get(2).size());
+ assertEquals(0, trackedJobs.get(3).size());
+ assertEquals(0, trackedJobs.get(4).size());
+
+ // Over halfway through the flex window. The job that prefers all flex constraints
+ // should have its first flex constraint dropped.
final long nowElapsed = ((DEFAULT_FALLBACK_FLEXIBILITY_DEADLINE_MS / 2)
+ HOUR_IN_MILLIS);
JobSchedulerService.sElapsedRealtimeClock =
@@ -601,9 +609,9 @@
flexTracker.resetJobNumDroppedConstraints(jobs[0], nowElapsed);
assertEquals(1, trackedJobs.get(0).size());
- assertEquals(0, trackedJobs.get(1).size());
+ assertEquals(1, trackedJobs.get(1).size());
assertEquals(1, trackedJobs.get(2).size());
- assertEquals(1, trackedJobs.get(3).size());
+ assertEquals(0, trackedJobs.get(3).size());
assertEquals(0, trackedJobs.get(4).size());
}
}
@@ -618,8 +626,13 @@
@Test
public void testExceptions_UserInitiated() {
- JobInfo.Builder jb = createJob(0);
- jb.setUserInitiated(true).setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY);
+ JobInfo.Builder jb = createJob(0)
+ .setUserInitiated(true)
+ .setRequiredNetworkType(JobInfo.NETWORK_TYPE_ANY)
+ // Attempt to add flex constraints to the job. For now, we will ignore them.
+ .setPrefersBatteryNotLow(true)
+ .setPrefersCharging(true)
+ .setPrefersDeviceIdle(false);
JobStatus js = createJobStatus("testExceptions_UserInitiated", jb);
assertFalse(js.hasFlexibilityConstraint());
}
@@ -635,10 +648,10 @@
@Test
public void testExceptions_NoFlexibleConstraints() {
- JobInfo.Builder jb = createJob(0);
- jb.setRequiresDeviceIdle(true);
- jb.setRequiresCharging(true);
- jb.setRequiresBatteryNotLow(true);
+ JobInfo.Builder jb = createJob(0)
+ .setPrefersBatteryNotLow(false)
+ .setPrefersCharging(false)
+ .setPrefersDeviceIdle(false);
JobStatus js = createJobStatus("testExceptions_NoFlexibleConstraints", jb);
assertFalse(js.hasFlexibilityConstraint());
}
@@ -697,15 +710,50 @@
JobStatus js = createJobStatus("testTopAppBypass", jb);
synchronized (mFlexibilityController.mLock) {
js.setHasAccessToUnmetered(false);
- assertEquals(0, mFlexibilityController.getNumSatisfiedRequiredConstraintsLocked(js));
+ assertEquals(0, mFlexibilityController.getNumSatisfiedFlexibleConstraintsLocked(js));
js.setHasAccessToUnmetered(true);
- assertEquals(1, mFlexibilityController.getNumSatisfiedRequiredConstraintsLocked(js));
+ assertEquals(1, mFlexibilityController.getNumSatisfiedFlexibleConstraintsLocked(js));
js.setHasAccessToUnmetered(false);
- assertEquals(0, mFlexibilityController.getNumSatisfiedRequiredConstraintsLocked(js));
+ assertEquals(0, mFlexibilityController.getNumSatisfiedFlexibleConstraintsLocked(js));
}
}
@Test
+ public void testGetNumSatisfiedFlexibleConstraints() {
+ long nowElapsed = FROZEN_TIME;
+ mFlexibilityController.setConstraintSatisfied(CONSTRAINT_BATTERY_NOT_LOW, true, nowElapsed);
+ mFlexibilityController.setConstraintSatisfied(CONSTRAINT_CHARGING, true, nowElapsed);
+ mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, true, nowElapsed);
+ JobInfo.Builder jb = createJob(0)
+ .setPrefersBatteryNotLow(false)
+ .setPrefersCharging(false)
+ .setPrefersDeviceIdle(false);
+ JobStatus js = createJobStatus("testGetNumSatisfiedFlexibleConstraints", jb);
+ assertEquals(0, mFlexibilityController.getNumSatisfiedFlexibleConstraintsLocked(js));
+
+ jb = createJob(0)
+ .setPrefersBatteryNotLow(true)
+ .setPrefersCharging(false)
+ .setPrefersDeviceIdle(false);
+ js = createJobStatus("testGetNumSatisfiedFlexibleConstraints", jb);
+ assertEquals(1, mFlexibilityController.getNumSatisfiedFlexibleConstraintsLocked(js));
+
+ jb = createJob(0)
+ .setPrefersBatteryNotLow(true)
+ .setPrefersCharging(false)
+ .setPrefersDeviceIdle(true);
+ js = createJobStatus("testGetNumSatisfiedFlexibleConstraints", jb);
+ assertEquals(2, mFlexibilityController.getNumSatisfiedFlexibleConstraintsLocked(js));
+
+ jb = createJob(0)
+ .setPrefersBatteryNotLow(true)
+ .setPrefersCharging(true)
+ .setPrefersDeviceIdle(true);
+ js = createJobStatus("testGetNumSatisfiedFlexibleConstraints", jb);
+ assertEquals(3, mFlexibilityController.getNumSatisfiedFlexibleConstraintsLocked(js));
+ }
+
+ @Test
public void testSetConstraintSatisfied_Constraints() {
mFlexibilityController.setConstraintSatisfied(CONSTRAINT_IDLE, false, FROZEN_TIME);
assertFalse(mFlexibilityController.isConstraintSatisfied(CONSTRAINT_IDLE));
@@ -736,8 +784,11 @@
jb = createJob(i);
constraints = constraintCombinations[i];
jb.setRequiresDeviceIdle((constraints & CONSTRAINT_IDLE) != 0);
+ jb.setPrefersDeviceIdle((constraints & CONSTRAINT_IDLE) == 0);
jb.setRequiresBatteryNotLow((constraints & CONSTRAINT_BATTERY_NOT_LOW) != 0);
+ jb.setPrefersBatteryNotLow((constraints & CONSTRAINT_BATTERY_NOT_LOW) == 0);
jb.setRequiresCharging((constraints & CONSTRAINT_CHARGING) != 0);
+ jb.setPrefersCharging((constraints & CONSTRAINT_CHARGING) == 0);
synchronized (mFlexibilityController.mLock) {
mFlexibilityController.maybeStartTrackingJobLocked(
createJobStatus(String.valueOf(i), jb), null);
diff --git a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
index 5dc8ed5..b076ab4 100644
--- a/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/job/controllers/JobStatusTest.java
@@ -1039,7 +1039,9 @@
@Test
public void testReadinessStatusWithConstraint_FlexibilityConstraint() {
final JobStatus job = createJobStatus(
- new JobInfo.Builder(101, new ComponentName("foo", "bar")).build());
+ new JobInfo.Builder(101, new ComponentName("foo", "bar"))
+ .setPrefersCharging(true)
+ .build());
job.setConstraintSatisfied(CONSTRAINT_FLEXIBLE, sElapsedRealtimeClock.millis(), false);
markImplicitConstraintsSatisfied(job, true);
assertTrue(job.readinessStatusWithConstraint(CONSTRAINT_FLEXIBLE, true));
diff --git a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
index 70b5ac0..386fd3e 100644
--- a/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
+++ b/services/tests/mockingservicestests/src/com/android/server/pm/UserVisibilityMediatorTestCase.java
@@ -674,13 +674,13 @@
}
protected void expectDisplayAssignedToUser(@UserIdInt int userId, int displayId) {
- expectWithMessage("getDisplayAssignedToUser(%s)", userId)
- .that(mMediator.getDisplayAssignedToUser(userId)).isEqualTo(displayId);
+ expectWithMessage("getMainDisplayAssignedToUser(%s)", userId)
+ .that(mMediator.getMainDisplayAssignedToUser(userId)).isEqualTo(displayId);
}
protected void expectNoDisplayAssignedToUser(@UserIdInt int userId) {
- expectWithMessage("getDisplayAssignedToUser(%s)", userId)
- .that(mMediator.getDisplayAssignedToUser(userId)).isEqualTo(INVALID_DISPLAY);
+ expectWithMessage("getMainDisplayAssignedToUser(%s)", userId)
+ .that(mMediator.getMainDisplayAssignedToUser(userId)).isEqualTo(INVALID_DISPLAY);
}
protected void expectDisplaysAssignedToUserContainsDisplayId(
diff --git a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
index 71280ce..e81b63c 100644
--- a/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
+++ b/services/tests/mockingservicestests/src/com/android/server/tare/ScribeTest.java
@@ -403,6 +403,7 @@
ApplicationInfo applicationInfo = new ApplicationInfo();
applicationInfo.uid = UserHandle.getUid(userId, Math.abs(pkgName.hashCode()));
pkgInfo.applicationInfo = applicationInfo;
- mInstalledPackages.add(userId, pkgName, new InstalledPackageInfo(getContext(), pkgInfo));
+ mInstalledPackages.add(userId, pkgName, new InstalledPackageInfo(getContext(), userId,
+ pkgInfo));
}
}
diff --git a/services/tests/servicestests/Android.bp b/services/tests/servicestests/Android.bp
index 5f3b975..627e9d7 100644
--- a/services/tests/servicestests/Android.bp
+++ b/services/tests/servicestests/Android.bp
@@ -36,7 +36,7 @@
"services.net",
"services.people",
"services.usage",
- "service-permission.impl",
+ "service-permission.stubs.system_server",
"guava",
"guava-android-testlib",
"androidx.test.core",
diff --git a/services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java b/services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java
index 8f07238..3ad24de 100644
--- a/services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java
+++ b/services/tests/servicestests/src/com/android/server/audio/SpatializerHelperTest.java
@@ -80,7 +80,9 @@
asAdapter = mMockAudioSystem;
}
mSpatHelper = new SpatializerHelper(mMockAudioService, asAdapter,
- false /*headTrackingEnabledByDefault*/);
+ true /*binauralEnabledDefault*/,
+ true /*transauralEnabledDefault*/,
+ false /*headTrackingEnabledDefault*/);
}
diff --git a/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java
new file mode 100644
index 0000000..5adf391
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/biometrics/log/BiometricFrameworkStatsLoggerTest.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.biometrics.log;
+
+import static com.google.common.truth.Truth.assertThat;
+
+import android.hardware.biometrics.BiometricsProtoEnums;
+import android.hardware.biometrics.common.AuthenticateReason;
+import android.hardware.biometrics.common.OperationContext;
+import android.hardware.biometrics.common.WakeReason;
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+
+@Presubmit
+@SmallTest
+public class BiometricFrameworkStatsLoggerTest {
+
+ @Test
+ public void testConvertsWakeReason_whenEmpty() {
+ final OperationContextExt ctx = new OperationContextExt();
+
+ final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
+ final int[] reasonDetails = BiometricFrameworkStatsLogger
+ .toProtoWakeReasonDetails(ctx);
+
+ assertThat(reason).isEqualTo(BiometricsProtoEnums.WAKE_REASON_UNKNOWN);
+ assertThat(reasonDetails).isEmpty();
+ }
+
+ @Test
+ public void testConvertsWakeReason_whenPowerReason() {
+ final OperationContext context = new OperationContext();
+ context.wakeReason = WakeReason.WAKE_MOTION;
+ final OperationContextExt ctx = new OperationContextExt(context);
+
+ final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
+ final int[] reasonDetails = BiometricFrameworkStatsLogger
+ .toProtoWakeReasonDetails(new OperationContextExt(context));
+
+ assertThat(reason).isEqualTo(BiometricsProtoEnums.WAKE_REASON_WAKE_MOTION);
+ assertThat(reasonDetails).isEmpty();
+ }
+
+ @Test
+ public void testConvertsWakeReason_whenFaceReason() {
+ final OperationContext context = new OperationContext();
+ context.authenticateReason = AuthenticateReason.faceAuthenticateReason(
+ AuthenticateReason.Face.ASSISTANT_VISIBLE);
+ final OperationContextExt ctx = new OperationContextExt(context);
+
+ final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
+ final int[] reasonDetails = BiometricFrameworkStatsLogger
+ .toProtoWakeReasonDetails(ctx);
+
+ assertThat(reason).isEqualTo(BiometricsProtoEnums.WAKE_REASON_UNKNOWN);
+ assertThat(reasonDetails).asList().containsExactly(
+ BiometricsProtoEnums.DETAILS_FACE_ASSISTANT_VISIBLE);
+ }
+
+ @Test
+ public void testConvertsWakeReason_whenVendorReason() {
+ final OperationContext context = new OperationContext();
+ context.authenticateReason = AuthenticateReason.vendorAuthenticateReason(
+ new AuthenticateReason.Vendor());
+ final OperationContextExt ctx = new OperationContextExt(context);
+
+ final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
+ final int[] reasonDetails = BiometricFrameworkStatsLogger
+ .toProtoWakeReasonDetails(ctx);
+
+ assertThat(reason).isEqualTo(BiometricsProtoEnums.WAKE_REASON_UNKNOWN);
+ assertThat(reasonDetails).isEmpty();
+ }
+
+
+ @Test
+ public void testConvertsWakeReason_whenPowerAndFaceReason() {
+ final OperationContext context = new OperationContext();
+ context.wakeReason = WakeReason.WAKE_KEY;
+ context.authenticateReason = AuthenticateReason.faceAuthenticateReason(
+ AuthenticateReason.Face.PRIMARY_BOUNCER_SHOWN);
+ final OperationContextExt ctx = new OperationContextExt(context);
+
+ final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
+ final int[] reasonDetails = BiometricFrameworkStatsLogger
+ .toProtoWakeReasonDetails(ctx);
+
+ assertThat(reason).isEqualTo(BiometricsProtoEnums.WAKE_REASON_WAKE_KEY);
+ assertThat(reasonDetails).asList().containsExactly(
+ BiometricsProtoEnums.DETAILS_FACE_PRIMARY_BOUNCER_SHOWN);
+ }
+
+ @Test
+ public void testConvertsWakeReason_whenPowerAndVendorReason() {
+ final OperationContext context = new OperationContext();
+ context.wakeReason = WakeReason.LID;
+ context.authenticateReason = AuthenticateReason.vendorAuthenticateReason(
+ new AuthenticateReason.Vendor());
+ final OperationContextExt ctx = new OperationContextExt(context);
+
+ final int reason = BiometricFrameworkStatsLogger.toProtoWakeReason(ctx);
+ final int[] reasonDetails = BiometricFrameworkStatsLogger
+ .toProtoWakeReasonDetails(ctx);
+
+ assertThat(reason).isEqualTo(BiometricsProtoEnums.WAKE_REASON_LID);
+ assertThat(reasonDetails).isEmpty();
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
index aaabb28..4f74ef8 100644
--- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java
@@ -5002,6 +5002,8 @@
configureProfileOwnerOfOrgOwnedDevice(admin1, CALLER_USER_HANDLE);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "true", false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+ FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "true", false);
// Even if the caller is the managed profile, the current user is the user 0
when(getServices().iactivityManager.getCurrentUser())
.thenReturn(new UserInfo(UserHandle.USER_SYSTEM, "user system", 0));
@@ -5064,6 +5066,8 @@
verify(getServices().subscriptionManager).setSubscriptionUserHandle(0, null);
DeviceConfig.setProperty(DeviceConfig.NAMESPACE_DEVICE_POLICY_MANAGER,
FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "false", false);
+ DeviceConfig.setProperty(DeviceConfig.NAMESPACE_TELEPHONY,
+ FLAG_ENABLE_WORK_PROFILE_TELEPHONY, "false", false);
}
@Test
diff --git a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java
index 8196d6a..e396263 100644
--- a/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java
+++ b/services/tests/servicestests/src/com/android/server/devicestate/DeviceStateNotificationControllerTest.java
@@ -52,7 +52,7 @@
private static final int STATE_WITHOUT_NOTIFICATION = 1;
private static final int STATE_WITH_ACTIVE_NOTIFICATION = 2;
- private static final int STATE_WITH_ACTIVE_AND_THERMAL_NOTIFICATION = 3;
+ private static final int STATE_WITH_ALL_NOTIFICATION = 3;
private static final int VALID_APP_UID = 1000;
private static final int INVALID_APP_UID = 2000;
@@ -68,6 +68,8 @@
private static final String CONTENT_2 = "content2:%1$s";
private static final String THERMAL_TITLE_2 = "thermal_title2";
private static final String THERMAL_CONTENT_2 = "thermal_content2";
+ private static final String POWER_SAVE_TITLE_2 = "power_save_title2";
+ private static final String POWER_SAVE_CONTENT_2 = "power_save_content2";
private DeviceStateNotificationController mController;
@@ -88,11 +90,12 @@
notificationInfos.put(STATE_WITH_ACTIVE_NOTIFICATION,
new DeviceStateNotificationController.NotificationInfo(
NAME_1, TITLE_1, CONTENT_1,
- "", ""));
- notificationInfos.put(STATE_WITH_ACTIVE_AND_THERMAL_NOTIFICATION,
+ "", "", "", ""));
+ notificationInfos.put(STATE_WITH_ALL_NOTIFICATION,
new DeviceStateNotificationController.NotificationInfo(
NAME_2, TITLE_2, CONTENT_2,
- THERMAL_TITLE_2, THERMAL_CONTENT_2));
+ THERMAL_TITLE_2, THERMAL_CONTENT_2,
+ POWER_SAVE_TITLE_2, POWER_SAVE_CONTENT_2));
when(packageManager.getNameForUid(VALID_APP_UID)).thenReturn(VALID_APP_NAME);
when(packageManager.getNameForUid(INVALID_APP_UID)).thenReturn(INVALID_APP_NAME);
@@ -139,10 +142,46 @@
}
@Test
+ public void test_powerSaveNotification() {
+ // Verify that the active notification is created.
+ mController.showStateActiveNotificationIfNeeded(
+ STATE_WITH_ALL_NOTIFICATION, VALID_APP_UID);
+ verify(mNotificationManager).notify(
+ eq(DeviceStateNotificationController.NOTIFICATION_TAG),
+ eq(DeviceStateNotificationController.NOTIFICATION_ID),
+ mNotificationCaptor.capture());
+ Notification notification = mNotificationCaptor.getValue();
+ assertEquals(TITLE_2, notification.extras.getString(Notification.EXTRA_TITLE));
+ assertEquals(String.format(CONTENT_2, VALID_APP_LABEL),
+ notification.extras.getString(Notification.EXTRA_TEXT));
+ assertEquals(Notification.FLAG_ONGOING_EVENT,
+ notification.flags & Notification.FLAG_ONGOING_EVENT);
+ Mockito.clearInvocations(mNotificationManager);
+
+ // Verify that the thermal critical notification is created.
+ mController.showPowerSaveNotificationIfNeeded(
+ STATE_WITH_ALL_NOTIFICATION);
+ verify(mNotificationManager).notify(
+ eq(DeviceStateNotificationController.NOTIFICATION_TAG),
+ eq(DeviceStateNotificationController.NOTIFICATION_ID),
+ mNotificationCaptor.capture());
+ notification = mNotificationCaptor.getValue();
+ assertEquals(POWER_SAVE_TITLE_2, notification.extras.getString(Notification.EXTRA_TITLE));
+ assertEquals(POWER_SAVE_CONTENT_2, notification.extras.getString(Notification.EXTRA_TEXT));
+ assertEquals(0, notification.flags & Notification.FLAG_ONGOING_EVENT);
+
+ // Verify that the notification is canceled.
+ mController.cancelNotification(STATE_WITH_ALL_NOTIFICATION);
+ verify(mNotificationManager).cancel(
+ DeviceStateNotificationController.NOTIFICATION_TAG,
+ DeviceStateNotificationController.NOTIFICATION_ID);
+ }
+
+ @Test
public void test_thermalNotification() {
// Verify that the active notification is created.
mController.showStateActiveNotificationIfNeeded(
- STATE_WITH_ACTIVE_AND_THERMAL_NOTIFICATION, VALID_APP_UID);
+ STATE_WITH_ALL_NOTIFICATION, VALID_APP_UID);
verify(mNotificationManager).notify(
eq(DeviceStateNotificationController.NOTIFICATION_TAG),
eq(DeviceStateNotificationController.NOTIFICATION_ID),
@@ -157,7 +196,7 @@
// Verify that the thermal critical notification is created.
mController.showThermalCriticalNotificationIfNeeded(
- STATE_WITH_ACTIVE_AND_THERMAL_NOTIFICATION);
+ STATE_WITH_ALL_NOTIFICATION);
verify(mNotificationManager).notify(
eq(DeviceStateNotificationController.NOTIFICATION_TAG),
eq(DeviceStateNotificationController.NOTIFICATION_ID),
@@ -168,7 +207,7 @@
assertEquals(0, notification.flags & Notification.FLAG_ONGOING_EVENT);
// Verify that the notification is canceled.
- mController.cancelNotification(STATE_WITH_ACTIVE_NOTIFICATION);
+ mController.cancelNotification(STATE_WITH_ALL_NOTIFICATION);
verify(mNotificationManager).cancel(
DeviceStateNotificationController.NOTIFICATION_TAG,
DeviceStateNotificationController.NOTIFICATION_ID);
diff --git a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
index 94d30bb..6d2ce7f 100644
--- a/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/DisplayManagerServiceTest.java
@@ -34,7 +34,9 @@
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import static org.mockito.ArgumentMatchers.anyLong;
+import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.any;
+import static org.mockito.Mockito.atLeastOnce;
import static org.mockito.Mockito.doReturn;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
@@ -65,12 +67,14 @@
import android.hardware.display.IDisplayManagerCallback;
import android.hardware.display.IVirtualDisplayCallback;
import android.hardware.display.VirtualDisplayConfig;
+import android.media.projection.IMediaProjection;
import android.media.projection.IMediaProjectionManager;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.os.MessageQueue;
import android.os.Process;
+import android.os.RemoteException;
import android.view.ContentRecordingSession;
import android.view.Display;
import android.view.DisplayCutout;
@@ -1024,11 +1028,14 @@
}
@Test
- public void testCreateVirtualDisplay_setContentRecordingSessionSuccess() throws Exception {
+ public void testCreateVirtualDisplay_setContentRecordingSessionSuccess()
+ throws RemoteException {
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
when(mMockWindowManagerInternal
.setContentRecordingSession(any(ContentRecordingSession.class)))
.thenReturn(true);
+ IMediaProjection projection = mock(IMediaProjection.class);
+ doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection));
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
VIRTUAL_DISPLAY_NAME, 600, 800, 320);
@@ -1042,17 +1049,19 @@
DisplayManagerService.BinderService binderService = displayManager.new BinderService();
final int displayId = binderService.createVirtualDisplay(builder.build(),
- mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
+ mMockAppToken /* callback */, projection, PACKAGE_NAME);
assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY);
}
@Test
- public void testCreateVirtualDisplay_setContentRecordingSessionFail() throws Exception {
+ public void testCreateVirtualDisplay_setContentRecordingSessionFail() throws RemoteException {
when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
when(mMockWindowManagerInternal
.setContentRecordingSession(any(ContentRecordingSession.class)))
.thenReturn(false);
+ IMediaProjection projection = mock(IMediaProjection.class);
+ doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection));
final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
VIRTUAL_DISPLAY_NAME, 600, 800, 320);
@@ -1066,11 +1075,96 @@
DisplayManagerService.BinderService binderService = displayManager.new BinderService();
final int displayId = binderService.createVirtualDisplay(builder.build(),
- mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
+ mMockAppToken /* callback */, projection, PACKAGE_NAME);
assertThat(displayId).isEqualTo(Display.INVALID_DISPLAY);
}
+ @Test
+ public void testCreateVirtualDisplay_setContentRecordingSession_noProjection_noFlags() {
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+
+ // Set no flags for the VirtualDisplay.
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, 600, 800, 320);
+ builder.setUniqueId("uniqueId --- setContentRecordingSession false");
+ builder.setContentRecordingSession(
+ ContentRecordingSession.createDisplaySession(new Binder("")));
+
+ DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+ displayManager.windowManagerAndInputReady();
+
+ // Pass in a null projection.
+ DisplayManagerService.BinderService binderService = displayManager.new BinderService();
+ final int displayId = binderService.createVirtualDisplay(builder.build(),
+ mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
+
+ // VirtualDisplay is created but not for mirroring.
+ assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY);
+ verify(mMockWindowManagerInternal, never()).setContentRecordingSession(
+ any(ContentRecordingSession.class));
+ }
+
+ @Test
+ public void testCreateVirtualDisplay_setContentRecordingSession_noProjection_noMirroringFlag() {
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+
+ // Set a non-mirroring flag for the VirtualDisplay.
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, 600, 800, 320);
+ builder.setUniqueId("uniqueId --- setContentRecordingSession false");
+ builder.setFlags(VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY);
+ builder.setContentRecordingSession(
+ ContentRecordingSession.createDisplaySession(new Binder("")));
+
+ DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+ displayManager.windowManagerAndInputReady();
+
+ // Pass in a null projection.
+ DisplayManagerService.BinderService binderService = displayManager.new BinderService();
+ final int displayId = binderService.createVirtualDisplay(builder.build(),
+ mMockAppToken /* callback */, null /* projection */, PACKAGE_NAME);
+
+ // VirtualDisplay is created but not for mirroring.
+ assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY);
+ verify(mMockWindowManagerInternal, never()).setContentRecordingSession(
+ any(ContentRecordingSession.class));
+ }
+
+ @Test
+ public void testCreateVirtualDisplay_setContentRecordingSession_projection_noMirroringFlag()
+ throws RemoteException {
+ when(mMockAppToken.asBinder()).thenReturn(mMockAppToken);
+ when(mMockWindowManagerInternal
+ .setContentRecordingSession(any(ContentRecordingSession.class)))
+ .thenReturn(true);
+ IMediaProjection projection = mock(IMediaProjection.class);
+ doReturn(true).when(mMockProjectionService).isCurrentProjection(eq(projection));
+
+ // Set no flags for the VirtualDisplay.
+ final VirtualDisplayConfig.Builder builder = new VirtualDisplayConfig.Builder(
+ VIRTUAL_DISPLAY_NAME, 600, 800, 320);
+ builder.setUniqueId("uniqueId --- setContentRecordingSession false");
+ builder.setContentRecordingSession(
+ ContentRecordingSession.createDisplaySession(new Binder("")));
+
+ DisplayManagerService displayManager = new DisplayManagerService(mContext, mBasicInjector);
+ registerDefaultDisplays(displayManager);
+ displayManager.windowManagerAndInputReady();
+
+ // Pass in a non-null projection.
+ DisplayManagerService.BinderService binderService = displayManager.new BinderService();
+ final int displayId = binderService.createVirtualDisplay(builder.build(),
+ mMockAppToken /* callback */, projection, PACKAGE_NAME);
+
+ // VirtualDisplay is created for mirroring.
+ assertThat(displayId).isNotEqualTo(Display.INVALID_DISPLAY);
+ verify(mMockWindowManagerInternal, atLeastOnce()).setContentRecordingSession(
+ any(ContentRecordingSession.class));
+ }
+
/**
* Tests that the virtual display is created with
* {@link VirtualDisplayConfig.Builder#setSurface(Surface)}
diff --git a/services/tests/servicestests/src/com/android/server/display/mode/DisplayModeDirectorTest.java b/services/tests/servicestests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
index 1b02799..db5a469 100644
--- a/services/tests/servicestests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
+++ b/services/tests/servicestests/src/com/android/server/display/mode/DisplayModeDirectorTest.java
@@ -2300,7 +2300,7 @@
// We don't expect any interaction with DeviceConfig when the director is initialized
// because we explicitly avoid doing this as this can lead to a latency spike in the
// startup of DisplayManagerService
- // Verify all the loaded values are from DisplayDeviceConfig
+ // Verify all the loaded values are from config.xml
assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 45, 0.0);
assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 75,
0.0);
@@ -2332,6 +2332,7 @@
when(displayDeviceConfig.getDefaultRefreshRateInHbmSunlight()).thenReturn(75);
director.defaultDisplayDeviceUpdated(displayDeviceConfig);
+ // Verify the new values are from the freshly loaded DisplayDeviceConfig.
assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 65,
0.0);
@@ -2362,6 +2363,7 @@
// Need to wait for the property change to propagate to the main thread.
waitForIdleSync();
+ // Verify the values are loaded from the DeviceConfig.
assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 60,
0.0);
@@ -2377,6 +2379,35 @@
new int[]{20});
assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 70);
assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 80);
+
+ // Reset the DeviceConfig
+ config.setDefaultPeakRefreshRate(null);
+ config.setRefreshRateInHighZone(null);
+ config.setRefreshRateInLowZone(null);
+ config.setLowAmbientBrightnessThresholds(new int[]{});
+ config.setLowDisplayBrightnessThresholds(new int[]{});
+ config.setHighDisplayBrightnessThresholds(new int[]{});
+ config.setHighAmbientBrightnessThresholds(new int[]{});
+ config.setRefreshRateInHbmHdr(null);
+ config.setRefreshRateInHbmSunlight(null);
+ waitForIdleSync();
+
+ // verify the new values now fallback to DisplayDeviceConfig
+ assertEquals(director.getSettingsObserver().getDefaultRefreshRate(), 60, 0.0);
+ assertEquals(director.getSettingsObserver().getDefaultPeakRefreshRate(), 65,
+ 0.0);
+ assertEquals(director.getBrightnessObserver().getRefreshRateInHighZone(), 55);
+ assertEquals(director.getBrightnessObserver().getRefreshRateInLowZone(), 50);
+ assertArrayEquals(director.getBrightnessObserver().getHighDisplayBrightnessThreshold(),
+ new int[]{210});
+ assertArrayEquals(director.getBrightnessObserver().getHighAmbientBrightnessThreshold(),
+ new int[]{2100});
+ assertArrayEquals(director.getBrightnessObserver().getLowDisplayBrightnessThreshold(),
+ new int[]{25});
+ assertArrayEquals(director.getBrightnessObserver().getLowAmbientBrightnessThreshold(),
+ new int[]{30});
+ assertEquals(director.getHbmObserver().getRefreshRateInHbmHdr(), 65);
+ assertEquals(director.getHbmObserver().getRefreshRateInHbmSunlight(), 75);
}
@Test
@@ -2536,18 +2567,18 @@
super.addOnPropertiesChangedListener(namespace, executor, listener);
}
- void setRefreshRateInLowZone(int fps) {
+ void setRefreshRateInLowZone(Integer fps) {
putPropertyAndNotify(
DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_REFRESH_RATE_IN_LOW_ZONE,
String.valueOf(fps));
}
- void setRefreshRateInHbmSunlight(int fps) {
+ void setRefreshRateInHbmSunlight(Integer fps) {
putPropertyAndNotify(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
KEY_REFRESH_RATE_IN_HBM_SUNLIGHT, String.valueOf(fps));
}
- void setRefreshRateInHbmHdr(int fps) {
+ void setRefreshRateInHbmHdr(Integer fps) {
putPropertyAndNotify(DeviceConfig.NAMESPACE_DISPLAY_MANAGER,
KEY_REFRESH_RATE_IN_HBM_HDR, String.valueOf(fps));
}
@@ -2583,13 +2614,13 @@
thresholds);
}
- void setRefreshRateInHighZone(int fps) {
+ void setRefreshRateInHighZone(Integer fps) {
putPropertyAndNotify(
DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_REFRESH_RATE_IN_HIGH_ZONE,
String.valueOf(fps));
}
- void setDefaultPeakRefreshRate(int fps) {
+ void setDefaultPeakRefreshRate(Integer fps) {
putPropertyAndNotify(
DeviceConfig.NAMESPACE_DISPLAY_MANAGER, KEY_PEAK_REFRESH_RATE_DEFAULT,
String.valueOf(fps));
diff --git a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
index 5560b41..236c74f 100644
--- a/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
+++ b/services/tests/servicestests/src/com/android/server/job/JobStoreTest.java
@@ -728,6 +728,66 @@
}
@Test
+ public void testPersistedPreferredBatteryNotLowConstraint() throws Exception {
+ JobInfo.Builder b = new Builder(8, mComponent)
+ .setPrefersBatteryNotLow(true)
+ .setPersisted(true);
+ JobStatus taskStatus =
+ JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null, null);
+
+ mTaskStoreUnderTest.add(taskStatus);
+ waitForPendingIo();
+
+ final JobSet jobStatusSet = new JobSet();
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
+ assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
+ JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
+ assertEquals("Battery-not-low constraint not persisted correctly.",
+ taskStatus.getJob().isPreferBatteryNotLow(),
+ loaded.getJob().isPreferBatteryNotLow());
+ }
+
+ @Test
+ public void testPersistedPreferredChargingConstraint() throws Exception {
+ JobInfo.Builder b = new Builder(8, mComponent)
+ .setPrefersCharging(true)
+ .setPersisted(true);
+ JobStatus taskStatus =
+ JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null, null);
+
+ mTaskStoreUnderTest.add(taskStatus);
+ waitForPendingIo();
+
+ final JobSet jobStatusSet = new JobSet();
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
+ assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
+ JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
+ assertEquals("Charging constraint not persisted correctly.",
+ taskStatus.getJob().isPreferCharging(),
+ loaded.getJob().isPreferCharging());
+ }
+
+ @Test
+ public void testPersistedPreferredDeviceIdleConstraint() throws Exception {
+ JobInfo.Builder b = new Builder(8, mComponent)
+ .setPrefersDeviceIdle(true)
+ .setPersisted(true);
+ JobStatus taskStatus =
+ JobStatus.createFromJobInfo(b.build(), SOME_UID, null, -1, null, null);
+
+ mTaskStoreUnderTest.add(taskStatus);
+ waitForPendingIo();
+
+ final JobSet jobStatusSet = new JobSet();
+ mTaskStoreUnderTest.readJobMapFromDisk(jobStatusSet, true);
+ assertEquals("Incorrect # of persisted tasks.", 1, jobStatusSet.size());
+ JobStatus loaded = jobStatusSet.getAllJobs().iterator().next();
+ assertEquals("Idle constraint not persisted correctly.",
+ taskStatus.getJob().isPreferDeviceIdle(),
+ loaded.getJob().isPreferDeviceIdle());
+ }
+
+ @Test
public void testJobWorkItems() throws Exception {
JobWorkItem item1 = new JobWorkItem.Builder().build();
item1.bumpDeliveryCount();
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 7125796..7e40f96 100644
--- a/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java
+++ b/services/tests/servicestests/src/com/android/server/policy/DeviceStateProviderImplTest.java
@@ -20,6 +20,8 @@
import static android.content.Context.SENSOR_SERVICE;
import static com.android.server.devicestate.DeviceStateProvider.SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED;
+import static com.android.server.devicestate.DeviceStateProvider.SUPPORTED_DEVICE_STATES_CHANGED_POWER_SAVE_DISABLED;
+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.DeviceStateProviderImpl.DEFAULT_DEVICE_STATE;
@@ -327,7 +329,8 @@
+ " <name>THERMAL_TEST</name>\n"
+ " <flags>\n"
+ " <flag>FLAG_EMULATED_ONLY</flag>\n"
- + " <flag>FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL</flag>\n"
+ + " <flag>FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL</flag>\n"
+ + " <flag>FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE</flag>\n"
+ " </flags>\n"
+ " </device-state>\n"
+ "</device-state-config>\n";
@@ -354,7 +357,8 @@
new DeviceState(3, "OPENED", 0 /* flags */),
new DeviceState(4, "THERMAL_TEST",
DeviceState.FLAG_EMULATED_ONLY
- | DeviceState.FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL) },
+ | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL
+ | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) },
mDeviceStateArrayCaptor.getValue());
// onStateChanged() should not be called because the provider has not yet been notified of
// the initial sensor state.
@@ -419,7 +423,8 @@
new DeviceState(3, "OPENED", 0 /* flags */),
new DeviceState(4, "THERMAL_TEST",
DeviceState.FLAG_EMULATED_ONLY
- | DeviceState.FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL) },
+ | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL
+ | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) },
mDeviceStateArrayCaptor.getValue());
Mockito.clearInvocations(listener);
@@ -451,7 +456,65 @@
new DeviceState(3, "OPENED", 0 /* flags */),
new DeviceState(4, "THERMAL_TEST",
DeviceState.FLAG_EMULATED_ONLY
- | DeviceState.FLAG_DISABLE_WHEN_THERMAL_STATUS_CRITICAL) },
+ | DeviceState.FLAG_UNSUPPORTED_WHEN_THERMAL_STATUS_CRITICAL
+ | DeviceState.FLAG_UNSUPPORTED_WHEN_POWER_SAVE_MODE) },
+ mDeviceStateArrayCaptor.getValue());
+ }
+
+ @Test
+ public void test_flagDisableWhenPowerSaveEnabled() throws Exception {
+ Sensor sensor = newSensor("sensor", Sensor.STRING_TYPE_HINGE_ANGLE);
+ when(mSensorManager.getSensorList(anyInt())).thenReturn(List.of(sensor));
+ DeviceStateProviderImpl provider = create_sensorBasedProvider(sensor);
+
+ provider.onPowerSaveModeChanged(false /* isPowerSaveModeEnabled */);
+ DeviceStateProvider.Listener listener = mock(DeviceStateProvider.Listener.class);
+ provider.setListener(listener);
+
+ verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(),
+ 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) },
+ mDeviceStateArrayCaptor.getValue());
+ Mockito.clearInvocations(listener);
+
+ provider.onPowerSaveModeChanged(false /* isPowerSaveModeEnabled */);
+ verify(listener, never()).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(),
+ eq(SUPPORTED_DEVICE_STATES_CHANGED_INITIALIZED));
+ Mockito.clearInvocations(listener);
+
+ // The THERMAL_TEST state should be disabled due to power save being enabled.
+ provider.onPowerSaveModeChanged(true /* isPowerSaveModeEnabled */);
+ verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(),
+ 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 */) },
+ mDeviceStateArrayCaptor.getValue());
+ Mockito.clearInvocations(listener);
+
+ // The THERMAL_TEST state should be re-enabled.
+ provider.onPowerSaveModeChanged(false /* isPowerSaveModeEnabled */);
+ verify(listener).onSupportedDeviceStatesChanged(mDeviceStateArrayCaptor.capture(),
+ 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) },
mDeviceStateArrayCaptor.getValue());
}
diff --git a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
index 9570ff6..8487903 100644
--- a/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
+++ b/services/tests/servicestests/src/com/android/server/usage/AppStandbyControllerTests.java
@@ -160,6 +160,9 @@
private static final String ADMIN_PKG2 = "com.android.admin2";
private static final String ADMIN_PKG3 = "com.android.admin3";
+ private static final String ADMIN_PROTECTED_PKG = "com.android.admin.protected";
+ private static final String ADMIN_PROTECTED_PKG2 = "com.android.admin.protected2";
+
private static final long MINUTE_MS = 60 * 1000;
private static final long HOUR_MS = 60 * MINUTE_MS;
private static final long DAY_MS = 24 * HOUR_MS;
@@ -229,7 +232,6 @@
long mElapsedRealtime;
boolean mIsAppIdleEnabled = true;
boolean mIsCharging;
- boolean mIsRestrictedBucketEnabled = true;
List<String> mNonIdleWhitelistApps = new ArrayList<>();
boolean mDisplayOn;
DisplayManager.DisplayListener mDisplayListener;
@@ -313,11 +315,6 @@
}
@Override
- boolean isRestrictedBucketEnabled() {
- return mIsRestrictedBucketEnabled;
- }
-
- @Override
File getDataSystemDirectory() {
return new File(getContext().getFilesDir(), Long.toString(sRandom.nextLong()));
}
@@ -1352,50 +1349,6 @@
@Test
@FlakyTest(bugId = 185169504)
- public void testRestrictedBucketDisabled() throws Exception {
- mInjector.mIsRestrictedBucketEnabled = false;
- // Get the controller to read the new value. Capturing the ContentObserver isn't possible
- // at the moment.
- mController.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
-
- reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
- mInjector.mElapsedRealtime += RESTRICTED_THRESHOLD;
-
- // Nothing should be able to put it into the RESTRICTED bucket.
- mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
- REASON_MAIN_TIMEOUT);
- assertNotBucket(STANDBY_BUCKET_RESTRICTED);
- mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
- REASON_MAIN_PREDICTED);
- assertNotBucket(STANDBY_BUCKET_RESTRICTED);
- mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
- REASON_MAIN_FORCED_BY_SYSTEM);
- assertNotBucket(STANDBY_BUCKET_RESTRICTED);
- mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
- REASON_MAIN_FORCED_BY_USER);
- assertNotBucket(STANDBY_BUCKET_RESTRICTED);
- }
-
- @Test
- @FlakyTest(bugId = 185169504)
- public void testRestrictedBucket_EnabledToDisabled() throws Exception {
- reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
- mInjector.mElapsedRealtime += RESTRICTED_THRESHOLD;
- mController.setAppStandbyBucket(PACKAGE_1, USER_ID, STANDBY_BUCKET_RESTRICTED,
- REASON_MAIN_FORCED_BY_SYSTEM);
- assertBucket(STANDBY_BUCKET_RESTRICTED);
-
- mInjector.mIsRestrictedBucketEnabled = false;
- // Get the controller to read the new value. Capturing the ContentObserver isn't possible
- // at the moment.
- mController.onBootPhase(SystemService.PHASE_SYSTEM_SERVICES_READY);
-
- mController.checkIdleStates(USER_ID);
- assertNotBucket(STANDBY_BUCKET_RESTRICTED);
- }
-
- @Test
- @FlakyTest(bugId = 185169504)
public void testPredictionRaiseFromRestrictedTimeout_highBucket() throws Exception {
reportEvent(mController, USER_INTERACTION, mInjector.mElapsedRealtime, PACKAGE_1);
@@ -1758,6 +1711,19 @@
}
@Test
+ public void testSetAdminProtectedPackages() {
+ assertAdminProtectedPackagesForTest(USER_ID, (String[]) null);
+ assertAdminProtectedPackagesForTest(USER_ID2, (String[]) null);
+
+ setAdminProtectedPackages(USER_ID, ADMIN_PROTECTED_PKG, ADMIN_PROTECTED_PKG2);
+ assertAdminProtectedPackagesForTest(USER_ID, ADMIN_PROTECTED_PKG, ADMIN_PROTECTED_PKG2);
+ assertAdminProtectedPackagesForTest(USER_ID2, (String[]) null);
+
+ setAdminProtectedPackages(USER_ID, (String[]) null);
+ assertAdminProtectedPackagesForTest(USER_ID, (String[]) null);
+ }
+
+ @Test
@FlakyTest(bugId = 185169504)
public void testUserInteraction_CrossProfile() throws Exception {
mInjector.mRunningUsers = new int[] {USER_ID, USER_ID2, USER_ID3};
@@ -2195,6 +2161,28 @@
mController.setActiveAdminApps(new ArraySet<>(Arrays.asList(admins)), userId);
}
+ private void setAdminProtectedPackages(int userId, String... packageNames) {
+ Set<String> adminProtectedPackages = packageNames != null ? new ArraySet<>(
+ Arrays.asList(packageNames)) : null;
+ mController.setAdminProtectedPackages(adminProtectedPackages, userId);
+ }
+
+ private void assertAdminProtectedPackagesForTest(int userId, String... packageNames) {
+ final Set<String> actualAdminProtectedPackages =
+ mController.getAdminProtectedPackagesForTest(userId);
+ if (packageNames == null) {
+ if (actualAdminProtectedPackages != null && !actualAdminProtectedPackages.isEmpty()) {
+ fail("Admin protected packages should be null; " + getAdminAppsStr(userId,
+ actualAdminProtectedPackages));
+ }
+ return;
+ }
+ assertEquals(packageNames.length, actualAdminProtectedPackages.size());
+ for (String adminProtectedPackage : packageNames) {
+ assertTrue(actualAdminProtectedPackages.contains(adminProtectedPackage));
+ }
+ }
+
private void setAndAssertBucket(String pkg, int user, int bucket, int reason) throws Exception {
rearmLatch(pkg);
mController.setAppStandbyBucket(pkg, user, bucket, reason);
diff --git a/services/tests/uiservicestests/Android.bp b/services/tests/uiservicestests/Android.bp
index 9a0a4d7..4b65895 100644
--- a/services/tests/uiservicestests/Android.bp
+++ b/services/tests/uiservicestests/Android.bp
@@ -26,7 +26,7 @@
"services.devicepolicy",
"services.net",
"services.usage",
- "service-permission.impl",
+ "service-permission.stubs.system_server",
"guava",
"androidx.test.rules",
"hamcrest-library",
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
index 91d4f8f..d73a3b8 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationComparatorTest.java
@@ -15,9 +15,11 @@
*/
package com.android.server.notification;
-import static org.hamcrest.Matchers.contains;
+import static com.android.internal.config.sysui.SystemUiSystemPropertiesFlags.NotificationFlags.NO_SORT_BY_INTERRUPTIVENESS;
+
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertThat;
import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.anyInt;
import static org.mockito.Matchers.anyString;
@@ -43,13 +45,14 @@
import android.telecom.TelecomManager;
import android.test.suitebuilder.annotation.SmallTest;
-import androidx.test.runner.AndroidJUnit4;
-
+import com.android.internal.config.sysui.SystemUiSystemPropertiesFlags;
import com.android.server.UiServiceTestCase;
+import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
@@ -58,7 +61,7 @@
import java.util.List;
@SmallTest
-@RunWith(AndroidJUnit4.class)
+@RunWith(Parameterized.class)
public class NotificationComparatorTest extends UiServiceTestCase {
@Mock Context mContext;
@Mock TelecomManager mTm;
@@ -92,9 +95,24 @@
private NotificationRecord mRecordColorized;
private NotificationRecord mRecordColorizedCall;
+ @Parameterized.Parameters(name = "sortByInterruptiveness={0}")
+ public static Boolean[] getSortByInterruptiveness() {
+ return new Boolean[] { true, false };
+ }
+
+ @Parameterized.Parameter
+ public boolean mSortByInterruptiveness;
+
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
+ SystemUiSystemPropertiesFlags.TEST_RESOLVER = flag -> {
+ if (flag.mSysPropKey.equals(NO_SORT_BY_INTERRUPTIVENESS.mSysPropKey)) {
+ return !mSortByInterruptiveness;
+ }
+ return new SystemUiSystemPropertiesFlags.DebugResolver().isEnabled(flag);
+ };
+
int userId = UserHandle.myUserId();
when(mContext.getResources()).thenReturn(getContext().getResources());
@@ -126,7 +144,7 @@
new StatusBarNotification(callPkg,
callPkg, 1, "mRecordMinCallNonInterruptive", callUid, callUid,
nonInterruptiveNotif,
- new UserHandle(userId), "", 2000), getDefaultChannel());
+ new UserHandle(userId), "", 2001), getDefaultChannel());
mRecordMinCallNonInterruptive.setSystemImportance(NotificationManager.IMPORTANCE_MIN);
mRecordMinCallNonInterruptive.setInterruptive(false);
@@ -228,7 +246,7 @@
.setColorized(true).setColor(Color.WHITE)
.build();
mRecordCheaterColorized = new NotificationRecord(mContext, new StatusBarNotification(pkg2,
- pkg2, 1, "cheater", uid2, uid2, n11, new UserHandle(userId),
+ pkg2, 1, "cheaterColorized", uid2, uid2, n11, new UserHandle(userId),
"", 9258), getDefaultChannel());
mRecordCheaterColorized.setSystemImportance(NotificationManager.IMPORTANCE_LOW);
@@ -262,6 +280,11 @@
mRecordColorizedCall.setSystemImportance(NotificationManager.IMPORTANCE_HIGH);
}
+ @After
+ public void tearDown() {
+ SystemUiSystemPropertiesFlags.TEST_RESOLVER = null;
+ }
+
@Test
public void testOrdering() {
final List<NotificationRecord> expected = new ArrayList<>();
@@ -281,8 +304,13 @@
expected.add(mNoMediaSessionMedia);
expected.add(mRecordCheater);
expected.add(mRecordCheaterColorized);
- expected.add(mRecordMinCall);
- expected.add(mRecordMinCallNonInterruptive);
+ if (mSortByInterruptiveness) {
+ expected.add(mRecordMinCall);
+ expected.add(mRecordMinCallNonInterruptive);
+ } else {
+ expected.add(mRecordMinCallNonInterruptive);
+ expected.add(mRecordMinCall);
+ }
List<NotificationRecord> actual = new ArrayList<>();
actual.addAll(expected);
@@ -290,14 +318,18 @@
Collections.sort(actual, new NotificationComparator(mContext));
- assertThat(actual, contains(expected.toArray()));
+ assertThat(actual).containsExactlyElementsIn(expected).inOrder();
}
@Test
public void testRankingScoreOverrides() {
NotificationComparator comp = new NotificationComparator(mContext);
NotificationRecord recordMinCallNonInterruptive = spy(mRecordMinCallNonInterruptive);
- assertTrue(comp.compare(mRecordMinCall, recordMinCallNonInterruptive) < 0);
+ if (mSortByInterruptiveness) {
+ assertTrue(comp.compare(mRecordMinCall, recordMinCallNonInterruptive) < 0);
+ } else {
+ assertTrue(comp.compare(mRecordMinCall, recordMinCallNonInterruptive) > 0);
+ }
when(recordMinCallNonInterruptive.getRankingScore()).thenReturn(1f);
assertTrue(comp.compare(mRecordMinCall, recordMinCallNonInterruptive) > 0);
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
index 2f7a5f4..7a55143 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationListenerServiceTest.java
@@ -21,6 +21,8 @@
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_NEUTRAL;
import static android.service.notification.NotificationListenerService.Ranking.USER_SENTIMENT_POSITIVE;
+import static com.google.common.truth.Truth.assertThat;
+
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotEquals;
@@ -35,10 +37,12 @@
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
+import android.app.Person;
import android.content.ComponentName;
import android.content.Context;
import android.content.Intent;
import android.content.pm.ApplicationInfo;
+import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.graphics.Bitmap;
import android.graphics.drawable.Icon;
@@ -46,11 +50,14 @@
import android.os.Build;
import android.os.IBinder;
import android.os.Parcel;
+import android.os.RemoteException;
+import android.os.UserHandle;
import android.service.notification.NotificationListenerService;
import android.service.notification.NotificationListenerService.Ranking;
import android.service.notification.NotificationListenerService.RankingMap;
import android.service.notification.NotificationRankingUpdate;
import android.service.notification.SnoozeCriterion;
+import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
import androidx.test.runner.AndroidJUnit4;
@@ -63,6 +70,7 @@
import org.junit.runner.RunWith;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.List;
@SmallTest
@@ -95,6 +103,31 @@
}
@Test
+ public void testGetActiveNotifications_preP_mapsExtraPeople() throws RemoteException {
+ TestListenerService service = new TestListenerService();
+ service.attachBaseContext(mContext);
+ service.targetSdk = Build.VERSION_CODES.O_MR1;
+
+ Notification notification = new Notification();
+ ArrayList<Person> people = new ArrayList<>();
+ people.add(new Person.Builder().setUri("uri1").setName("P1").build());
+ people.add(new Person.Builder().setUri("uri2").setName("P2").build());
+ notification.extras.putParcelableArrayList(Notification.EXTRA_PEOPLE_LIST, people);
+ when(service.getNoMan().getActiveNotificationsFromListener(any(), any(), anyInt()))
+ .thenReturn(new ParceledListSlice<StatusBarNotification>(Arrays.asList(
+ new StatusBarNotification("pkg", "opPkg", 1, "tag", 123, 1234,
+ notification, UserHandle.of(0), null, 0))));
+
+ StatusBarNotification[] sbns = service.getActiveNotifications();
+
+ assertThat(sbns).hasLength(1);
+ String[] mappedPeople = sbns[0].getNotification().extras.getStringArray(
+ Notification.EXTRA_PEOPLE);
+ assertThat(mappedPeople).isNotNull();
+ assertThat(mappedPeople).asList().containsExactly("uri1", "uri2");
+ }
+
+ @Test
public void testRanking() {
TestListenerService service = new TestListenerService();
service.applyUpdateLocked(generateUpdate());
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 41a9504..02c030d 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -4413,6 +4413,43 @@
assertFalse(posted.getNotification().extras
.containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
+ assertFalse(posted.getNotification().extras
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_ICON));
+ assertFalse(posted.getNotification().extras
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_INTENT));
+ }
+
+ @Test
+ public void testCustomMediaStyleRemote_noPermission() throws RemoteException {
+ String deviceName = "device";
+ when(mPackageManager.checkPermission(
+ eq(android.Manifest.permission.MEDIA_CONTENT_CONTROL), any(), anyInt()))
+ .thenReturn(PERMISSION_DENIED);
+ Notification.DecoratedMediaCustomViewStyle style =
+ new Notification.DecoratedMediaCustomViewStyle();
+ style.setRemotePlaybackInfo(deviceName, 0, null);
+ Notification.Builder nb = new Notification.Builder(mContext,
+ mTestNotificationChannel.getId())
+ .setStyle(style);
+
+ StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
+ "testCustomMediaStyleRemoteNoPermission", mUid, 0,
+ nb.build(), UserHandle.getUserHandleForUid(mUid), null, 0);
+ NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);
+
+ mBinderService.enqueueNotificationWithTag(PKG, PKG, sbn.getTag(),
+ nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
+ waitForIdle();
+
+ NotificationRecord posted = mService.findNotificationLocked(
+ PKG, nr.getSbn().getTag(), nr.getSbn().getId(), nr.getSbn().getUserId());
+
+ assertFalse(posted.getNotification().extras
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_DEVICE));
+ assertFalse(posted.getNotification().extras
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_ICON));
+ assertFalse(posted.getNotification().extras
+ .containsKey(Notification.EXTRA_MEDIA_REMOTE_INTENT));
}
@Test
@@ -5804,6 +5841,57 @@
}
@Test
+ public void testVisualDifference_sameImages() {
+ Icon large = Icon.createWithResource(mContext, 1);
+ Notification n1 = new Notification.Builder(mContext, "channel")
+ .setSmallIcon(1).setLargeIcon(large).build();
+ Notification n2 = new Notification.Builder(mContext, "channel")
+ .setSmallIcon(1).setLargeIcon(large).build();
+
+ NotificationRecord r1 = notificationToRecord(n1);
+ NotificationRecord r2 = notificationToRecord(n2);
+
+ assertThat(mService.isVisuallyInterruptive(r1, r2)).isFalse();
+ }
+
+ @Test
+ public void testVisualDifference_differentSmallImage() {
+ Icon large = Icon.createWithResource(mContext, 1);
+ Notification n1 = new Notification.Builder(mContext, "channel")
+ .setSmallIcon(1).setLargeIcon(large).build();
+ Notification n2 = new Notification.Builder(mContext, "channel")
+ .setSmallIcon(2).setLargeIcon(large).build();
+
+ NotificationRecord r1 = notificationToRecord(n1);
+ NotificationRecord r2 = notificationToRecord(n2);
+
+ assertThat(mService.isVisuallyInterruptive(r1, r2)).isTrue();
+ }
+
+ @Test
+ public void testVisualDifference_differentLargeImage() {
+ Icon large1 = Icon.createWithResource(mContext, 1);
+ Icon large2 = Icon.createWithResource(mContext, 2);
+ Notification n1 = new Notification.Builder(mContext, "channel")
+ .setSmallIcon(1).setLargeIcon(large1).build();
+ Notification n2 = new Notification.Builder(mContext, "channel")
+ .setSmallIcon(1).setLargeIcon(large2).build();
+
+ NotificationRecord r1 = notificationToRecord(n1);
+ NotificationRecord r2 = notificationToRecord(n2);
+
+ assertThat(mService.isVisuallyInterruptive(r1, r2)).isTrue();
+ }
+
+ private NotificationRecord notificationToRecord(Notification n) {
+ return new NotificationRecord(
+ mContext,
+ new StatusBarNotification(PKG, PKG, 0, "tag", mUid, 0, n,
+ UserHandle.getUserHandleForUid(mUid), null, 0),
+ mock(NotificationChannel.class));
+ }
+
+ @Test
public void testHideAndUnhideNotificationsOnSuspendedPackageBroadcast() {
// post 2 notification from this package
final NotificationRecord notif1 = generateNotificationRecord(
@@ -10441,6 +10529,31 @@
}
@Test
+ public void fixCallNotification_withOnGoingFlag_shouldNotBeNonDismissible()
+ throws Exception {
+ // Given: a call notification has the flag FLAG_ONGOING_EVENT set
+ // feature flag: ALLOW_DISMISS_ONGOING is on
+ mTestFlagResolver.setFlagOverride(ALLOW_DISMISS_ONGOING, true);
+ when(mTelecomManager.isInManagedCall()).thenReturn(true);
+
+ Person person = new Person.Builder()
+ .setName("caller")
+ .build();
+ Notification n = new Notification.Builder(mContext, "test")
+ .setOngoing(true)
+ .setStyle(Notification.CallStyle.forOngoingCall(
+ person, mock(PendingIntent.class)))
+ .build();
+
+ // When: fix the notification with NotificationManagerService
+ mService.fixNotification(n, PKG, "tag", 9, 0, mUid, NOT_FOREGROUND_SERVICE);
+
+ // Then: the notification's flag FLAG_NO_DISMISS should be set
+ assertNotSame(0, n.flags & Notification.FLAG_NO_DISMISS);
+ }
+
+
+ @Test
public void fixNonExemptNotification_withOnGoingFlag_shouldBeDismissible() throws Exception {
// Given: a non-exempt notification has the flag FLAG_ONGOING_EVENT set
// feature flag: ALLOW_DISMISS_ONGOING is on
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
index 06bcb91..50e5bbf 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/PreferencesHelperTest.java
@@ -679,10 +679,6 @@
compareChannels(ido, mHelper.getNotificationChannel(PKG_O, UID_O, ido.getId(), false));
compareChannels(idp, mHelper.getNotificationChannel(PKG_P, UID_P, idp.getId(), false));
- verify(mPermissionHelper).setNotificationPermission(nMr1Expected);
- verify(mPermissionHelper).setNotificationPermission(oExpected);
- verify(mPermissionHelper).setNotificationPermission(pExpected);
-
// verify that we also write a state for review_permissions_notification to eventually
// show a notification
assertEquals(NotificationManagerService.REVIEW_NOTIF_STATE_SHOULD_SHOW,
diff --git a/services/tests/wmtests/Android.bp b/services/tests/wmtests/Android.bp
index 98c358c..6509591 100644
--- a/services/tests/wmtests/Android.bp
+++ b/services/tests/wmtests/Android.bp
@@ -49,7 +49,7 @@
static_libs: [
"frameworks-base-testutils",
"services.core",
- "service-permission.impl",
+ "service-permission.stubs.system_server",
"androidx.test.runner",
"androidx.test.rules",
"mockito-target-extended-minus-junit4",
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 6147633..1a635a9e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivityRecordTests.java
@@ -1205,6 +1205,8 @@
any(ClientTransaction.class));
} catch (RemoteException ignored) {
}
+
+ assertNull(targetActivity.results);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
new file mode 100644
index 0000000..0eca8c9
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/ActivitySnapshotControllerTests.java
@@ -0,0 +1,162 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+
+import static org.junit.Assert.assertEquals;
+
+import android.platform.test.annotations.Presubmit;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test class for {@link ActivitySnapshotController}.
+ *
+ * Build/Install/Run:
+ * * atest WmTests:ActivitySnapshotControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class ActivitySnapshotControllerTests extends WindowTestsBase {
+
+ private ActivitySnapshotController mActivitySnapshotController;
+ @Before
+ public void setUp() throws Exception {
+ mActivitySnapshotController = mWm.mSnapshotController.mActivitySnapshotController;
+ mActivitySnapshotController.resetTmpFields();
+ }
+ @Test
+ public void testOpenActivityTransition() {
+ final SnapshotController.TransitionState transitionState =
+ new SnapshotController.TransitionState();
+ final Task task = createTask(mDisplayContent);
+ // note for createAppWindow: the new child is added at index 0
+ final WindowState openingWindow = createAppWindow(task,
+ ACTIVITY_TYPE_STANDARD, "openingWindow");
+ openingWindow.mActivityRecord.commitVisibility(
+ true /* visible */, true /* performLayout */);
+ final WindowState closingWindow = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
+ "closingWindow");
+ closingWindow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+ transitionState.addParticipant(closingWindow.mActivityRecord, false);
+ transitionState.addParticipant(openingWindow.mActivityRecord, true);
+ mActivitySnapshotController.handleOpenActivityTransition(transitionState);
+
+ assertEquals(1, mActivitySnapshotController.mPendingCaptureActivity.size());
+ assertEquals(0, mActivitySnapshotController.mPendingRemoveActivity.size());
+ assertEquals(closingWindow.mActivityRecord,
+ mActivitySnapshotController.mPendingCaptureActivity.valueAt(0));
+ mActivitySnapshotController.resetTmpFields();
+
+ // simulate three activity
+ final WindowState belowClose = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
+ "belowClose");
+ belowClose.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+ mActivitySnapshotController.handleOpenActivityTransition(transitionState);
+ assertEquals(1, mActivitySnapshotController.mPendingCaptureActivity.size());
+ assertEquals(1, mActivitySnapshotController.mPendingRemoveActivity.size());
+ assertEquals(closingWindow.mActivityRecord,
+ mActivitySnapshotController.mPendingCaptureActivity.valueAt(0));
+ assertEquals(belowClose.mActivityRecord,
+ mActivitySnapshotController.mPendingRemoveActivity.valueAt(0));
+ }
+
+ @Test
+ public void testCloseActivityTransition() {
+ final SnapshotController.TransitionState transitionState =
+ new SnapshotController.TransitionState();
+ final Task task = createTask(mDisplayContent);
+ // note for createAppWindow: the new child is added at index 0
+ final WindowState closingWindow = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
+ "closingWindow");
+ closingWindow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+ final WindowState openingWindow = createAppWindow(task,
+ ACTIVITY_TYPE_STANDARD, "openingWindow");
+ openingWindow.mActivityRecord.commitVisibility(
+ true /* visible */, true /* performLayout */);
+ transitionState.addParticipant(closingWindow.mActivityRecord, false);
+ transitionState.addParticipant(openingWindow.mActivityRecord, true);
+ mActivitySnapshotController.handleCloseActivityTransition(transitionState);
+ assertEquals(0, mActivitySnapshotController.mPendingCaptureActivity.size());
+ assertEquals(1, mActivitySnapshotController.mPendingDeleteActivity.size());
+ assertEquals(openingWindow.mActivityRecord,
+ mActivitySnapshotController.mPendingDeleteActivity.valueAt(0));
+ mActivitySnapshotController.resetTmpFields();
+
+ // simulate three activity
+ final WindowState belowOpen = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
+ "belowOpen");
+ belowOpen.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+ mActivitySnapshotController.handleCloseActivityTransition(transitionState);
+ assertEquals(0, mActivitySnapshotController.mPendingCaptureActivity.size());
+ assertEquals(1, mActivitySnapshotController.mPendingDeleteActivity.size());
+ assertEquals(1, mActivitySnapshotController.mPendingLoadActivity.size());
+ assertEquals(openingWindow.mActivityRecord,
+ mActivitySnapshotController.mPendingDeleteActivity.valueAt(0));
+ assertEquals(belowOpen.mActivityRecord,
+ mActivitySnapshotController.mPendingLoadActivity.valueAt(0));
+ }
+
+ @Test
+ public void testTaskTransition() {
+ final SnapshotController.TransitionState taskCloseTransition =
+ new SnapshotController.TransitionState();
+ final SnapshotController.TransitionState taskOpenTransition =
+ new SnapshotController.TransitionState();
+ final Task closeTask = createTask(mDisplayContent);
+ // note for createAppWindow: the new child is added at index 0
+ final WindowState closingWindow = createAppWindow(closeTask, ACTIVITY_TYPE_STANDARD,
+ "closingWindow");
+ closingWindow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+ final WindowState closingWindowBelow = createAppWindow(closeTask, ACTIVITY_TYPE_STANDARD,
+ "closingWindowBelow");
+ closingWindowBelow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+
+ final Task openTask = createTask(mDisplayContent);
+ final WindowState openingWindow = createAppWindow(openTask, ACTIVITY_TYPE_STANDARD,
+ "openingWindow");
+ openingWindow.mActivityRecord.commitVisibility(
+ true /* visible */, true /* performLayout */);
+ final WindowState openingWindowBelow = createAppWindow(openTask, ACTIVITY_TYPE_STANDARD,
+ "openingWindowBelow");
+ openingWindowBelow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+ taskCloseTransition.addParticipant(closeTask, false);
+ taskOpenTransition.addParticipant(openTask, true);
+ mActivitySnapshotController.handleCloseTaskTransition(taskCloseTransition);
+ mActivitySnapshotController.handleOpenTaskTransition(taskOpenTransition);
+
+ assertEquals(1, mActivitySnapshotController.mPendingRemoveActivity.size());
+ assertEquals(closingWindowBelow.mActivityRecord,
+ mActivitySnapshotController.mPendingRemoveActivity.valueAt(0));
+ assertEquals(1, mActivitySnapshotController.mPendingLoadActivity.size());
+ assertEquals(openingWindowBelow.mActivityRecord,
+ mActivitySnapshotController.mPendingLoadActivity.valueAt(0));
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppSnapshotControllerTests.java b/services/tests/wmtests/src/com/android/server/wm/AppSnapshotControllerTests.java
new file mode 100644
index 0000000..83af1814
--- /dev/null
+++ b/services/tests/wmtests/src/com/android/server/wm/AppSnapshotControllerTests.java
@@ -0,0 +1,171 @@
+/*
+ * Copyright (C) 2022 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm;
+
+import static android.app.WindowConfiguration.ACTIVITY_TYPE_STANDARD;
+
+import static com.android.server.wm.SnapshotController.ACTIVITY_CLOSE;
+import static com.android.server.wm.SnapshotController.ACTIVITY_OPEN;
+import static com.android.server.wm.SnapshotController.TASK_CLOSE;
+import static com.android.server.wm.SnapshotController.TASK_OPEN;
+
+import static org.junit.Assert.assertTrue;
+
+import android.platform.test.annotations.Presubmit;
+import android.util.ArraySet;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+
+/**
+ * Test class for {@link SnapshotController}.
+ *
+ * Build/Install/Run:
+ * * atest WmTests:AppSnapshotControllerTests
+ */
+@SmallTest
+@Presubmit
+@RunWith(WindowTestRunner.class)
+public class AppSnapshotControllerTests extends WindowTestsBase {
+ final ArraySet<ActivityRecord> mClosingApps = new ArraySet<>();
+ final ArraySet<ActivityRecord> mOpeningApps = new ArraySet<>();
+
+ final TransitionMonitor mOpenActivityMonitor = new TransitionMonitor();
+ final TransitionMonitor mCloseActivityMonitor = new TransitionMonitor();
+ final TransitionMonitor mOpenTaskMonitor = new TransitionMonitor();
+ final TransitionMonitor mCloseTaskMonitor = new TransitionMonitor();
+
+ @Before
+ public void setUp() throws Exception {
+ resetStatus();
+ mWm.mSnapshotController.registerTransitionStateConsumer(
+ ACTIVITY_CLOSE, mCloseActivityMonitor::handleTransition);
+ mWm.mSnapshotController.registerTransitionStateConsumer(
+ ACTIVITY_OPEN, mOpenActivityMonitor::handleTransition);
+ mWm.mSnapshotController.registerTransitionStateConsumer(
+ TASK_CLOSE, mCloseTaskMonitor::handleTransition);
+ mWm.mSnapshotController.registerTransitionStateConsumer(
+ TASK_OPEN, mOpenTaskMonitor::handleTransition);
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ mWm.mSnapshotController.unregisterTransitionStateConsumer(
+ ACTIVITY_CLOSE, mCloseActivityMonitor::handleTransition);
+ mWm.mSnapshotController.unregisterTransitionStateConsumer(
+ ACTIVITY_OPEN, mOpenActivityMonitor::handleTransition);
+ mWm.mSnapshotController.unregisterTransitionStateConsumer(
+ TASK_CLOSE, mCloseTaskMonitor::handleTransition);
+ mWm.mSnapshotController.unregisterTransitionStateConsumer(
+ TASK_OPEN, mOpenTaskMonitor::handleTransition);
+ }
+
+ private static class TransitionMonitor {
+ private final ArraySet<WindowContainer> mOpenParticipant = new ArraySet<>();
+ private final ArraySet<WindowContainer> mCloseParticipant = new ArraySet<>();
+ void handleTransition(SnapshotController.TransitionState<ActivityRecord> state) {
+ mOpenParticipant.addAll(state.getParticipant(true /* open */));
+ mCloseParticipant.addAll(state.getParticipant(false /* close */));
+ }
+ void reset() {
+ mOpenParticipant.clear();
+ mCloseParticipant.clear();
+ }
+ }
+
+ private void resetStatus() {
+ mClosingApps.clear();
+ mOpeningApps.clear();
+ mOpenActivityMonitor.reset();
+ mCloseActivityMonitor.reset();
+ mOpenTaskMonitor.reset();
+ mCloseTaskMonitor.reset();
+ }
+
+ @Test
+ public void testHandleAppTransition_openActivityTransition() {
+ final Task task = createTask(mDisplayContent);
+ // note for createAppWindow: the new child is added at index 0
+ final WindowState openingWindow = createAppWindow(task,
+ ACTIVITY_TYPE_STANDARD, "openingWindow");
+ openingWindow.mActivityRecord.commitVisibility(
+ true /* visible */, true /* performLayout */);
+ final WindowState closingWindow = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
+ "closingWindow");
+ closingWindow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+ mClosingApps.add(closingWindow.mActivityRecord);
+ mOpeningApps.add(openingWindow.mActivityRecord);
+ mWm.mSnapshotController.handleAppTransition(mClosingApps, mOpeningApps);
+ assertTrue(mOpenActivityMonitor.mCloseParticipant.contains(closingWindow.mActivityRecord));
+ assertTrue(mOpenActivityMonitor.mOpenParticipant.contains(openingWindow.mActivityRecord));
+ }
+
+ @Test
+ public void testHandleAppTransition_closeActivityTransition() {
+ final Task task = createTask(mDisplayContent);
+ // note for createAppWindow: the new child is added at index 0
+ final WindowState closingWindow = createAppWindow(task, ACTIVITY_TYPE_STANDARD,
+ "closingWindow");
+ closingWindow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+ final WindowState openingWindow = createAppWindow(task,
+ ACTIVITY_TYPE_STANDARD, "openingWindow");
+ openingWindow.mActivityRecord.commitVisibility(
+ true /* visible */, true /* performLayout */);
+ mClosingApps.add(closingWindow.mActivityRecord);
+ mOpeningApps.add(openingWindow.mActivityRecord);
+ mWm.mSnapshotController.handleAppTransition(mClosingApps, mOpeningApps);
+ assertTrue(mCloseActivityMonitor.mCloseParticipant.contains(closingWindow.mActivityRecord));
+ assertTrue(mCloseActivityMonitor.mOpenParticipant.contains(openingWindow.mActivityRecord));
+ }
+
+ @Test
+ public void testHandleAppTransition_TaskTransition() {
+ final Task closeTask = createTask(mDisplayContent);
+ // note for createAppWindow: the new child is added at index 0
+ final WindowState closingWindow = createAppWindow(closeTask, ACTIVITY_TYPE_STANDARD,
+ "closingWindow");
+ closingWindow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+ final WindowState closingWindowBelow = createAppWindow(closeTask, ACTIVITY_TYPE_STANDARD,
+ "closingWindowBelow");
+ closingWindowBelow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+
+ final Task openTask = createTask(mDisplayContent);
+ final WindowState openingWindow = createAppWindow(openTask, ACTIVITY_TYPE_STANDARD,
+ "openingWindow");
+ openingWindow.mActivityRecord.commitVisibility(
+ true /* visible */, true /* performLayout */);
+ final WindowState openingWindowBelow = createAppWindow(openTask, ACTIVITY_TYPE_STANDARD,
+ "openingWindowBelow");
+ openingWindowBelow.mActivityRecord.commitVisibility(
+ false /* visible */, true /* performLayout */);
+
+ mClosingApps.add(closingWindow.mActivityRecord);
+ mOpeningApps.add(openingWindow.mActivityRecord);
+ mWm.mSnapshotController.handleAppTransition(mClosingApps, mOpeningApps);
+ assertTrue(mCloseTaskMonitor.mCloseParticipant.contains(closeTask));
+ assertTrue(mOpenTaskMonitor.mOpenParticipant.contains(openTask));
+ }
+}
diff --git a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
index c73237e..0ae579b 100644
--- a/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/AppTransitionControllerTest.java
@@ -376,46 +376,6 @@
}
@Test
- public void testGetAnimationTargets_windowsAreBeingReplaced() {
- // [DisplayContent] -+- [Task1] - [ActivityRecord1] (opening, visible)
- // +- [AppWindow1] (being-replaced)
- // +- [Task2] - [ActivityRecord2] (closing, invisible)
- // +- [AppWindow2] (being-replaced)
- final ActivityRecord activity1 = createActivityRecord(mDisplayContent);
- final WindowManager.LayoutParams attrs = new WindowManager.LayoutParams(
- TYPE_BASE_APPLICATION);
- attrs.setTitle("AppWindow1");
- final TestWindowState appWindow1 = createWindowState(attrs, activity1);
- appWindow1.mWillReplaceWindow = true;
- activity1.addWindow(appWindow1);
-
- final ActivityRecord activity2 = createActivityRecord(mDisplayContent);
- activity2.setVisible(false);
- activity2.setVisibleRequested(false);
- attrs.setTitle("AppWindow2");
- final TestWindowState appWindow2 = createWindowState(attrs, activity2);
- appWindow2.mWillReplaceWindow = true;
- activity2.addWindow(appWindow2);
-
- final ArraySet<ActivityRecord> opening = new ArraySet<>();
- opening.add(activity1);
- final ArraySet<ActivityRecord> closing = new ArraySet<>();
- closing.add(activity2);
-
- // Animate opening apps even if it's already visible in case its windows are being replaced.
- // Don't animate closing apps if it's already invisible even though its windows are being
- // replaced.
- assertEquals(
- new ArraySet<>(new WindowContainer[]{activity1.getRootTask()}),
- AppTransitionController.getAnimationTargets(
- opening, closing, true /* visible */));
- assertEquals(
- new ArraySet<>(new WindowContainer[]{}),
- AppTransitionController.getAnimationTargets(
- opening, closing, false /* visible */));
- }
-
- @Test
public void testGetAnimationTargets_openingClosingInDifferentTask() {
// [DisplayContent] -+- [Task1] -+- [ActivityRecord1] (opening, invisible)
// | +- [ActivityRecord2] (invisible)
diff --git a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
index 7cb7c79d..43fc1c4 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LaunchParamsPersisterTests.java
@@ -111,6 +111,7 @@
mDisplayUniqueId = "test:" + sNextUniqueId++;
mTestDisplay = new TestDisplayContent.Builder(mAtm, 1000, 1500)
.setUniqueId(mDisplayUniqueId).build();
+ mTestDisplay.getDefaultTaskDisplayArea().setWindowingMode(TEST_WINDOWING_MODE);
when(mRootWindowContainer.getDisplayContent(eq(mDisplayUniqueId)))
.thenReturn(mTestDisplay);
diff --git a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
index da078a2..9b4cb13 100644
--- a/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/LetterboxUiControllerTest.java
@@ -55,6 +55,7 @@
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.Mockito.verify;
import android.annotation.Nullable;
import android.compat.testing.PlatformCompatChangeRule;
@@ -526,6 +527,16 @@
// overrideOrientationIfNeeded
@Test
+ public void testOverrideOrientationIfNeeded_mapInvokedOnRequest() throws Exception {
+ mController = new LetterboxUiController(mWm, mActivity);
+ spyOn(mWm);
+
+ mController.overrideOrientationIfNeeded(SCREEN_ORIENTATION_PORTRAIT);
+
+ verify(mWm).mapOrientationRequest(SCREEN_ORIENTATION_PORTRAIT);
+ }
+
+ @Test
@EnableCompatChanges({OVERRIDE_UNDEFINED_ORIENTATION_TO_PORTRAIT})
public void testOverrideOrientationIfNeeded_portraitOverrideEnabled_returnsPortrait()
throws Exception {
diff --git a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
index 2cc46a9..adc3db7 100644
--- a/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/SizeCompatTests.java
@@ -108,7 +108,6 @@
import libcore.junit.util.compat.CoreCompatChangeRule.EnableCompatChanges;
import org.junit.After;
-import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -604,11 +603,11 @@
// The scale is 2000/2500=0.8. The horizontal centered offset is (1000-(1000*0.8))/2=100.
final float scale = (float) display.mBaseDisplayHeight / currentBounds.height();
final int offsetX = (int) (display.mBaseDisplayWidth - (origBounds.width() * scale)) / 2;
- assertEquals(offsetX, currentBounds.left);
+ final int screenX = mActivity.getBounds().left;
+ assertEquals(offsetX, screenX);
- // The position of configuration bounds should be the same as compat bounds.
- assertEquals(mActivity.getBounds().left, currentBounds.left);
- assertEquals(mActivity.getBounds().top, currentBounds.top);
+ // The position of configuration bounds should be in app space.
+ assertEquals(screenX, (int) (currentBounds.left * scale + 0.5f));
// Activity is sandboxed to the offset size compat bounds.
assertActivityMaxBoundsSandboxed();
@@ -638,7 +637,7 @@
// The size should still be in portrait [100, 0 - 1100, 2500] = 1000x2500.
assertEquals(origBounds.width(), currentBounds.width());
assertEquals(origBounds.height(), currentBounds.height());
- assertEquals(offsetX, currentBounds.left);
+ assertEquals(offsetX, mActivity.getBounds().left);
assertScaled();
// Activity is sandboxed due to size compat mode.
assertActivityMaxBoundsSandboxed();
@@ -801,9 +800,11 @@
assertEquals(origAppBounds.height(), appBounds.height());
// The activity is 1000x1400 and the display is 2500x1000.
assertScaled();
- // The position in configuration should be global coordinates.
- assertEquals(mActivity.getBounds().left, currentBounds.left);
- assertEquals(mActivity.getBounds().top, currentBounds.top);
+ final float scale = mActivity.getCompatScale();
+ // The position in configuration should be in app coordinates.
+ final Rect screenBounds = mActivity.getBounds();
+ assertEquals(screenBounds.left, (int) (currentBounds.left * scale + 0.5f));
+ assertEquals(screenBounds.top, (int) (currentBounds.top * scale + 0.5f));
// Activity max bounds are sandboxed due to size compat mode.
assertActivityMaxBoundsSandboxed();
@@ -2025,7 +2026,7 @@
float expectedAspectRatio = 1f * displayWidth / getExpectedSplitSize(displayHeight);
final Rect afterBounds = activity.getBounds();
final float afterAspectRatio = (float) (afterBounds.height()) / afterBounds.width();
- Assert.assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
+ assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
}
@Test
@@ -2050,7 +2051,7 @@
float expectedAspectRatio = 1f * displayHeight / getExpectedSplitSize(displayWidth);
final Rect afterBounds = activity.getBounds();
final float afterAspectRatio = (float) (afterBounds.height()) / afterBounds.width();
- Assert.assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
+ assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
}
@Test
@@ -2076,7 +2077,7 @@
float expectedAspectRatio = 1f * displayWidth / getExpectedSplitSize(displayHeight);
final Rect afterBounds = activity.getBounds();
final float afterAspectRatio = (float) (afterBounds.width()) / afterBounds.height();
- Assert.assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
+ assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
}
@Test
@@ -2102,7 +2103,89 @@
float expectedAspectRatio = 1f * displayHeight / getExpectedSplitSize(displayWidth);
final Rect afterBounds = activity.getBounds();
final float afterAspectRatio = (float) (afterBounds.width()) / afterBounds.height();
- Assert.assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
+ assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
+ }
+
+ @Test
+ @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
+ ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN})
+ public void testOverrideSplitScreenAspectRatio_splitScreenActivityInPortrait_notLetterboxed() {
+ mAtm.mDevEnableNonResizableMultiWindow = true;
+ final int screenWidth = 1800;
+ final int screenHeight = 1000;
+ setUpDisplaySizeWithApp(screenWidth, screenHeight);
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+
+ activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ // Simulate real display with top insets.
+ final int topInset = 30;
+ activity.mDisplayContent.getWindowConfiguration()
+ .setAppBounds(0, topInset, screenWidth, screenHeight);
+
+ final TestSplitOrganizer organizer =
+ new TestSplitOrganizer(mAtm, activity.getDisplayContent());
+ // Move activity to split screen which takes half of the screen.
+ mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test");
+ organizer.mPrimary.setBounds(0, 0, getExpectedSplitSize(screenWidth), screenHeight);
+ assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode());
+ assertEquals(WINDOWING_MODE_MULTI_WINDOW, activity.getWindowingMode());
+
+ // Unresizable portrait-only activity.
+ prepareUnresizable(activity, 3f, SCREEN_ORIENTATION_PORTRAIT);
+
+ // Activity should have the aspect ratio of a split screen activity and occupy exactly one
+ // half of the screen, so there is no letterbox
+ float expectedAspectRatio = 1f * screenHeight / getExpectedSplitSize(screenWidth);
+ final Rect afterBounds = activity.getBounds();
+ final float afterAspectRatio = (float) (afterBounds.height()) / afterBounds.width();
+ assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
+ assertFalse(activity.areBoundsLetterboxed());
+ }
+
+ @Test
+ @EnableCompatChanges({ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO,
+ ActivityInfo.OVERRIDE_MIN_ASPECT_RATIO_TO_ALIGN_WITH_SPLIT_SCREEN})
+ public void testOverrideSplitScreenAspectRatio_splitScreenActivityInLandscape_notLetterboxed() {
+ mAtm.mDevEnableNonResizableMultiWindow = true;
+ final int screenWidth = 1000;
+ final int screenHeight = 1800;
+ setUpDisplaySizeWithApp(screenWidth, screenHeight);
+ final ActivityRecord activity = new ActivityBuilder(mAtm)
+ .setTask(mTask)
+ .setComponent(ComponentName.createRelative(mContext,
+ SizeCompatTests.class.getName()))
+ .setUid(android.os.Process.myUid())
+ .build();
+
+ activity.mDisplayContent.setIgnoreOrientationRequest(true /* ignoreOrientationRequest */);
+ // Simulate real display with top insets.
+ final int leftInset = 30;
+ activity.mDisplayContent.getWindowConfiguration()
+ .setAppBounds(leftInset, 0, screenWidth, screenHeight);
+
+ final TestSplitOrganizer organizer =
+ new TestSplitOrganizer(mAtm, activity.getDisplayContent());
+ // Move activity to split screen which takes half of the screen.
+ mTask.reparent(organizer.mPrimary, POSITION_TOP, /* moveParents= */ false , "test");
+ organizer.mPrimary.setBounds(0, 0, screenWidth, getExpectedSplitSize(screenHeight));
+ assertEquals(WINDOWING_MODE_MULTI_WINDOW, mTask.getWindowingMode());
+ assertEquals(WINDOWING_MODE_MULTI_WINDOW, activity.getWindowingMode());
+
+ // Unresizable landscape-only activity.
+ prepareUnresizable(activity, 3f, SCREEN_ORIENTATION_LANDSCAPE);
+
+ // Activity should have the aspect ratio of a split screen activity and occupy exactly one
+ // half of the screen, so there is no letterbox
+ float expectedAspectRatio = 1f * screenWidth / getExpectedSplitSize(screenHeight);
+ final Rect afterBounds = activity.getBounds();
+ final float afterAspectRatio = (float) (afterBounds.width()) / afterBounds.height();
+ assertEquals(expectedAspectRatio, afterAspectRatio, 0.001f);
+ assertFalse(activity.areBoundsLetterboxed());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
index 378e8be..99ab715 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskFragmentOrganizerControllerTest.java
@@ -398,6 +398,8 @@
public void testOnActivityReparentedToTask_activityNotInOrganizerProcess_useTemporaryToken() {
final int pid = Binder.getCallingPid();
final int uid = Binder.getCallingUid();
+ final WindowProcessController organizerProc = mSystemServicesTestRule.addProcess(
+ "pkg.organizer", DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME, pid, uid);
mTaskFragment.setTaskFragmentOrganizer(mOrganizer.getOrganizerToken(), uid,
DEFAULT_TASK_FRAGMENT_ORGANIZER_PROCESS_NAME);
mWindowOrganizerController.mLaunchTaskFragments.put(mFragmentToken, mTaskFragment);
@@ -436,6 +438,15 @@
// The temporary token can only be used once.
assertNull(mController.getReparentActivityFromTemporaryToken(mIOrganizer,
change.getActivityToken()));
+
+ // The organizer process should also have visible state by the visible activity in a
+ // different process.
+ activity.setVisibleRequested(true);
+ activity.setState(ActivityRecord.State.RESUMED, "test");
+ assertTrue(organizerProc.hasVisibleActivities());
+ activity.setVisibleRequested(false);
+ activity.setState(ActivityRecord.State.STOPPED, "test");
+ assertFalse(organizerProc.hasVisibleActivities());
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
index 5208e5a..28241d3 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TaskTests.java
@@ -1328,17 +1328,16 @@
spyOn(persister);
final Task task = getTestTask();
- task.setHasBeenVisible(false);
+ task.setHasBeenVisible(true);
task.getDisplayContent()
.getDefaultTaskDisplayArea()
- .setWindowingMode(WindowConfiguration.WINDOWING_MODE_FREEFORM);
- task.getRootTask().setWindowingMode(WINDOWING_MODE_FULLSCREEN);
+ .setWindowingMode(WINDOWING_MODE_FREEFORM);
+ task.getRootTask().setWindowingMode(WINDOWING_MODE_FREEFORM);
final DisplayContent oldDisplay = task.getDisplayContent();
LaunchParamsController.LaunchParams params = new LaunchParamsController.LaunchParams();
- params.mWindowingMode = WINDOWING_MODE_UNDEFINED;
persister.getLaunchParams(task, null, params);
- assertEquals(WINDOWING_MODE_UNDEFINED, params.mWindowingMode);
+ assertEquals(WINDOWING_MODE_FREEFORM, params.mWindowingMode);
task.setHasBeenVisible(true);
task.removeImmediately();
@@ -1346,7 +1345,7 @@
verify(persister).saveTask(task, oldDisplay);
persister.getLaunchParams(task, null, params);
- assertEquals(WINDOWING_MODE_FULLSCREEN, params.mWindowingMode);
+ assertEquals(WINDOWING_MODE_FREEFORM, params.mWindowingMode);
}
@Test
diff --git a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
index 1d0715a..2a2641e 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TestWindowManagerPolicy.java
@@ -314,7 +314,7 @@
}
@Override
- public int applyKeyguardOcclusionChange(boolean notify) {
+ public int applyKeyguardOcclusionChange() {
return 0;
}
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 616d528..582d7d8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/TransitionTests.java
@@ -44,6 +44,7 @@
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doNothing;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.doReturn;
import static com.android.dx.mockito.inline.extended.ExtendedMockito.spyOn;
+import static com.android.server.wm.SnapshotController.TASK_CLOSE;
import static com.android.server.wm.WindowContainer.POSITION_TOP;
import static org.junit.Assert.assertEquals;
@@ -1351,6 +1352,9 @@
@Test
public void testTransientLaunch() {
+ spyOn(mWm.mSnapshotController.mTaskSnapshotController);
+ mWm.mSnapshotController.registerTransitionStateConsumer(TASK_CLOSE,
+ mWm.mSnapshotController.mTaskSnapshotController::handleTaskClose);
final ArrayList<ActivityRecord> enteringAnimReports = new ArrayList<>();
final TransitionController controller = new TestTransitionController(mAtm) {
@Override
@@ -1361,7 +1365,9 @@
super.dispatchLegacyAppTransitionFinished(ar);
}
};
- final TaskSnapshotController snapshotController = controller.mTaskSnapshotController;
+ controller.mSnapshotController = mWm.mSnapshotController;
+ final TaskSnapshotController taskSnapshotController = controller.mSnapshotController
+ .mTaskSnapshotController;
final ITransitionPlayer player = new ITransitionPlayer.Default();
controller.registerTransitionPlayer(player, null /* playerProc */);
final Transition openTransition = controller.createTransition(TRANSIT_OPEN);
@@ -1391,7 +1397,7 @@
// normally.
mWm.mSyncEngine.abort(openTransition.getSyncId());
- verify(snapshotController, times(1)).recordSnapshot(eq(task2), eq(false));
+ verify(taskSnapshotController, times(1)).recordSnapshot(eq(task2), eq(false));
controller.finishTransition(openTransition);
@@ -1421,7 +1427,7 @@
// Make sure we haven't called recordSnapshot (since we are transient, it shouldn't be
// called until finish).
- verify(snapshotController, times(0)).recordSnapshot(eq(task1), eq(false));
+ verify(taskSnapshotController, times(0)).recordSnapshot(eq(task1), eq(false));
enteringAnimReports.clear();
doCallRealMethod().when(mWm.mRoot).ensureActivitiesVisible(any(),
@@ -1447,7 +1453,7 @@
assertFalse(activity1.isVisible());
assertFalse(activity1.app.hasActivityInVisibleTask());
- verify(snapshotController, times(1)).recordSnapshot(eq(task1), eq(false));
+ verify(taskSnapshotController, times(1)).recordSnapshot(eq(task1), eq(false));
assertTrue(enteringAnimReports.contains(activity2));
}
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
index 7d6cf4a..ba6b3b6 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowManagerServiceTests.java
@@ -26,7 +26,10 @@
import static android.hardware.display.DisplayManager.VIRTUAL_DISPLAY_FLAG_TRUSTED;
import static android.view.Display.DEFAULT_DISPLAY;
import static android.view.Display.FLAG_OWN_FOCUS;
+import static android.view.WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
+import static android.view.WindowManager.LayoutParams.INPUT_FEATURE_SPY;
import static android.view.WindowManager.LayoutParams.INVALID_WINDOW_TYPE;
+import static android.view.WindowManager.LayoutParams.PRIVATE_FLAG_TRUSTED_OVERLAY;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION;
import static android.view.WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
import static android.view.WindowManager.LayoutParams.TYPE_BASE_APPLICATION;
@@ -49,11 +52,13 @@
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThrows;
import static org.junit.Assert.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
+import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
@@ -67,12 +72,16 @@
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.InputConfig;
+import android.os.Process;
import android.os.RemoteException;
import android.os.UserHandle;
import android.platform.test.annotations.Presubmit;
import android.util.DisplayMetrics;
import android.util.MergedConfiguration;
+import android.view.IWindow;
import android.view.IWindowSessionCallback;
+import android.view.InputChannel;
import android.view.InsetsSourceControl;
import android.view.InsetsState;
import android.view.Surface;
@@ -108,6 +117,20 @@
ADD_TRUSTED_DISPLAY);
@Test
+ public void testIsRequestedOrientationMapped() {
+ mWm.setOrientationRequestPolicy(/* isIgnoreOrientationRequestDisabled*/ true,
+ /* fromOrientations */ new int[]{1}, /* toOrientations */ new int[]{2});
+ assertThat(mWm.mapOrientationRequest(1)).isEqualTo(2);
+ assertThat(mWm.mapOrientationRequest(3)).isEqualTo(3);
+
+ // Mapping disabled
+ mWm.setOrientationRequestPolicy(/* isIgnoreOrientationRequestDisabled*/ false,
+ /* fromOrientations */ null, /* toOrientations */ null);
+ assertThat(mWm.mapOrientationRequest(1)).isEqualTo(1);
+ assertThat(mWm.mapOrientationRequest(3)).isEqualTo(3);
+ }
+
+ @Test
public void testAddWindowToken() {
IBinder token = mock(IBinder.class);
mWm.addWindowToken(token, TYPE_TOAST, mDisplayContent.getDisplayId(), null /* options */);
@@ -690,6 +713,102 @@
assertEquals(validRect, resultingArgs.mSourceCrop);
}
+ @Test
+ public void testGrantInputChannel_sanitizeSpyWindowForApplications() {
+ final Session session = mock(Session.class);
+ final int callingUid = Process.FIRST_APPLICATION_UID;
+ final int callingPid = 1234;
+ final SurfaceControl surfaceControl = mock(SurfaceControl.class);
+ final IWindow window = mock(IWindow.class);
+ final IBinder windowToken = mock(IBinder.class);
+ when(window.asBinder()).thenReturn(windowToken);
+ final IBinder focusGrantToken = mock(IBinder.class);
+
+ final InputChannel inputChannel = new InputChannel();
+ assertThrows(IllegalArgumentException.class, () ->
+ mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY,
+ surfaceControl, window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE,
+ PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY, TYPE_APPLICATION,
+ null /* windowToken */, focusGrantToken, "TestInputChannel",
+ inputChannel));
+ }
+
+ @Test
+ public void testGrantInputChannel_allowSpyWindowForInputMonitorPermission() {
+ final Session session = mock(Session.class);
+ final int callingUid = Process.SYSTEM_UID;
+ final int callingPid = 1234;
+ final SurfaceControl surfaceControl = mock(SurfaceControl.class);
+ final IWindow window = mock(IWindow.class);
+ final IBinder windowToken = mock(IBinder.class);
+ when(window.asBinder()).thenReturn(windowToken);
+ final IBinder focusGrantToken = mock(IBinder.class);
+
+ final InputChannel inputChannel = new InputChannel();
+ mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY, surfaceControl,
+ window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY,
+ INPUT_FEATURE_SPY, TYPE_APPLICATION, null /* windowToken */, focusGrantToken,
+ "TestInputChannel", inputChannel);
+
+ verify(mTransaction).setInputWindowInfo(
+ eq(surfaceControl),
+ argThat(h -> (h.inputConfig & InputConfig.SPY) == InputConfig.SPY));
+ }
+
+ @Test
+ public void testUpdateInputChannel_sanitizeSpyWindowForApplications() {
+ final Session session = mock(Session.class);
+ final int callingUid = Process.FIRST_APPLICATION_UID;
+ final int callingPid = 1234;
+ final SurfaceControl surfaceControl = mock(SurfaceControl.class);
+ final IWindow window = mock(IWindow.class);
+ final IBinder windowToken = mock(IBinder.class);
+ when(window.asBinder()).thenReturn(windowToken);
+ final IBinder focusGrantToken = mock(IBinder.class);
+
+ final InputChannel inputChannel = new InputChannel();
+ mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY, surfaceControl,
+ window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY,
+ 0 /* inputFeatures */, TYPE_APPLICATION, null /* windowToken */, focusGrantToken,
+ "TestInputChannel", inputChannel);
+ verify(mTransaction).setInputWindowInfo(
+ eq(surfaceControl),
+ argThat(h -> (h.inputConfig & InputConfig.SPY) == 0));
+
+ assertThrows(IllegalArgumentException.class, () ->
+ mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
+ FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY,
+ null /* region */));
+ }
+
+ @Test
+ public void testUpdateInputChannel_allowSpyWindowForInputMonitorPermission() {
+ final Session session = mock(Session.class);
+ final int callingUid = Process.SYSTEM_UID;
+ final int callingPid = 1234;
+ final SurfaceControl surfaceControl = mock(SurfaceControl.class);
+ final IWindow window = mock(IWindow.class);
+ final IBinder windowToken = mock(IBinder.class);
+ when(window.asBinder()).thenReturn(windowToken);
+ final IBinder focusGrantToken = mock(IBinder.class);
+
+ final InputChannel inputChannel = new InputChannel();
+ mWm.grantInputChannel(session, callingUid, callingPid, DEFAULT_DISPLAY, surfaceControl,
+ window, null /* hostInputToken */, FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY,
+ 0 /* inputFeatures */, TYPE_APPLICATION, null /* windowToken */, focusGrantToken,
+ "TestInputChannel", inputChannel);
+ verify(mTransaction).setInputWindowInfo(
+ eq(surfaceControl),
+ argThat(h -> (h.inputConfig & InputConfig.SPY) == 0));
+
+ mWm.updateInputChannel(inputChannel.getToken(), DEFAULT_DISPLAY, surfaceControl,
+ FLAG_NOT_FOCUSABLE, PRIVATE_FLAG_TRUSTED_OVERLAY, INPUT_FEATURE_SPY,
+ null /* region */);
+ verify(mTransaction).setInputWindowInfo(
+ eq(surfaceControl),
+ argThat(h -> (h.inputConfig & InputConfig.SPY) == InputConfig.SPY));
+ }
+
private void setupActivityWithLaunchCookie(IBinder launchCookie, WindowContainerToken wct) {
final WindowContainer.RemoteToken remoteToken = mock(WindowContainer.RemoteToken.class);
when(remoteToken.toWindowContainerToken()).thenReturn(wct);
diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
index b80500a..0d7cdc8 100644
--- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
+++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java
@@ -1746,7 +1746,8 @@
static class TestTransitionController extends TransitionController {
TestTransitionController(ActivityTaskManagerService atms) {
super(atms);
- mTaskSnapshotController = mock(TaskSnapshotController.class);
+ doReturn(this).when(atms).getTransitionController();
+ mSnapshotController = mock(SnapshotController.class);
mTransitionTracer = mock(TransitionTracer.class);
}
}
diff --git a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java b/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java
index f5f9b84..d49214a 100644
--- a/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java
+++ b/services/texttospeech/java/com/android/server/texttospeech/TextToSpeechManagerPerUserService.java
@@ -95,7 +95,7 @@
ITextToSpeechSessionCallback callback) {
super(context,
new Intent(TextToSpeech.Engine.INTENT_ACTION_TTS_SERVICE).setPackage(engine),
- Context.BIND_AUTO_CREATE,
+ Context.BIND_AUTO_CREATE | Context.BIND_SCHEDULE_LIKE_TOP_APP,
userId,
ITextToSpeechService.Stub::asInterface);
mEngine = engine;
diff --git a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
index 2d382a2..79046db 100644
--- a/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
+++ b/services/translation/java/com/android/server/translation/TranslationManagerServiceImpl.java
@@ -37,6 +37,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.os.IRemoteCallback;
@@ -160,11 +161,20 @@
return null;
}
final ComponentName serviceComponent = ComponentName.unflattenFromString(serviceName);
- if (!isServiceAvailableForUser(serviceComponent)) {
+ boolean isServiceAvailableForUser;
+ final long identity = Binder.clearCallingIdentity();
+ try {
+ isServiceAvailableForUser = isServiceAvailableForUser(serviceComponent);
if (mMaster.verbose) {
- Slog.v(TAG, "ensureRemoteServiceLocked(): " + serviceComponent
- + " is not available,");
+ Slog.v(TAG, "ensureRemoteServiceLocked(): isServiceAvailableForUser="
+ + isServiceAvailableForUser);
}
+ } finally {
+ Binder.restoreCallingIdentity(identity);
+ }
+ if (!isServiceAvailableForUser) {
+ Slog.w(TAG, "ensureRemoteServiceLocked(): " + serviceComponent
+ + " is not available,");
return null;
}
mRemoteTranslationService = new RemoteTranslationService(getContext(), serviceComponent,
diff --git a/services/usage/java/com/android/server/usage/UsageStatsService.java b/services/usage/java/com/android/server/usage/UsageStatsService.java
index 7ff5b4a..8948e494 100644
--- a/services/usage/java/com/android/server/usage/UsageStatsService.java
+++ b/services/usage/java/com/android/server/usage/UsageStatsService.java
@@ -3129,6 +3129,11 @@
}
@Override
+ public void setAdminProtectedPackages(Set<String> packageNames, int userId) {
+ mAppStandby.setAdminProtectedPackages(packageNames, userId);
+ }
+
+ @Override
public void onAdminDataAvailable() {
mAppStandby.onAdminDataAvailable();
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java
index dbc824c..cd29dac 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/DetectorSession.java
@@ -26,6 +26,7 @@
import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_SUCCESS;
import static android.service.voice.HotwordDetectionService.INITIALIZATION_STATUS_UNKNOWN;
import static android.service.voice.HotwordDetectionService.KEY_INITIALIZATION_STATUS;
+import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_COPY_AUDIO_DATA_FAILURE;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_ERROR;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTION_SERVICE_INIT_RESULT_REPORTED__RESULT__CALLBACK_INIT_STATE_SUCCESS;
@@ -68,7 +69,6 @@
import android.os.PersistableBundle;
import android.os.RemoteException;
import android.os.SharedMemory;
-import android.service.voice.DetectorFailure;
import android.service.voice.HotwordDetectedResult;
import android.service.voice.HotwordDetectionService;
import android.service.voice.HotwordDetectionServiceFailure;
@@ -76,6 +76,7 @@
import android.service.voice.HotwordRejectedResult;
import android.service.voice.IDspHotwordDetectionCallback;
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
+import android.service.voice.VisualQueryDetectionServiceFailure;
import android.text.TextUtils;
import android.util.Pair;
import android.util.Slog;
@@ -124,17 +125,12 @@
private static final String HOTWORD_DETECTION_OP_MESSAGE =
"Providing hotword detection result to VoiceInteractionService";
- // The error codes are used for onError callback
- static final int HOTWORD_DETECTION_SERVICE_DIED =
- HotwordDetectionServiceFailure.ERROR_CODE_BINDING_DIED;
- static final int CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION =
+ // The error codes are used for onHotwordDetectionServiceFailure callback.
+ // Define these due to lines longer than 100 characters.
+ static final int ONDETECTED_GOT_SECURITY_EXCEPTION =
HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION;
- static final int CALLBACK_DETECT_TIMEOUT =
- HotwordDetectionServiceFailure.ERROR_CODE_DETECT_TIMEOUT;
- static final int CALLBACK_ONDETECTED_STREAM_COPY_ERROR =
+ static final int ONDETECTED_STREAM_COPY_ERROR =
HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE;
- static final int CALLBACK_COPY_AUDIO_DATA_FAILURE =
- HotwordDetectionServiceFailure.ERROR_CODE_COPY_AUDIO_DATA_FAILURE;
// TODO: These constants need to be refined.
private static final long MAX_UPDATE_TIMEOUT_MILLIS = 30000;
@@ -449,11 +445,11 @@
Slog.w(TAG, "Failed supplying audio data to validator", e);
try {
- callback.onError(
- new HotwordDetectionServiceFailure(CALLBACK_COPY_AUDIO_DATA_FAILURE,
+ callback.onHotwordDetectionServiceFailure(
+ new HotwordDetectionServiceFailure(ERROR_CODE_COPY_AUDIO_DATA_FAILURE,
"Copy audio data failure for external source detection."));
} catch (RemoteException ex) {
- Slog.w(TAG, "Failed to report onError status: " + ex);
+ Slog.w(TAG, "Failed to report onHotwordDetectionServiceFailure status: " + ex);
if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
HotwordMetricsLogger.writeDetectorEvent(getDetectorType(),
HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION,
@@ -538,10 +534,11 @@
EXTERNAL_SOURCE_DETECT_SECURITY_EXCEPTION,
mVoiceInteractionServiceUid);
try {
- callback.onError(new HotwordDetectionServiceFailure(
- CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION,
- "Security exception occurs in #onDetected"
- + " method."));
+ callback.onHotwordDetectionServiceFailure(
+ new HotwordDetectionServiceFailure(
+ ONDETECTED_GOT_SECURITY_EXCEPTION,
+ "Security exception occurs in "
+ + "#onDetected method"));
} catch (RemoteException e1) {
notifyOnDetectorRemoteException();
throw e1;
@@ -557,9 +554,10 @@
+ "IOException", e);
// TODO: Write event
try {
- callback.onError(new HotwordDetectionServiceFailure(
- CALLBACK_ONDETECTED_STREAM_COPY_ERROR,
- "Copy audio stream failure."));
+ callback.onHotwordDetectionServiceFailure(
+ new HotwordDetectionServiceFailure(
+ ONDETECTED_STREAM_COPY_ERROR,
+ "Copy audio stream failure."));
} catch (RemoteException e1) {
notifyOnDetectorRemoteException();
throw e1;
@@ -624,17 +622,40 @@
mRemoteDetectionService = remoteDetectionService;
}
- void reportErrorLocked(@NonNull DetectorFailure detectorFailure) {
+ private void reportErrorGetRemoteException() {
+ if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
+ HotwordMetricsLogger.writeDetectorEvent(getDetectorType(),
+ HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION,
+ mVoiceInteractionServiceUid);
+ }
+ notifyOnDetectorRemoteException();
+ }
+
+ void reportErrorLocked(@NonNull HotwordDetectionServiceFailure hotwordDetectionServiceFailure) {
try {
- mCallback.onDetectionFailure(detectorFailure);
+ mCallback.onHotwordDetectionServiceFailure(hotwordDetectionServiceFailure);
} catch (RemoteException e) {
- Slog.w(TAG, "Failed to report onError status: " + e);
- if (getDetectorType() != HotwordDetector.DETECTOR_TYPE_VISUAL_QUERY_DETECTOR) {
- HotwordMetricsLogger.writeDetectorEvent(getDetectorType(),
- HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION,
- mVoiceInteractionServiceUid);
- }
- notifyOnDetectorRemoteException();
+ Slog.w(TAG, "Failed to call onHotwordDetectionServiceFailure: " + e);
+ reportErrorGetRemoteException();
+ }
+ }
+
+ void reportErrorLocked(
+ @NonNull VisualQueryDetectionServiceFailure visualQueryDetectionServiceFailure) {
+ try {
+ mCallback.onVisualQueryDetectionServiceFailure(visualQueryDetectionServiceFailure);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onVisualQueryDetectionServiceFailure: " + e);
+ reportErrorGetRemoteException();
+ }
+ }
+
+ void reportErrorLocked(@NonNull String errorMessage) {
+ try {
+ mCallback.onUnknownFailure(errorMessage);
+ } catch (RemoteException e) {
+ Slog.w(TAG, "Failed to call onUnknownFailure: " + e);
+ reportErrorGetRemoteException();
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/DspTrustedHotwordDetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/DspTrustedHotwordDetectorSession.java
index f9b5111..9a4fbdc 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/DspTrustedHotwordDetectorSession.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/DspTrustedHotwordDetectorSession.java
@@ -16,6 +16,10 @@
package com.android.server.voiceinteraction;
+import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_DETECT_TIMEOUT;
+import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION;
+import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE;
+
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_DETECTED_EXCEPTION;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_PROCESS_RESTARTED_EXCEPTION;
@@ -135,9 +139,10 @@
METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION,
mVoiceInteractionServiceUid);
try {
- externalCallback.onDetectionFailure(new HotwordDetectionServiceFailure(
- CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION,
- "Security exception occurs in #onDetected method."));
+ externalCallback.onHotwordDetectionServiceFailure(
+ new HotwordDetectionServiceFailure(
+ ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION,
+ "Security exception occurs in #onDetected method."));
} catch (RemoteException e1) {
notifyOnDetectorRemoteException();
HotwordMetricsLogger.writeDetectorEvent(
@@ -155,9 +160,10 @@
} catch (IOException e) {
try {
Slog.w(TAG, "Ignoring #onDetected due to a IOException", e);
- externalCallback.onDetectionFailure(new HotwordDetectionServiceFailure(
- CALLBACK_ONDETECTED_STREAM_COPY_ERROR,
- "Copy audio stream failure."));
+ externalCallback.onHotwordDetectionServiceFailure(
+ new HotwordDetectionServiceFailure(
+ ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE,
+ "Copy audio stream failure."));
} catch (RemoteException e1) {
notifyOnDetectorRemoteException();
throw e1;
@@ -242,8 +248,8 @@
HOTWORD_DETECTOR_KEYPHRASE_TRIGGERED__RESULT__DETECT_TIMEOUT,
mVoiceInteractionServiceUid);
try {
- externalCallback.onDetectionFailure(
- new HotwordDetectionServiceFailure(CALLBACK_DETECT_TIMEOUT,
+ externalCallback.onHotwordDetectionServiceFailure(
+ new HotwordDetectionServiceFailure(ERROR_CODE_DETECT_TIMEOUT,
"Timeout to response to the detection result."));
} catch (RemoteException e) {
Slog.w(TAG, "Failed to report onError status: ", e);
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
index 4fd5979..3eabea6 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/HotwordDetectionConnection.java
@@ -56,7 +56,6 @@
import android.service.voice.IMicrophoneHotwordDetectionVoiceInteractionCallback;
import android.service.voice.ISandboxedDetectionService;
import android.service.voice.IVisualQueryDetectionVoiceInteractionCallback;
-import android.service.voice.UnknownFailure;
import android.service.voice.VisualQueryDetectionService;
import android.service.voice.VisualQueryDetectionServiceFailure;
import android.service.voice.VoiceInteractionManagerInternal.HotwordDetectionServiceIdentity;
@@ -786,8 +785,8 @@
VisualQueryDetectionServiceFailure.ERROR_CODE_BINDING_DIED,
"Detection service is dead."));
} else {
- detectorSession.reportErrorLocked(new UnknownFailure(
- "Detection service is dead with unknown detection service type."));
+ detectorSession.reportErrorLocked(
+ "Detection service is dead with unknown detection service type.");
}
}
@@ -804,8 +803,8 @@
VisualQueryDetectionServiceFailure.ERROR_CODE_BIND_FAILURE,
"Bind detection service failure."));
} else {
- detectorSession.reportErrorLocked(new UnknownFailure(
- "Bind detection service failure with unknown detection service type."));
+ detectorSession.reportErrorLocked(
+ "Bind detection service failure with unknown detection service type.");
}
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoftwareTrustedHotwordDetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoftwareTrustedHotwordDetectorSession.java
index 367fb81..f06c997 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/SoftwareTrustedHotwordDetectorSession.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/SoftwareTrustedHotwordDetectorSession.java
@@ -17,6 +17,8 @@
package com.android.server.voiceinteraction;
import static android.service.voice.HotwordDetectionService.AUDIO_SOURCE_MICROPHONE;
+import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION;
+import static android.service.voice.HotwordDetectionServiceFailure.ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_DETECTED_EXCEPTION;
import static com.android.internal.util.FrameworkStatsLog.HOTWORD_DETECTOR_EVENTS__EVENT__CALLBACK_ON_ERROR_EXCEPTION;
@@ -128,9 +130,10 @@
METRICS_KEYPHRASE_TRIGGERED_DETECT_SECURITY_EXCEPTION,
mVoiceInteractionServiceUid);
try {
- mSoftwareCallback.onError(new HotwordDetectionServiceFailure(
- CALLBACK_ONDETECTED_GOT_SECURITY_EXCEPTION,
- "Security exception occurs in #onDetected method."));
+ mSoftwareCallback.onHotwordDetectionServiceFailure(
+ new HotwordDetectionServiceFailure(
+ ERROR_CODE_ON_DETECTED_SECURITY_EXCEPTION,
+ "Security exception occurs in #onDetected method."));
} catch (RemoteException e1) {
notifyOnDetectorRemoteException();
HotwordMetricsLogger.writeDetectorEvent(
@@ -149,9 +152,10 @@
Slog.w(TAG, "Ignoring #onDetected due to a IOException", e);
// TODO: Write event
try {
- mSoftwareCallback.onError(new HotwordDetectionServiceFailure(
- CALLBACK_ONDETECTED_STREAM_COPY_ERROR,
- "Copy audio stream failure."));
+ mSoftwareCallback.onHotwordDetectionServiceFailure(
+ new HotwordDetectionServiceFailure(
+ ERROR_CODE_ON_DETECTED_STREAM_COPY_FAILURE,
+ "Copy audio stream failure."));
} catch (RemoteException e1) {
notifyOnDetectorRemoteException();
HotwordMetricsLogger.writeDetectorEvent(
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java
index afe5dab..aadb38d 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VisualQueryDetectorSession.java
@@ -110,11 +110,12 @@
} catch (RemoteException e) {
Slog.e(TAG, "Error delivering attention gained event.", e);
try {
- callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_ATTENTION_STATE,
- "Attention listener failed to switch to GAINED state."));
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_ATTENTION_STATE,
+ "Attention listener failed to switch to GAINED state."));
} catch (RemoteException ex) {
- Slog.v(TAG, "Fail to call onDetectionFailure");
+ Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
}
return;
}
@@ -132,11 +133,12 @@
} catch (RemoteException e) {
Slog.e(TAG, "Error delivering attention lost event.", e);
try {
- callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_ATTENTION_STATE,
- "Attention listener failed to switch to LOST state."));
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_ATTENTION_STATE,
+ "Attention listener failed to switch to LOST state."));
} catch (RemoteException ex) {
- Slog.v(TAG, "Fail to call onDetectionFailure");
+ Slog.v(TAG, "Fail to call onVisualQueryDetectionServiceFailure");
}
return;
}
@@ -148,9 +150,10 @@
Slog.v(TAG, "BinderCallback#onQueryDetected");
if (!mEgressingData) {
Slog.v(TAG, "Query should not be egressed within the unattention state.");
- callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_STREAMING_STATE,
- "Cannot stream queries without attention signals."));
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_STREAMING_STATE,
+ "Cannot stream queries without attention signals."));
return;
}
mQueryStreaming = true;
@@ -164,9 +167,10 @@
if (!mQueryStreaming) {
Slog.v(TAG, "Query streaming state signal FINISHED is block since there is"
+ " no active query being streamed.");
- callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_STREAMING_STATE,
- "Cannot send FINISHED signal with no query streamed."));
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_STREAMING_STATE,
+ "Cannot send FINISHED signal with no query streamed."));
return;
}
callback.onQueryFinished();
@@ -179,9 +183,10 @@
if (!mQueryStreaming) {
Slog.v(TAG, "Query streaming state signal REJECTED is block since there is"
+ " no active query being streamed.");
- callback.onDetectionFailure(new VisualQueryDetectionServiceFailure(
- ERROR_CODE_ILLEGAL_STREAMING_STATE,
- "Cannot send REJECTED signal with no query streamed."));
+ callback.onVisualQueryDetectionServiceFailure(
+ new VisualQueryDetectionServiceFailure(
+ ERROR_CODE_ILLEGAL_STREAMING_STATE,
+ "Cannot send REJECTED signal with no query streamed."));
return;
}
callback.onQueryRejected();
diff --git a/telecomm/java/android/telecom/Call.java b/telecomm/java/android/telecom/Call.java
index c152a41..1da4ea9 100644
--- a/telecomm/java/android/telecom/Call.java
+++ b/telecomm/java/android/telecom/Call.java
@@ -24,6 +24,7 @@
import android.compat.annotation.UnsupportedAppUsage;
import android.content.pm.ServiceInfo;
import android.net.Uri;
+import android.os.BadParcelableException;
import android.os.Build;
import android.os.Bundle;
import android.os.Handler;
@@ -2951,21 +2952,27 @@
for(String key : bundle.keySet()) {
if (key != null) {
- final Object value = bundle.get(key);
- final Object newValue = newBundle.get(key);
if (!newBundle.containsKey(key)) {
return false;
}
- if (value instanceof Bundle && newValue instanceof Bundle) {
- if (!areBundlesEqual((Bundle) value, (Bundle) newValue)) {
+ // In case new call extra contains non-framework class objects, return false to
+ // force update the call extra
+ try {
+ final Object value = bundle.get(key);
+ final Object newValue = newBundle.get(key);
+ if (value instanceof Bundle && newValue instanceof Bundle) {
+ if (!areBundlesEqual((Bundle) value, (Bundle) newValue)) {
+ return false;
+ }
+ }
+ if (value instanceof byte[] && newValue instanceof byte[]) {
+ if (!Arrays.equals((byte[]) value, (byte[]) newValue)) {
+ return false;
+ }
+ } else if (!Objects.equals(value, newValue)) {
return false;
}
- }
- if (value instanceof byte[] && newValue instanceof byte[]) {
- if (!Arrays.equals((byte[]) value, (byte[]) newValue)) {
- return false;
- }
- } else if (!Objects.equals(value, newValue)) {
+ } catch (BadParcelableException e) {
return false;
}
}
diff --git a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
index 0325ba6..f9b76f4 100644
--- a/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
+++ b/telephony/common/com/android/internal/telephony/util/TelephonyUtils.java
@@ -20,6 +20,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.app.ActivityManager;
+import android.app.role.RoleManager;
import android.content.Context;
import android.content.pm.ComponentInfo;
import android.content.pm.PackageManager;
@@ -255,15 +256,26 @@
* Show switch to managed profile dialog if subscription is associated with managed profile.
*
* @param context Context object
- * @param subId subscription id
+ * @param subId subscription id
+ * @param callingUid uid for the calling app
+ * @param callingPackage package name of the calling app
*/
- public static void showErrorIfSubscriptionAssociatedWithManagedProfile(Context context,
- int subId) {
+ public static void showSwitchToManagedProfileDialogIfAppropriate(Context context,
+ int subId, int callingUid, String callingPackage) {
if (!isSwitchToManagedProfileDialogFlagEnabled()) {
return;
}
final long token = Binder.clearCallingIdentity();
try {
+ UserHandle callingUserHandle = UserHandle.getUserHandleForUid(callingUid);
+ // We only want to show this dialog, while user actually trying to send the message from
+ // a messaging app, in other cases this dialog don't make sense.
+ if (!TelephonyUtils.isUidForeground(context, callingUid)
+ || !TelephonyUtils.isPackageSMSRoleHolderForUser(context, callingPackage,
+ callingUserHandle)) {
+ return;
+ }
+
SubscriptionManager subscriptionManager = context.getSystemService(
SubscriptionManager.class);
UserHandle associatedUserHandle = subscriptionManager.getSubscriptionUserHandle(subId);
@@ -295,22 +307,25 @@
"enable_switch_to_managed_profile_dialog", false);
}
- /**
- * Check if the process with given uid is foreground.
- *
- * @param context context
- * @param uid the caller uid
- * @return true if the process with uid is foreground, false otherwise.
- */
- public static boolean isUidForeground(Context context, int uid) {
- final long token = Binder.clearCallingIdentity();
- try {
- ActivityManager am = context.getSystemService(ActivityManager.class);
- boolean result = am != null && am.getUidImportance(uid)
- == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
- return result;
- } finally {
- Binder.restoreCallingIdentity(token);
+ private static boolean isUidForeground(Context context, int uid) {
+ ActivityManager am = context.getSystemService(ActivityManager.class);
+ boolean result = am != null && am.getUidImportance(uid)
+ == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND;
+ return result;
+ }
+
+ private static boolean isPackageSMSRoleHolderForUser(Context context, String callingPackage,
+ UserHandle user) {
+ RoleManager roleManager = context.getSystemService(RoleManager.class);
+ final List<String> smsRoleHolder = roleManager.getRoleHoldersAsUser(
+ RoleManager.ROLE_SMS, user);
+
+ // ROLE_SMS is an exclusive role per user, so there would just be one entry in the
+ // retuned list if not empty
+ if (!smsRoleHolder.isEmpty() && callingPackage.equals(smsRoleHolder.get(0))) {
+ return true;
}
+ return false;
+
}
}
\ No newline at end of file
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 212dc41..ba4a54e 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -4444,6 +4444,22 @@
"min_udp_port_4500_nat_timeout_sec_int";
/**
+ * The preferred IKE protocol for ESP packets.
+ *
+ * This will be used by Android platform VPNs to select preferred encapsulation type and IP
+ * protocol type. The possible customization values are:
+ *
+ * AUTO IP VERSION and ENCAPSULATION TYPE SELECTION : "0"
+ * IPv4 UDP : "40"
+ * IPv6 ESP : "61"
+ *
+ * See the {@code PREFERRED_IKE_PROTOCOL_} constants in
+ * {@link com.android.server.connectivity.Vpn}.
+ * @hide
+ */
+ public static final String KEY_PREFERRED_IKE_PROTOCOL_INT = "preferred_ike_protocol_int";
+
+ /**
* Specifies whether the system should prefix the EAP method to the anonymous identity.
* The following prefix will be added if this key is set to TRUE:
* EAP-AKA: "0"
@@ -8654,6 +8670,16 @@
public static final String KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY =
KEY_PREFIX + "epdg_address_priority_int_array";
+ /**
+ * A priority list of PLMN to be used in EPDG_ADDRESS_PLMN. Possible values are {@link
+ * #EPDG_PLMN_RPLMN}, {@link #EPDG_PLMN_HPLMN}, {@link #EPDG_PLMN_EHPLMN_ALL}, {@link
+ * #EPDG_PLMN_EHPLMN_FIRST}
+ *
+ * @hide
+ */
+ public static final String KEY_EPDG_PLMN_PRIORITY_INT_ARRAY =
+ KEY_PREFIX + "epdg_plmn_priority_int_array";
+
/** Epdg static IP address or FQDN */
public static final String KEY_EPDG_STATIC_ADDRESS_STRING =
KEY_PREFIX + "epdg_static_address_string";
@@ -8854,6 +8880,36 @@
public static final int EPDG_ADDRESS_VISITED_COUNTRY = 4;
/** @hide */
+ @IntDef({
+ EPDG_PLMN_RPLMN,
+ EPDG_PLMN_HPLMN,
+ EPDG_PLMN_EHPLMN_ALL,
+ EPDG_PLMN_EHPLMN_FIRST
+ })
+ public @interface EpdgAddressPlmnType {}
+
+ /**
+ * Use the Registered PLMN
+ * @hide
+ */
+ public static final int EPDG_PLMN_RPLMN = 0;
+ /**
+ * Use the PLMN derived from IMSI
+ * @hide
+ */
+ public static final int EPDG_PLMN_HPLMN = 1;
+ /**
+ * Use all EHPLMN from SIM EF files
+ * @hide
+ */
+ public static final int EPDG_PLMN_EHPLMN_ALL = 2;
+ /**
+ * Use the first EHPLMN from SIM EF files
+ * @hide
+ */
+ public static final int EPDG_PLMN_EHPLMN_FIRST = 3;
+
+ /** @hide */
@IntDef({ID_TYPE_FQDN, ID_TYPE_RFC822_ADDR, ID_TYPE_KEY_ID})
public @interface IkeIdType {}
@@ -8988,6 +9044,12 @@
defaults.putIntArray(
KEY_EPDG_ADDRESS_PRIORITY_INT_ARRAY,
new int[] {EPDG_ADDRESS_PLMN, EPDG_ADDRESS_STATIC});
+ defaults.putIntArray(
+ KEY_EPDG_PLMN_PRIORITY_INT_ARRAY,
+ new int[]{
+ EPDG_PLMN_RPLMN,
+ EPDG_PLMN_HPLMN,
+ EPDG_PLMN_EHPLMN_ALL});
defaults.putStringArray(KEY_MCC_MNCS_STRING_ARRAY, new String[0]);
defaults.putInt(KEY_IKE_LOCAL_ID_TYPE_INT, ID_TYPE_RFC822_ADDR);
defaults.putInt(KEY_IKE_REMOTE_ID_TYPE_INT, ID_TYPE_FQDN);
@@ -10130,6 +10192,7 @@
sDefaults.putInt(KEY_PARAMETERS_USED_FOR_LTE_SIGNAL_BAR_INT,
CellSignalStrengthLte.USE_RSRP);
sDefaults.putInt(KEY_MIN_UDP_PORT_4500_NAT_TIMEOUT_SEC_INT, 300);
+ sDefaults.putInt(KEY_PREFERRED_IKE_PROTOCOL_INT, 0);
// Default wifi configurations.
sDefaults.putAll(Wifi.getDefaults());
sDefaults.putBoolean(ENABLE_EAP_METHOD_PREFIX_BOOL, false);
diff --git a/telephony/java/android/telephony/SubscriptionManager.java b/telephony/java/android/telephony/SubscriptionManager.java
index 5cbbe37..286e71c 100644
--- a/telephony/java/android/telephony/SubscriptionManager.java
+++ b/telephony/java/android/telephony/SubscriptionManager.java
@@ -4439,7 +4439,6 @@
*
* @throws IllegalArgumentException if subscription is invalid.
* @throws SecurityException if the caller doesn't have permissions required.
- * @throws IllegalStateException if subscription service is not available.
*
* @hide
*/
@@ -4456,8 +4455,8 @@
if (iSub != null) {
return iSub.isSubscriptionAssociatedWithUser(subscriptionId, userHandle);
} else {
- throw new IllegalStateException("[isSubscriptionAssociatedWithUser]: "
- + "subscription service unavailable");
+ Log.e(LOG_TAG, "[isSubscriptionAssociatedWithUser]: subscription service "
+ + "unavailable");
}
} catch (RemoteException ex) {
ex.rethrowAsRuntimeException();
@@ -4484,7 +4483,7 @@
if (iSub != null) {
return iSub.getSubscriptionInfoListAssociatedWithUser(userHandle);
} else {
- throw new IllegalStateException("[getSubscriptionInfoListAssociatedWithUser]: "
+ Log.e(LOG_TAG, "[getSubscriptionInfoListAssociatedWithUser]: "
+ "subscription service unavailable");
}
} catch (RemoteException ex) {
diff --git a/telephony/java/android/telephony/TelephonyManager.java b/telephony/java/android/telephony/TelephonyManager.java
index 3f5c76d..0aff4ea 100644
--- a/telephony/java/android/telephony/TelephonyManager.java
+++ b/telephony/java/android/telephony/TelephonyManager.java
@@ -3511,7 +3511,15 @@
public static final String ACTION_SECRET_CODE = "android.telephony.action.SECRET_CODE";
/**
- * @return true if a ICC card is present
+ * This API is used to check if there is an ICC card present in the device.
+ *
+ * An ICC card is a smart card that contains a subscriber identity module (SIM) and is used
+ * to identify and authenticate users to a mobile network.
+ *
+ * Note: In case of embedded SIM there is an ICC card always present irrespective
+ * of whether an active SIM profile is present or not so this API would always return true.
+ *
+ * @return true if a ICC card is present.
*/
@RequiresFeature(PackageManager.FEATURE_TELEPHONY_SUBSCRIPTION)
public boolean hasIccCard() {
diff --git a/telephony/java/android/telephony/satellite/ISatelliteTransmissionUpdateCallback.aidl b/telephony/java/android/telephony/satellite/ISatelliteTransmissionUpdateCallback.aidl
index 2442083..a81444d 100644
--- a/telephony/java/android/telephony/satellite/ISatelliteTransmissionUpdateCallback.aidl
+++ b/telephony/java/android/telephony/satellite/ISatelliteTransmissionUpdateCallback.aidl
@@ -24,15 +24,22 @@
*/
oneway interface ISatelliteTransmissionUpdateCallback {
/**
- * Called when satellite datagram transfer state changed.
+ * Called when satellite datagram send state changed.
*
- * @param state The new datagram transfer state.
+ * @param state The new send datagram transfer state.
* @param sendPendingCount The number of datagrams that are currently being sent.
- * @param receivePendingCount The number of datagrams that are currently being received.
* @param errorCode If datagram transfer failed, the reason for failure.
*/
- void onDatagramTransferStateChanged(in int state, in int sendPendingCount,
- in int receivePendingCount, in int errorCode);
+ void onSendDatagramStateChanged(in int state, in int sendPendingCount, in int errorCode);
+
+ /**
+ * Called when satellite datagram receive state changed.
+ *
+ * @param state The new receive datagram transfer state.
+ * @param receivePendingCount The number of datagrams that are currently pending to be received.
+ * @param errorCode If datagram transfer failed, the reason for failure.
+ */
+ void onReceiveDatagramStateChanged(in int state, in int receivePendingCount, in int errorCode);
/**
* Called when the satellite position changed.
diff --git a/telephony/java/android/telephony/satellite/PointingInfo.java b/telephony/java/android/telephony/satellite/PointingInfo.java
index 7c794473..e8a8576 100644
--- a/telephony/java/android/telephony/satellite/PointingInfo.java
+++ b/telephony/java/android/telephony/satellite/PointingInfo.java
@@ -17,6 +17,7 @@
package android.telephony.satellite;
import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -33,6 +34,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public PointingInfo(float satelliteAzimuthDegrees, float satelliteElevationDegrees) {
mSatelliteAzimuthDegrees = satelliteAzimuthDegrees;
mSatelliteElevationDegrees = satelliteElevationDegrees;
diff --git a/telephony/java/android/telephony/satellite/SatelliteCapabilities.java b/telephony/java/android/telephony/satellite/SatelliteCapabilities.java
index df80159..87c8db3 100644
--- a/telephony/java/android/telephony/satellite/SatelliteCapabilities.java
+++ b/telephony/java/android/telephony/satellite/SatelliteCapabilities.java
@@ -17,6 +17,7 @@
package android.telephony.satellite;
import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -45,6 +46,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public SatelliteCapabilities(Set<Integer> supportedRadioTechnologies,
boolean isPointingRequired, int maxBytesPerOutgoingDatagram) {
mSupportedRadioTechnologies = supportedRadioTechnologies == null
diff --git a/telephony/java/android/telephony/satellite/SatelliteDatagram.java b/telephony/java/android/telephony/satellite/SatelliteDatagram.java
index d3cb8a0..44f56f3 100644
--- a/telephony/java/android/telephony/satellite/SatelliteDatagram.java
+++ b/telephony/java/android/telephony/satellite/SatelliteDatagram.java
@@ -17,6 +17,7 @@
package android.telephony.satellite;
import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -32,6 +33,7 @@
/**
* @hide
*/
+ @UnsupportedAppUsage
public SatelliteDatagram(@NonNull byte[] data) {
mData = data;
}
diff --git a/telephony/java/android/telephony/satellite/SatelliteDatagramCallback.java b/telephony/java/android/telephony/satellite/SatelliteDatagramCallback.java
index f237ada..d8a6faf 100644
--- a/telephony/java/android/telephony/satellite/SatelliteDatagramCallback.java
+++ b/telephony/java/android/telephony/satellite/SatelliteDatagramCallback.java
@@ -17,6 +17,7 @@
package android.telephony.satellite;
import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
import com.android.internal.telephony.ILongConsumer;
@@ -36,6 +37,7 @@
* datagramId to Telephony. If the callback is not received within five minutes,
* Telephony will resend the datagram.
*/
+ @UnsupportedAppUsage
void onSatelliteDatagramReceived(long datagramId, @NonNull SatelliteDatagram datagram,
int pendingCount, @NonNull ILongConsumer callback);
}
diff --git a/telephony/java/android/telephony/satellite/SatelliteManager.java b/telephony/java/android/telephony/satellite/SatelliteManager.java
index d0abfbf..7d82fd8 100644
--- a/telephony/java/android/telephony/satellite/SatelliteManager.java
+++ b/telephony/java/android/telephony/satellite/SatelliteManager.java
@@ -23,6 +23,7 @@
import android.annotation.Nullable;
import android.annotation.RequiresFeature;
import android.annotation.RequiresPermission;
+import android.compat.annotation.UnsupportedAppUsage;
import android.content.Context;
import android.content.pm.PackageManager;
import android.os.Binder;
@@ -82,6 +83,7 @@
* @param context The context the SatelliteManager belongs to.
* @hide
*/
+ @UnsupportedAppUsage
public SatelliteManager(@Nullable Context context) {
this(context, SubscriptionManager.DEFAULT_SUBSCRIPTION_ID);
}
@@ -127,6 +129,7 @@
* {@link #requestIsSatelliteEnabled(Executor, OutcomeReceiver)}.
* @hide
*/
+ @UnsupportedAppUsage
public static final String KEY_SATELLITE_ENABLED = "satellite_enabled";
/**
@@ -134,6 +137,7 @@
* {@link #requestIsDemoModeEnabled(Executor, OutcomeReceiver)}.
* @hide
*/
+ @UnsupportedAppUsage
public static final String KEY_DEMO_MODE_ENABLED = "demo_mode_enabled";
/**
@@ -141,6 +145,7 @@
* {@link #requestIsSatelliteSupported(Executor, OutcomeReceiver)}.
* @hide
*/
+ @UnsupportedAppUsage
public static final String KEY_SATELLITE_SUPPORTED = "satellite_supported";
/**
@@ -148,6 +153,7 @@
* {@link #requestSatelliteCapabilities(Executor, OutcomeReceiver)}.
* @hide
*/
+ @UnsupportedAppUsage
public static final String KEY_SATELLITE_CAPABILITIES = "satellite_capabilities";
/**
@@ -155,6 +161,7 @@
* {@link #requestIsSatelliteProvisioned(Executor, OutcomeReceiver)}.
* @hide
*/
+ @UnsupportedAppUsage
public static final String KEY_SATELLITE_PROVISIONED = "satellite_provisioned";
/**
@@ -162,6 +169,7 @@
* {@link #requestIsSatelliteCommunicationAllowedForCurrentLocation(Executor, OutcomeReceiver)}.
* @hide
*/
+ @UnsupportedAppUsage
public static final String KEY_SATELLITE_COMMUNICATION_ALLOWED =
"satellite_communication_allowed";
@@ -170,6 +178,7 @@
* {@link #requestTimeForNextSatelliteVisibility(Executor, OutcomeReceiver)}.
* @hide
*/
+ @UnsupportedAppUsage
public static final String KEY_SATELLITE_NEXT_VISIBILITY = "satellite_next_visibility";
/**
@@ -340,6 +349,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void requestSatelliteEnabled(boolean enableSatellite, boolean enableDemoMode,
@NonNull @CallbackExecutor Executor executor,
@SatelliteError @NonNull Consumer<Integer> resultListener) {
@@ -382,6 +392,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void requestIsSatelliteEnabled(@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
Objects.requireNonNull(executor);
@@ -436,6 +447,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void requestIsDemoModeEnabled(@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
Objects.requireNonNull(executor);
@@ -488,6 +500,7 @@
*
* @throws IllegalStateException if the Telephony process is not currently available.
*/
+ @UnsupportedAppUsage
public void requestIsSatelliteSupported(@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
Objects.requireNonNull(executor);
@@ -541,6 +554,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void requestSatelliteCapabilities(@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<SatelliteCapabilities, SatelliteException> callback) {
Objects.requireNonNull(executor);
@@ -647,6 +661,7 @@
})
@Retention(RetentionPolicy.SOURCE)
public @interface SatelliteDatagramTransferState {}
+ // TODO: Split into two enums for sending and receiving states
/**
* Satellite modem is in idle state.
@@ -706,6 +721,7 @@
*/
public static final int DATAGRAM_TYPE_LOCATION_SHARING = 2;
+ /** @hide */
@IntDef(prefix = "DATAGRAM_TYPE_", value = {
DATAGRAM_TYPE_UNKNOWN,
DATAGRAM_TYPE_SOS_MESSAGE,
@@ -731,6 +747,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void startSatelliteTransmissionUpdates(@NonNull @CallbackExecutor Executor executor,
@SatelliteError @NonNull Consumer<Integer> resultListener,
@NonNull SatelliteTransmissionUpdateCallback callback) {
@@ -750,20 +767,28 @@
};
ISatelliteTransmissionUpdateCallback internalCallback =
new ISatelliteTransmissionUpdateCallback.Stub() {
- @Override
- public void onDatagramTransferStateChanged(int state,
- int sendPendingCount, int receivePendingCount, int errorCode) {
- executor.execute(() -> Binder.withCleanCallingIdentity(
- () -> callback.onDatagramTransferStateChanged(
- state, sendPendingCount, receivePendingCount,
- errorCode)));
- }
@Override
public void onSatellitePositionChanged(PointingInfo pointingInfo) {
executor.execute(() -> Binder.withCleanCallingIdentity(
() -> callback.onSatellitePositionChanged(pointingInfo)));
}
+
+ @Override
+ public void onSendDatagramStateChanged(int state, int sendPendingCount,
+ int errorCode) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onSendDatagramStateChanged(
+ state, sendPendingCount, errorCode)));
+ }
+
+ @Override
+ public void onReceiveDatagramStateChanged(int state,
+ int receivePendingCount, int errorCode) {
+ executor.execute(() -> Binder.withCleanCallingIdentity(
+ () -> callback.onReceiveDatagramStateChanged(
+ state, receivePendingCount, errorCode)));
+ }
};
sSatelliteTransmissionUpdateCallbackMap.put(callback, internalCallback);
telephony.startSatelliteTransmissionUpdates(mSubId, errorCallback,
@@ -792,6 +817,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void stopSatelliteTransmissionUpdates(
@NonNull SatelliteTransmissionUpdateCallback callback,
@NonNull @CallbackExecutor Executor executor,
@@ -847,6 +873,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void provisionSatelliteService(@NonNull String token, @NonNull String regionId,
@Nullable CancellationSignal cancellationSignal,
@NonNull @CallbackExecutor Executor executor,
@@ -886,7 +913,7 @@
* {@link SatelliteProvisionStateCallback#onSatelliteProvisionStateChanged(boolean)}
* should report as deprovisioned.
* For provisioning satellite service, refer to
- * {@link #provisionSatelliteService(String, CancellationSignal, Executor, Consumer)}.
+ * {@link #provisionSatelliteService(String, String, CancellationSignal, Executor, Consumer)}
*
* @param token The token of the device/subscription to be deprovisioned.
* @param resultListener Listener for the {@link SatelliteError} result of the operation.
@@ -895,6 +922,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void deprovisionSatelliteService(@NonNull String token,
@NonNull @CallbackExecutor Executor executor,
@SatelliteError @NonNull Consumer<Integer> resultListener) {
@@ -934,6 +962,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
@SatelliteError public int registerForSatelliteProvisionStateChanged(
@NonNull @CallbackExecutor Executor executor,
@NonNull SatelliteProvisionStateCallback callback) {
@@ -976,6 +1005,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void unregisterForSatelliteProvisionStateChanged(
@NonNull SatelliteProvisionStateCallback callback) {
Objects.requireNonNull(callback);
@@ -1014,6 +1044,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void requestIsSatelliteProvisioned(@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
Objects.requireNonNull(executor);
@@ -1065,6 +1096,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
@SatelliteError public int registerForSatelliteModemStateChanged(
@NonNull @CallbackExecutor Executor executor,
@NonNull SatelliteStateCallback callback) {
@@ -1104,6 +1136,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void unregisterForSatelliteModemStateChanged(@NonNull SatelliteStateCallback callback) {
Objects.requireNonNull(callback);
ISatelliteStateCallback internalCallback = sSatelliteStateCallbackMap.remove(callback);
@@ -1138,6 +1171,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
@SatelliteError public int registerForSatelliteDatagram(
@NonNull @CallbackExecutor Executor executor,
@NonNull SatelliteDatagramCallback callback) {
@@ -1181,6 +1215,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void unregisterForSatelliteDatagram(@NonNull SatelliteDatagramCallback callback) {
Objects.requireNonNull(callback);
ISatelliteDatagramCallback internalCallback =
@@ -1218,6 +1253,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void pollPendingSatelliteDatagrams(@NonNull @CallbackExecutor Executor executor,
@SatelliteError @NonNull Consumer<Integer> resultListener) {
Objects.requireNonNull(executor);
@@ -1270,6 +1306,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void sendSatelliteDatagram(@DatagramType int datagramType,
@NonNull SatelliteDatagram datagram, boolean needFullScreenPointingUI,
@NonNull @CallbackExecutor Executor executor,
@@ -1315,6 +1352,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void requestIsSatelliteCommunicationAllowedForCurrentLocation(
@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Boolean, SatelliteException> callback) {
@@ -1372,6 +1410,7 @@
* @throws IllegalStateException if the Telephony process is not currently available.
*/
@RequiresPermission(Manifest.permission.SATELLITE_COMMUNICATION)
+ @UnsupportedAppUsage
public void requestTimeForNextSatelliteVisibility(@NonNull @CallbackExecutor Executor executor,
@NonNull OutcomeReceiver<Duration, SatelliteException> callback) {
Objects.requireNonNull(executor);
diff --git a/telephony/java/android/telephony/satellite/SatelliteProvisionStateCallback.java b/telephony/java/android/telephony/satellite/SatelliteProvisionStateCallback.java
index a62eb8b..20875af 100644
--- a/telephony/java/android/telephony/satellite/SatelliteProvisionStateCallback.java
+++ b/telephony/java/android/telephony/satellite/SatelliteProvisionStateCallback.java
@@ -16,6 +16,8 @@
package android.telephony.satellite;
+import android.compat.annotation.UnsupportedAppUsage;
+
/**
* A callback class for monitoring satellite provision state change events.
*
@@ -28,5 +30,6 @@
* @param provisioned The new provision state. {@code true} means satellite is provisioned
* {@code false} means satellite is not provisioned.
*/
+ @UnsupportedAppUsage
void onSatelliteProvisionStateChanged(boolean provisioned);
}
diff --git a/telephony/java/android/telephony/satellite/SatelliteStateCallback.java b/telephony/java/android/telephony/satellite/SatelliteStateCallback.java
index d9ecaa3..3312e3a 100644
--- a/telephony/java/android/telephony/satellite/SatelliteStateCallback.java
+++ b/telephony/java/android/telephony/satellite/SatelliteStateCallback.java
@@ -16,6 +16,8 @@
package android.telephony.satellite;
+import android.compat.annotation.UnsupportedAppUsage;
+
/**
* A callback class for monitoring satellite modem state change events.
*
@@ -26,5 +28,6 @@
* Called when satellite modem state changes.
* @param state The new satellite modem state.
*/
+ @UnsupportedAppUsage
void onSatelliteModemStateChanged(@SatelliteManager.SatelliteModemState int state);
}
diff --git a/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java b/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java
index 0efbd1f..17fff44 100644
--- a/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java
+++ b/telephony/java/android/telephony/satellite/SatelliteTransmissionUpdateCallback.java
@@ -17,6 +17,7 @@
package android.telephony.satellite;
import android.annotation.NonNull;
+import android.compat.annotation.UnsupportedAppUsage;
/**
* A callback class for monitoring satellite position update and datagram transfer state change
@@ -30,17 +31,30 @@
*
* @param pointingInfo The pointing info containing the satellite location.
*/
+ @UnsupportedAppUsage
void onSatellitePositionChanged(@NonNull PointingInfo pointingInfo);
/**
- * Called when satellite datagram transfer state changed.
+ * Called when satellite datagram send state changed.
*
- * @param state The new datagram transfer state.
+ * @param state The new send datagram transfer state.
* @param sendPendingCount The number of datagrams that are currently being sent.
- * @param receivePendingCount The number of datagrams that are currently being received.
* @param errorCode If datagram transfer failed, the reason for failure.
*/
- void onDatagramTransferStateChanged(@SatelliteManager.SatelliteDatagramTransferState int state,
- int sendPendingCount, int receivePendingCount,
+ @UnsupportedAppUsage
+ void onSendDatagramStateChanged(
+ @SatelliteManager.SatelliteDatagramTransferState int state, int sendPendingCount,
+ @SatelliteManager.SatelliteError int errorCode);
+
+ /**
+ * Called when satellite datagram receive state changed.
+ *
+ * @param state The new receive datagram transfer state.
+ * @param receivePendingCount The number of datagrams that are currently pending to be received.
+ * @param errorCode If datagram transfer failed, the reason for failure.
+ */
+ @UnsupportedAppUsage
+ void onReceiveDatagramStateChanged(
+ @SatelliteManager.SatelliteDatagramTransferState int state, int receivePendingCount,
@SatelliteManager.SatelliteError int errorCode);
}
diff --git a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
index d2a6bf2..81efda1 100644
--- a/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
+++ b/tests/BackgroundDexOptServiceIntegrationTests/src/com/android/server/pm/BackgroundDexOptServiceIntegrationTests.java
@@ -16,6 +16,8 @@
package com.android.server.pm;
+import static org.junit.Assume.assumeFalse;
+
import android.app.AlarmManager;
import android.content.Context;
import android.os.Environment;
@@ -112,6 +114,7 @@
@Before
public void setUp() throws IOException {
+ assumeFalse(SystemProperties.getBoolean("dalvik.vm.useartservice", false));
File dataDir = getContext().getDataDir();
mBigFile = new File(dataDir, BIG_FILE);
}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
index 5dc2dd7..47b2cda 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTest.kt
@@ -17,7 +17,6 @@
package com.android.server.wm.flicker.close
import android.platform.test.annotations.FlakyTest
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
@@ -40,20 +39,27 @@
* Launch an app [testApp] and wait animation to complete
* Press back button
* ```
+ *
* To run only the presubmit assertions add: `--
+ *
* ```
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Presubmit`
* ```
+ *
* To run only the postsubmit assertions add: `--
+ *
* ```
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Postsubmit`
* ```
+ *
* To run only the flaky assertions add: `--
+ *
* ```
* --module-arg FlickerTests:include-annotation:androidx.test.filters.FlakyTest`
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
@@ -65,7 +71,6 @@
* ```
*/
@RequiresDevice
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTestCfArm.kt
index 9fa84019..70eedd9 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppBackButtonTestCfArm.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.close
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
@@ -25,7 +24,6 @@
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
index b042a14..d8abb4e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTest.kt
@@ -17,7 +17,6 @@
package com.android.server.wm.flicker.close
import android.platform.test.annotations.FlakyTest
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
@@ -40,20 +39,27 @@
* Launch an app [testApp] and wait animation to complete
* Press home button
* ```
+ *
* To run only the presubmit assertions add: `--
+ *
* ```
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Presubmit`
* ```
+ *
* To run only the postsubmit assertions add: `--
+ *
* ```
* --module-arg FlickerTests:exclude-annotation:androidx.test.filters.FlakyTest
* --module-arg FlickerTests:include-annotation:android.platform.test.annotations.Postsubmit`
* ```
+ *
* To run only the flaky assertions add: `--
+ *
* ```
* --module-arg FlickerTests:include-annotation:androidx.test.filters.FlakyTest`
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
@@ -65,7 +71,6 @@
* ```
*/
@RequiresDevice
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTestCfArm.kt
index 136995a..c74f54b 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/close/CloseAppHomeButtonTestCfArm.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.close
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
@@ -25,7 +24,6 @@
import org.junit.runners.MethodSorters
import org.junit.runners.Parameterized
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt
new file mode 100644
index 0000000..ac05c76
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppAfterCameraTestCfArm.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.launch
+
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppAfterCameraTestCfArm(flicker: FlickerTest) : OpenAppAfterCameraTest(flicker) {
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests()
+ }
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
index ccbe74f..09c17b1 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdFromIconCfArm.kt
@@ -18,7 +18,6 @@
import android.platform.test.annotations.FlakyTest
import android.tools.common.NavBar
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
@@ -29,7 +28,6 @@
import org.junit.runners.Parameterized
/** Some assertions will fail because of b/264415996 */
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
index 8fdbb64..5cacb04 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTest.kt
@@ -16,15 +16,15 @@
package com.android.server.wm.flicker.launch
+import android.platform.test.annotations.Postsubmit
import android.platform.test.annotations.Presubmit
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.setRotation
-import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule.Companion.removeAllTasksButHome
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -41,6 +41,7 @@
* Make sure no apps are running on the device
* Launch an app [testApp] and wait animation to complete
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
@@ -52,7 +53,6 @@
* ```
*/
@RequiresDevice
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
@@ -72,6 +72,10 @@
/** {@inheritDoc} */
@Presubmit @Test override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
+ @Postsubmit
+ @Test
+ override fun navBarLayerPositionAtStartAndEnd() = super.navBarLayerPositionAtStartAndEnd()
+
companion object {
/**
* Creates the test configurations.
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt
new file mode 100644
index 0000000..f77f968
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppColdTestCfArm.kt
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.launch
+
+import android.platform.test.annotations.FlakyTest
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import org.junit.FixMethodOrder
+import org.junit.Test
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppColdTestCfArm(flicker: FlickerTest) : OpenAppColdTest(flicker) {
+ @FlakyTest(bugId = 273696733)
+ @Test
+ override fun appLayerReplacesLauncher() = super.appLayerReplacesLauncher()
+
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests()
+ }
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt
new file mode 100644
index 0000000..8b4a613
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationColdCfArm.kt
@@ -0,0 +1,47 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.launch
+
+import android.platform.test.annotations.Postsubmit
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+@Postsubmit
+class OpenAppFromNotificationColdCfArm(flicker: FlickerTest) :
+ OpenAppFromNotificationCold(flicker) {
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests()
+ }
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmCfArm.kt
new file mode 100644
index 0000000..d90b3ca
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromNotificationWarmCfArm.kt
@@ -0,0 +1,45 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.launch
+
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppFromNotificationWarmCfArm(flicker: FlickerTest) :
+ OpenAppFromNotificationWarm(flicker) {
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests()
+ }
+ }
+}
\ No newline at end of file
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
index 00d7544..66e0f06 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTest.kt
@@ -19,7 +19,6 @@
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
import android.tools.common.Rotation
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
@@ -44,6 +43,7 @@
* Relaunch an app [testApp] by selecting it in the overview screen, and wait animation to
* complete (only this action is traced)
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
@@ -55,7 +55,6 @@
* ```
*/
@RequiresDevice
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTestCfArm.kt
index ff24190..8139e1f 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTestCfArm.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppFromOverviewTestCfArm.kt
@@ -16,7 +16,6 @@
package com.android.server.wm.flicker.launch
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
@@ -26,7 +25,6 @@
import org.junit.runners.Parameterized
/** Some assertions will fail because of b/264415996 */
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
index 9ab6156..14df84e 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppNonResizeableTest.kt
@@ -22,7 +22,6 @@
import android.tools.common.NavBar
import android.tools.common.Rotation
import android.tools.common.datatypes.component.ComponentNameMatcher
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
@@ -48,6 +47,7 @@
* Lock the device.
* Launch an app on top of the lock screen [testApp] and wait animation to complete
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
@@ -59,7 +59,6 @@
* ```
*/
@RequiresDevice
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
index cdd2d45..cfc8e46 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTest.kt
@@ -18,7 +18,6 @@
import android.platform.test.annotations.FlakyTest
import android.platform.test.annotations.Presubmit
-import android.tools.device.flicker.annotation.FlickerServiceCompatible
import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
@@ -42,6 +41,7 @@
* Press home
* Relaunch an app [testApp] and wait animation to complete (only this action is traced)
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
@@ -53,7 +53,6 @@
* ```
*/
@RequiresDevice
-@FlickerServiceCompatible
@RunWith(Parameterized::class)
@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt
new file mode 100644
index 0000000..b47c931
--- /dev/null
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenAppWarmTestCfArm.kt
@@ -0,0 +1,44 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.android.server.wm.flicker.launch
+
+import android.tools.device.flicker.junit.FlickerParametersRunnerFactory
+import android.tools.device.flicker.legacy.FlickerTest
+import android.tools.device.flicker.legacy.FlickerTestFactory
+import org.junit.FixMethodOrder
+import org.junit.runner.RunWith
+import org.junit.runners.MethodSorters
+import org.junit.runners.Parameterized
+
+@RunWith(Parameterized::class)
+@Parameterized.UseParametersRunnerFactory(FlickerParametersRunnerFactory::class)
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+class OpenAppWarmTestCfArm(flicker: FlickerTest) : OpenAppWarmTest(flicker) {
+ companion object {
+ /**
+ * Creates the test configurations.
+ *
+ * See [FlickerTestFactory.nonRotationTests] for configuring screen orientation and
+ * navigation modes.
+ */
+ @Parameterized.Parameters(name = "{0}")
+ @JvmStatic
+ fun getParams(): Collection<FlickerTest> {
+ return FlickerTestFactory.nonRotationTests()
+ }
+ }
+}
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt
index 786bb32..e876e57 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OpenCameraOnDoubleClickPowerButton.kt
@@ -24,10 +24,10 @@
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
import android.view.KeyEvent
import androidx.test.filters.RequiresDevice
import com.android.server.wm.flicker.helpers.setRotation
-import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
@@ -44,6 +44,7 @@
* Make sure no apps are running on the device
* Launch an app [testApp] and wait animation to complete
* ```
+ *
* Notes:
* ```
* 1. Some default assertions (e.g., nav bar, status bar and screen covered)
diff --git a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
index b848e63..6cbb975 100644
--- a/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
+++ b/tests/FlickerTests/src/com/android/server/wm/flicker/launch/OverrideTaskTransitionTest.kt
@@ -27,13 +27,13 @@
import android.tools.device.flicker.legacy.FlickerBuilder
import android.tools.device.flicker.legacy.FlickerTest
import android.tools.device.flicker.legacy.FlickerTestFactory
+import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
+import android.tools.device.helpers.wakeUpAndGoToHomeScreen
import androidx.test.filters.RequiresDevice
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.wm.flicker.R
-import com.android.server.wm.flicker.helpers.setRotation
-import android.tools.device.flicker.rules.RemoveAllTasksButHomeRule
-import android.tools.device.helpers.wakeUpAndGoToHomeScreen
import com.android.server.wm.flicker.helpers.SimpleAppHelper
+import com.android.server.wm.flicker.helpers.setRotation
import org.junit.FixMethodOrder
import org.junit.Test
import org.junit.runner.RunWith
diff --git a/tests/Input/Android.bp b/tests/Input/Android.bp
index 83893ba..a4c48fd 100644
--- a/tests/Input/Android.bp
+++ b/tests/Input/Android.bp
@@ -13,6 +13,9 @@
"src/**/*.java",
"src/**/*.kt",
],
+ kotlincflags: [
+ "-Werror",
+ ],
platform_apis: true,
certificate: "platform",
static_libs: [
diff --git a/tests/Input/src/com/android/test/input/AnrTest.kt b/tests/Input/src/com/android/test/input/AnrTest.kt
index 9bb4ce7..41f6680 100644
--- a/tests/Input/src/com/android/test/input/AnrTest.kt
+++ b/tests/Input/src/com/android/test/input/AnrTest.kt
@@ -73,7 +73,7 @@
val contentResolver = instrumentation.targetContext.contentResolver
hideErrorDialogs = Settings.Global.getInt(contentResolver, HIDE_ERROR_DIALOGS, 0)
Settings.Global.putInt(contentResolver, HIDE_ERROR_DIALOGS, 0)
- PACKAGE_NAME = UnresponsiveGestureMonitorActivity::class.java.getPackage().getName()
+ PACKAGE_NAME = UnresponsiveGestureMonitorActivity::class.java.getPackage()!!.getName()
}
@After
diff --git a/tests/Input/src/com/android/test/input/UnresponsiveGestureMonitorActivity.kt b/tests/Input/src/com/android/test/input/UnresponsiveGestureMonitorActivity.kt
index d83a457..3a24406 100644
--- a/tests/Input/src/com/android/test/input/UnresponsiveGestureMonitorActivity.kt
+++ b/tests/Input/src/com/android/test/input/UnresponsiveGestureMonitorActivity.kt
@@ -45,7 +45,8 @@
private lateinit var mInputMonitor: InputMonitor
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
- mInputMonitor = InputManager.getInstance().monitorGestureInput(MONITOR_NAME, displayId)
+ val inputManager = getSystemService(InputManager::class.java)
+ mInputMonitor = inputManager.monitorGestureInput(MONITOR_NAME, displayId)
mInputEventReceiver = UnresponsiveReceiver(
mInputMonitor.getInputChannel(), Looper.myLooper())
}
diff --git a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
index f183a9b..b7f5b15 100644
--- a/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
+++ b/tests/VoiceInteraction/src/com/android/test/voiceinteraction/MainInteractionService.java
@@ -20,7 +20,6 @@
import android.service.voice.AlwaysOnHotwordDetector;
import android.service.voice.AlwaysOnHotwordDetector.Callback;
import android.service.voice.AlwaysOnHotwordDetector.EventPayload;
-import android.service.voice.HotwordDetector;
import android.service.voice.VoiceInteractionService;
import android.util.Log;
@@ -84,24 +83,16 @@
break;
case AlwaysOnHotwordDetector.STATE_KEYPHRASE_UNENROLLED:
Log.i(TAG, "STATE_KEYPHRASE_UNENROLLED");
- try {
- Intent enroll = mHotwordDetector.createEnrollIntent();
- Log.i(TAG, "Need to enroll with " + enroll);
- } catch (HotwordDetector.IllegalDetectorStateException e) {
- Log.e(TAG, "createEnrollIntent failed", e);
- }
+ Intent enroll = mHotwordDetector.createEnrollIntent();
+ Log.i(TAG, "Need to enroll with " + enroll);
break;
case AlwaysOnHotwordDetector.STATE_KEYPHRASE_ENROLLED:
Log.i(TAG, "STATE_KEYPHRASE_ENROLLED - starting recognition");
- try {
- if (mHotwordDetector.startRecognition(
- AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE)) {
- Log.i(TAG, "startRecognition succeeded");
- } else {
- Log.i(TAG, "startRecognition failed");
- }
- } catch (HotwordDetector.IllegalDetectorStateException e) {
- Log.e(TAG, "startRecognition failed", e);
+ if (mHotwordDetector.startRecognition(
+ AlwaysOnHotwordDetector.RECOGNITION_FLAG_NONE)) {
+ Log.i(TAG, "startRecognition succeeded");
+ } else {
+ Log.i(TAG, "startRecognition failed");
}
break;
}
diff --git a/tests/utils/testutils/Android.bp b/tests/utils/testutils/Android.bp
index deff42a..82953ac 100644
--- a/tests/utils/testutils/Android.bp
+++ b/tests/utils/testutils/Android.bp
@@ -41,3 +41,17 @@
"mockito-target-extended-minus-junit4",
],
}
+
+java_test_host {
+ name: "frameworks-base-android-os-unittests",
+ srcs: [
+ ":framework-android-os-unit-testable-src",
+ "java/android/os/test/DdmSyncStateTest.java",
+ ],
+ static_libs: [
+ "junit",
+ ],
+ test_options: {
+ unit_test: true,
+ },
+}
diff --git a/tests/utils/testutils/java/android/os/test/DdmSyncStateTest.java b/tests/utils/testutils/java/android/os/test/DdmSyncStateTest.java
new file mode 100644
index 0000000..8274ce4
--- /dev/null
+++ b/tests/utils/testutils/java/android/os/test/DdmSyncStateTest.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2023 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package android.os.test;
+
+import android.os.DdmSyncState;
+import android.os.DdmSyncState.Stage;
+
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Test DdmSyncState, the Android app stage boot sync system for DDM Client.
+ */
+
+public class DdmSyncStateTest {
+
+ @Test
+ public void testNoCycle() {
+ DdmSyncState.reset();
+ try {
+ DdmSyncState.next(Stage.Attach);
+ DdmSyncState.next(Stage.Bind);
+ DdmSyncState.next(Stage.Named);
+ DdmSyncState.next(Stage.Debugger);
+ DdmSyncState.next(Stage.Running);
+
+ // Cycling back here which is not allowed
+ DdmSyncState.next(Stage.Attach);
+ Assert.fail("Going back to attach should have failed");
+ } catch (IllegalStateException ignored) {
+
+ }
+ }
+
+ @Test
+ public void testDebuggerFlow() {
+ DdmSyncState.reset();
+ DdmSyncState.next(Stage.Attach);
+ DdmSyncState.next(Stage.Bind);
+ DdmSyncState.next(Stage.Named);
+ DdmSyncState.next(Stage.Debugger);
+ DdmSyncState.next(Stage.Running);
+ Assert.assertEquals(Stage.Running, DdmSyncState.getStage());
+
+ }
+
+ @Test
+ public void testNoDebugFlow() {
+ DdmSyncState.reset();
+ DdmSyncState.next(Stage.Attach);
+ DdmSyncState.next(Stage.Bind);
+ DdmSyncState.next(Stage.Named);
+ // Notice how Stage.Debugger stage is skipped
+ DdmSyncState.next(Stage.Running);
+ Assert.assertEquals(Stage.Running, DdmSyncState.getStage());
+ }
+}
diff --git a/tools/lint/fix/Android.bp b/tools/lint/fix/Android.bp
index 7375c16..43f2122 100644
--- a/tools/lint/fix/Android.bp
+++ b/tools/lint/fix/Android.bp
@@ -23,9 +23,8 @@
python_binary_host {
name: "lint_fix",
- main: "lint_fix.py",
- srcs: ["lint_fix.py"],
- libs: ["soong_lint_fix"],
+ main: "soong_lint_fix.py",
+ srcs: ["soong_lint_fix.py"],
}
python_library_host {
diff --git a/tools/lint/fix/README.md b/tools/lint/fix/README.md
index 367d0bc..a5ac2be 100644
--- a/tools/lint/fix/README.md
+++ b/tools/lint/fix/README.md
@@ -5,9 +5,12 @@
## What is this?
It's a python script that runs the framework linter,
-and then copies modified files back into the source tree.\
+and then (optionally) copies modified files back into the source tree.\
Why python, you ask? Because python is cool ¯\_(ツ)_/¯.
+Incidentally, this exposes a much simpler way to run individual lint checks
+against individual modules, so it's useful beyond applying fixes.
+
## Why?
Lint is not allowed to modify source files directly via lint's `--apply-suggestions` flag.
@@ -17,30 +20,11 @@
## How do I run it?
**WARNING: You probably want to commit/stash any changes to your working tree before doing this...**
-From this directory, run `python lint_fix.py -h`.
-The script's help output explains things that are omitted here.
-
-Alternatively, there is a python binary target you can build to make this
-available anywhere in your tree:
```
+source build/envsetup.sh
+lunch cf_x86_64_phone-userdebug # or any lunch target
m lint_fix
lint_fix -h
```
-**Gotcha**: You must have run `source build/envsetup.sh` and `lunch` first.
-
-Example: `lint_fix frameworks/base/services/core/services.core.unboosted UseEnforcePermissionAnnotation --dry-run`
-```shell
-(
-export ANDROID_LINT_CHECK=UseEnforcePermissionAnnotation;
-cd $ANDROID_BUILD_TOP;
-source build/envsetup.sh;
-rm out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/lint/lint-report.html;
-m out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/lint/lint-report.html;
-cd out/soong/.intermediates/frameworks/base/services/core/services.core.unboosted/android_common/lint;
-unzip suggested-fixes.zip -d suggested-fixes;
-cd suggested-fixes;
-find . -path ./out -prune -o -name '*.java' -print | xargs -n 1 sh -c 'cp $1 $ANDROID_BUILD_TOP/$1' --;
-rm -rf suggested-fixes
-)
-```
+The script's help output explains things that are omitted here.
diff --git a/tools/lint/fix/lint_fix.py b/tools/lint/fix/lint_fix.py
deleted file mode 100644
index 1c83f7b..0000000
--- a/tools/lint/fix/lint_fix.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright (C) 2023 The Android Open Source Project
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from soong_lint_fix import SoongLintFix
-
-SoongLintFix().run()
diff --git a/tools/lint/fix/soong_lint_fix.py b/tools/lint/fix/soong_lint_fix.py
index 3308df6..cd4d778d 100644
--- a/tools/lint/fix/soong_lint_fix.py
+++ b/tools/lint/fix/soong_lint_fix.py
@@ -13,14 +13,21 @@
# limitations under the License.
import argparse
+import json
import os
+import shutil
import subprocess
import sys
+import zipfile
ANDROID_BUILD_TOP = os.environ.get("ANDROID_BUILD_TOP")
+ANDROID_PRODUCT_OUT = os.environ.get("ANDROID_PRODUCT_OUT")
+PRODUCT_OUT = ANDROID_PRODUCT_OUT.removeprefix(f"{ANDROID_BUILD_TOP}/")
+
+SOONG_UI = "build/soong/soong_ui.bash"
PATH_PREFIX = "out/soong/.intermediates"
PATH_SUFFIX = "android_common/lint"
-FIX_DIR = "suggested-fixes"
+FIX_ZIP = "suggested-fixes.zip"
class SoongLintFix:
"""
@@ -28,14 +35,12 @@
apply lint fixes to the platform via the necessary
combination of soong and shell commands.
- It provides some basic hooks for experimental code
- to tweak the generation of the resulting shell script.
+ It breaks up these operations into a few "private" methods
+ that are intentionally exposed so experimental code can tweak behavior.
- By default, it will apply lint fixes using the intermediate `suggested-fixes`
- directory that soong creates during its invocation of lint.
-
- The default argument parser configures a number of command line arguments to
- facilitate running lint via soong.
+ The entry point, `run`, will apply lint fixes using the
+ intermediate `suggested-fixes` directory that soong creates during its
+ invocation of lint.
Basic usage:
```
@@ -45,99 +50,95 @@
```
"""
def __init__(self):
- self._commands = None
+ self._parser = _setup_parser()
self._args = None
+ self._kwargs = None
self._path = None
self._target = None
- self._parser = _setup_parser()
- def add_argument(self, *args, **kwargs):
- """
- If necessary, add arguments to the underlying argparse.ArgumentParser before running
- """
- self._parser.add_argument(*args, **kwargs)
-
-
- def run(self, add_setup_commands=None, override_fix_commands=None):
+ def run(self, additional_setup=None, custom_fix=None):
"""
Run the script
- :param add_setup_commands: OPTIONAL function to add additional setup commands
- passed the command line arguments, path, and build target
- must return a list of strings (the additional commands)
- :param override_fix_commands: OPTIONAL function to override the fix commands
- passed the command line arguments, path, and build target
- must return a list of strings (the fix commands)
"""
self._setup()
- if add_setup_commands:
- self._commands += add_setup_commands(self._args, self._path, self._target)
-
- self._add_lint_report_commands()
+ self._find_module()
+ self._lint()
if not self._args.no_fix:
- if override_fix_commands:
- self._commands += override_fix_commands(self._args, self._path, self._target)
- else:
- self._commands += [
- f"cd {self._path}",
- f"unzip {FIX_DIR}.zip -d {FIX_DIR}",
- f"cd {FIX_DIR}",
- # Find all the java files in the fix directory, excluding the ./out subdirectory,
- # and copy them back into the same path within the tree.
- f"find . -path ./out -prune -o -name '*.java' -print | xargs -n 1 sh -c 'cp $1 $ANDROID_BUILD_TOP/$1 || exit 255' --",
- f"rm -rf {FIX_DIR}"
- ]
+ self._fix()
-
- if self._args.dry_run:
- print(self._get_commands_str())
- else:
- self._execute()
-
+ if self._args.print:
+ self._print()
def _setup(self):
self._args = self._parser.parse_args()
- self._commands = []
- self._path = f"{PATH_PREFIX}/{self._args.build_path}/{PATH_SUFFIX}"
- self._target = f"{self._path}/lint-report.html"
-
- if not self._args.dry_run:
- self._commands += [f"export ANDROID_BUILD_TOP={ANDROID_BUILD_TOP}"]
-
+ env = os.environ.copy()
if self._args.check:
- self._commands += [f"export ANDROID_LINT_CHECK={self._args.check}"]
+ env["ANDROID_LINT_CHECK"] = self._args.check
+ if self._args.lint_module:
+ env["ANDROID_LINT_CHECK_EXTRA_MODULES"] = self._args.lint_module
+
+ self._kwargs = {
+ "env": env,
+ "executable": "/bin/bash",
+ "shell": True,
+ }
+
+ os.chdir(ANDROID_BUILD_TOP)
- def _add_lint_report_commands(self):
- self._commands += [
- "cd $ANDROID_BUILD_TOP",
- "source build/envsetup.sh",
- # remove the file first so soong doesn't think there is no work to do
- f"rm {self._target}",
- # remove in case there are fixes from a prior run,
- # that we don't want applied if this run fails
- f"rm {self._path}/{FIX_DIR}.zip",
- f"m {self._target}",
- ]
+ def _find_module(self):
+ print("Refreshing soong modules...")
+ try:
+ os.mkdir(ANDROID_PRODUCT_OUT)
+ except OSError:
+ pass
+ subprocess.call(f"{SOONG_UI} --make-mode {PRODUCT_OUT}/module-info.json", **self._kwargs)
+ print("done.")
+
+ with open(f"{ANDROID_PRODUCT_OUT}/module-info.json") as f:
+ module_info = json.load(f)
+
+ if self._args.module not in module_info:
+ sys.exit(f"Module {self._args.module} not found!")
+
+ module_path = module_info[self._args.module]["path"][0]
+ print(f"Found module {module_path}/{self._args.module}.")
+
+ self._path = f"{PATH_PREFIX}/{module_path}/{self._args.module}/{PATH_SUFFIX}"
+ self._target = f"{self._path}/lint-report.txt"
- def _get_commands_str(self):
- prefix = "(\n"
- delimiter = ";\n"
- suffix = "\n)"
- return f"{prefix}{delimiter.join(self._commands)}{suffix}"
+ def _lint(self):
+ print("Cleaning up any old lint results...")
+ try:
+ os.remove(f"{self._target}")
+ os.remove(f"{self._path}/{FIX_ZIP}")
+ except FileNotFoundError:
+ pass
+ print("done.")
+
+ print(f"Generating {self._target}")
+ subprocess.call(f"{SOONG_UI} --make-mode {self._target}", **self._kwargs)
+ print("done.")
- def _execute(self, with_echo=True):
- if with_echo:
- exec_commands = []
- for c in self._commands:
- exec_commands.append(f'echo "{c}"')
- exec_commands.append(c)
- self._commands = exec_commands
+ def _fix(self):
+ print("Copying suggested fixes to the tree...")
+ with zipfile.ZipFile(f"{self._path}/{FIX_ZIP}") as zip:
+ for name in zip.namelist():
+ if name.startswith("out") or not name.endswith(".java"):
+ continue
+ with zip.open(name) as src, open(f"{ANDROID_BUILD_TOP}/{name}", "wb") as dst:
+ shutil.copyfileobj(src, dst)
+ print("done.")
- subprocess.call(self._get_commands_str(), executable='/bin/bash', shell=True)
+
+ def _print(self):
+ print("### lint-report.txt ###", end="\n\n")
+ with open(self._target, "r") as f:
+ print(f.read())
def _setup_parser():
@@ -147,23 +148,26 @@
2. Run lint on the specified target.
3. Copy the modified files, from soong's intermediate directory, back into the tree.
- **Gotcha**: You must have run `source build/envsetup.sh` and `lunch`
- so that the `ANDROID_BUILD_TOP` environment variable has been set.
- Alternatively, set it manually in your shell.
+ **Gotcha**: You must have run `source build/envsetup.sh` and `lunch` first.
""", formatter_class=argparse.RawTextHelpFormatter)
- parser.add_argument('build_path', metavar='build_path', type=str,
- help='The build module to run '
- '(e.g. frameworks/base/framework-minus-apex or '
- 'frameworks/base/services/core/services.core.unboosted)')
+ parser.add_argument('module',
+ help='The soong build module to run '
+ '(e.g. framework-minus-apex or services.core.unboosted)')
- parser.add_argument('--check', metavar='check', type=str,
+ parser.add_argument('--check',
help='Which lint to run. Passed to the ANDROID_LINT_CHECK environment variable.')
- parser.add_argument('--dry-run', dest='dry_run', action='store_true',
- help='Just print the resulting shell script instead of running it.')
+ parser.add_argument('--lint-module',
+ help='Specific lint module to run. Passed to the ANDROID_LINT_CHECK_EXTRA_MODULES environment variable.')
- parser.add_argument('--no-fix', dest='no_fix', action='store_true',
+ parser.add_argument('--no-fix', action='store_true',
help='Just build and run the lint, do NOT apply the fixes.')
+ parser.add_argument('--print', action='store_true',
+ help='Print the contents of the generated lint-report.txt at the end.')
+
return parser
+
+if __name__ == "__main__":
+ SoongLintFix().run()
\ No newline at end of file
diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
index 423a684..b4f6a1c 100644
--- a/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
+++ b/tools/lint/framework/checks/src/main/java/com/google/android/lint/AndroidFrameworkIssueRegistry.kt
@@ -36,7 +36,6 @@
CallingSettingsNonUserGetterMethodsDetector.ISSUE_NON_USER_GETTER_CALLED,
SaferParcelChecker.ISSUE_UNSAFE_API_USAGE,
PackageVisibilityDetector.ISSUE_PACKAGE_NAME_NO_PACKAGE_VISIBILITY_FILTERS,
- RegisterReceiverFlagDetector.ISSUE_RECEIVER_EXPORTED_FLAG,
PermissionMethodDetector.ISSUE_PERMISSION_METHOD_USAGE,
PermissionMethodDetector.ISSUE_CAN_BE_PERMISSION_METHOD,
)
diff --git a/tools/lint/framework/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt b/tools/lint/framework/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt
deleted file mode 100644
index 28027a7..0000000
--- a/tools/lint/framework/checks/src/main/java/com/google/android/lint/RegisterReceiverFlagDetector.kt
+++ /dev/null
@@ -1,927 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.lint
-
-import com.android.tools.lint.checks.DataFlowAnalyzer
-import com.android.tools.lint.detector.api.Category
-import com.android.tools.lint.detector.api.ConstantEvaluator
-import com.android.tools.lint.detector.api.Detector
-import com.android.tools.lint.detector.api.Implementation
-import com.android.tools.lint.detector.api.Issue
-import com.android.tools.lint.detector.api.JavaContext
-import com.android.tools.lint.detector.api.Scope
-import com.android.tools.lint.detector.api.Severity
-import com.android.tools.lint.detector.api.SourceCodeScanner
-import com.android.tools.lint.detector.api.UastLintUtils.Companion.findLastAssignment
-import com.android.tools.lint.detector.api.getMethodName
-import com.intellij.psi.PsiMethod
-import com.intellij.psi.PsiVariable
-import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
-import org.jetbrains.uast.UCallExpression
-import org.jetbrains.uast.UElement
-import org.jetbrains.uast.UExpression
-import org.jetbrains.uast.UParenthesizedExpression
-import org.jetbrains.uast.UQualifiedReferenceExpression
-import org.jetbrains.uast.getContainingUMethod
-import org.jetbrains.uast.isNullLiteral
-import org.jetbrains.uast.skipParenthesizedExprDown
-import org.jetbrains.uast.tryResolve
-
-/**
- * Detector that identifies `registerReceiver()` calls which are missing the `RECEIVER_EXPORTED` or
- * `RECEIVER_NOT_EXPORTED` flags on T+.
- *
- * TODO: Add API level conditions to better support non-platform code.
- * 1. Check if registerReceiver() call is reachable on T+.
- * 2. Check if targetSdkVersion is T+.
- *
- * eg: isWithinVersionCheckConditional(context, node, 31, false)
- * eg: isPrecededByVersionCheckExit(context, node, 31) ?
- */
-@Suppress("UnstableApiUsage")
-class RegisterReceiverFlagDetector : Detector(), SourceCodeScanner {
-
- override fun getApplicableMethodNames(): List<String> = listOf(
- "registerReceiver",
- "registerReceiverAsUser",
- "registerReceiverForAllUsers"
- )
-
- private fun checkIsProtectedReceiverAndReturnUnprotectedActions(
- filterArg: UExpression,
- node: UCallExpression,
- evaluator: ConstantEvaluator
- ): Pair<Boolean, List<String>> { // isProtected, unprotectedActions
- val actions = mutableSetOf<String>()
- val construction = findIntentFilterConstruction(filterArg, node)
-
- if (construction == null) return Pair(false, listOf<String>())
- val constructorActionArg = construction.getArgumentForParameter(0)
- (constructorActionArg?.let(evaluator::evaluate) as? String)?.let(actions::add)
-
- val actionCollectorVisitor =
- ActionCollectorVisitor(setOf(construction), node, evaluator)
-
- val parent = node.getContainingUMethod()
- parent?.accept(actionCollectorVisitor)
- actions.addAll(actionCollectorVisitor.actions)
-
- // If we failed to evaluate any actions, there will be a null action in the set.
- val isProtected =
- actions.all(PROTECTED_BROADCASTS::contains) &&
- !actionCollectorVisitor.intentFilterEscapesScope
- val unprotectedActionsList = actions.filterNot(PROTECTED_BROADCASTS::contains)
- return Pair(isProtected, unprotectedActionsList)
- }
-
- override fun visitMethodCall(context: JavaContext, node: UCallExpression, method: PsiMethod) {
- if (!context.evaluator.isMemberInSubClassOf(method, "android.content.Context")) return
-
- // The parameter positions vary across the various registerReceiver*() methods, so rather
- // than hardcode them we simply look them up based on the parameter name and type.
- val receiverArg =
- findArgument(node, method, "android.content.BroadcastReceiver", "receiver")
- val filterArg = findArgument(node, method, "android.content.IntentFilter", "filter")
- val flagsArg = findArgument(node, method, "int", "flags")
-
- if (receiverArg == null || receiverArg.isNullLiteral() || filterArg == null) {
- return
- }
-
- val evaluator = ConstantEvaluator().allowFieldInitializers()
-
- val (isProtected, unprotectedActionsList) =
- checkIsProtectedReceiverAndReturnUnprotectedActions(filterArg, node, evaluator)
-
- val flags = evaluator.evaluate(flagsArg) as? Int
-
- if (!isProtected) {
- val actionsList = unprotectedActionsList.joinToString(", ", "", "", -1, "")
- val message = "$receiverArg is missing 'RECEIVER_EXPORTED` or 'RECEIVER_NOT_EXPORTED' " +
- "flag for unprotected broadcast(s) registered for $actionsList."
- if (flagsArg == null) {
- context.report(
- ISSUE_RECEIVER_EXPORTED_FLAG, node, context.getLocation(node), message)
- } else if (flags != null && (flags and RECEIVER_EXPORTED_FLAG_PRESENT_MASK) == 0) {
- context.report(
- ISSUE_RECEIVER_EXPORTED_FLAG, node, context.getLocation(flagsArg), message)
- }
- }
-
- if (DEBUG) {
- println(node.asRenderString())
- println("Unprotected Actions: $unprotectedActionsList")
- println("Protected: $isProtected")
- println("Flags: $flags")
- }
- }
-
- /** Finds the first argument of a method that matches the given parameter type and name. */
- private fun findArgument(
- node: UCallExpression,
- method: PsiMethod,
- type: String,
- name: String
- ): UExpression? {
- val psiParameter = method.parameterList.parameters.firstOrNull {
- it.type.canonicalText == type && it.name == name
- } ?: return null
- val argument = node.getArgumentForParameter(psiParameter.parameterIndex())
- return argument?.skipParenthesizedExprDown()
- }
-
- /**
- * For the supplied expression (eg. intent filter argument), attempts to find its construction.
- * This will be an `IntentFilter()` constructor, an `IntentFilter.create()` call, or `null`.
- */
- private fun findIntentFilterConstruction(
- expression: UExpression,
- node: UCallExpression
- ): UCallExpression? {
- val resolved = expression.tryResolve()
-
- if (resolved is PsiVariable) {
- val assignment = findLastAssignment(resolved, node) ?: return null
- return findIntentFilterConstruction(assignment, node)
- }
-
- if (expression is UParenthesizedExpression) {
- return findIntentFilterConstruction(expression.expression, node)
- }
-
- if (expression is UQualifiedReferenceExpression) {
- val call = expression.selector as? UCallExpression ?: return null
- return if (isReturningContext(call)) {
- // eg. filter.apply { addAction("abc") } --> use filter variable.
- findIntentFilterConstruction(expression.receiver, node)
- } else {
- // eg. IntentFilter.create("abc") --> use create("abc") UCallExpression.
- findIntentFilterConstruction(call, node)
- }
- }
-
- val method = resolved as? PsiMethod ?: return null
- return if (isIntentFilterFactoryMethod(method)) {
- expression as? UCallExpression
- } else {
- null
- }
- }
-
- private fun isIntentFilterFactoryMethod(method: PsiMethod) =
- (method.containingClass?.qualifiedName == "android.content.IntentFilter" &&
- (method.returnType?.canonicalText == "android.content.IntentFilter" ||
- method.isConstructor))
-
- /**
- * Returns true if the given call represents a Kotlin scope function where the return value is
- * the context object; see https://kotlinlang.org/docs/scope-functions.html#function-selection.
- */
- private fun isReturningContext(node: UCallExpression): Boolean {
- val name = getMethodName(node)
- if (name == "apply" || name == "also") {
- return isScopingFunction(node)
- }
- return false
- }
-
- /**
- * Returns true if the given node appears to be one of the scope functions. Only checks parent
- * class; caller should intend that it's actually one of let, with, apply, etc.
- */
- private fun isScopingFunction(node: UCallExpression): Boolean {
- val called = node.resolve() ?: return true
- // See libraries/stdlib/jvm/build/stdlib-declarations.json
- return called.containingClass?.qualifiedName == "kotlin.StandardKt__StandardKt"
- }
-
- inner class ActionCollectorVisitor(
- start: Collection<UElement>,
- val functionCall: UCallExpression,
- val evaluator: ConstantEvaluator,
- ) : DataFlowAnalyzer(start) {
- private var finished = false
- var intentFilterEscapesScope = false; private set
- val actions = mutableSetOf<String>()
-
- override fun argument(call: UCallExpression, reference: UElement) {
- // TODO: Remove this temporary fix for DataFlowAnalyzer bug (ag/15787550):
- if (reference !in call.valueArguments) return
- val methodNames = super@RegisterReceiverFlagDetector.getApplicableMethodNames()
- when {
- finished -> return
- // We've reached the registerReceiver*() call in question.
- call == functionCall -> finished = true
- // The filter 'intentFilterEscapesScope' to a method which could modify it.
- methodNames != null && getMethodName(call)!! !in methodNames ->
- intentFilterEscapesScope = true
- }
- }
-
- // Fixed in b/199163915: DataFlowAnalyzer doesn't call this for Kotlin properties.
- override fun field(field: UElement) {
- if (!finished) intentFilterEscapesScope = true
- }
-
- override fun receiver(call: UCallExpression) {
- if (!finished && getMethodName(call) == "addAction") {
- val actionArg = call.getArgumentForParameter(0)
- if (actionArg != null) {
- val action = evaluator.evaluate(actionArg) as? String
- if (action != null) actions.add(action)
- }
- }
- }
- }
-
- companion object {
- const val DEBUG = false
-
- private const val RECEIVER_EXPORTED = 0x2
- private const val RECEIVER_NOT_EXPORTED = 0x4
- private const val RECEIVER_EXPORTED_FLAG_PRESENT_MASK =
- RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED
-
- @JvmField
- val ISSUE_RECEIVER_EXPORTED_FLAG: Issue = Issue.create(
- id = "UnspecifiedRegisterReceiverFlag",
- briefDescription = "Missing `registerReceiver()` exported flag",
- explanation = """
- Apps targeting Android T (SDK 33) and higher must specify either `RECEIVER_EXPORTED` \
- or `RECEIVER_NOT_EXPORTED` when registering a broadcast receiver, unless the \
- receiver is only registered for protected system broadcast actions.
- """,
- category = Category.SECURITY,
- priority = 5,
- severity = Severity.WARNING,
- implementation = Implementation(
- RegisterReceiverFlagDetector::class.java,
- Scope.JAVA_FILE_SCOPE
- )
- )
-
- val PROTECTED_BROADCASTS = listOf(
- "android.intent.action.SCREEN_OFF",
- "android.intent.action.SCREEN_ON",
- "android.intent.action.USER_PRESENT",
- "android.intent.action.TIME_SET",
- "android.intent.action.TIME_TICK",
- "android.intent.action.TIMEZONE_CHANGED",
- "android.intent.action.DATE_CHANGED",
- "android.intent.action.PRE_BOOT_COMPLETED",
- "android.intent.action.BOOT_COMPLETED",
- "android.intent.action.PACKAGE_INSTALL",
- "android.intent.action.PACKAGE_ADDED",
- "android.intent.action.PACKAGE_REPLACED",
- "android.intent.action.MY_PACKAGE_REPLACED",
- "android.intent.action.PACKAGE_REMOVED",
- "android.intent.action.PACKAGE_REMOVED_INTERNAL",
- "android.intent.action.PACKAGE_FULLY_REMOVED",
- "android.intent.action.PACKAGE_CHANGED",
- "android.intent.action.PACKAGE_FULLY_LOADED",
- "android.intent.action.PACKAGE_ENABLE_ROLLBACK",
- "android.intent.action.CANCEL_ENABLE_ROLLBACK",
- "android.intent.action.ROLLBACK_COMMITTED",
- "android.intent.action.PACKAGE_RESTARTED",
- "android.intent.action.PACKAGE_DATA_CLEARED",
- "android.intent.action.PACKAGE_FIRST_LAUNCH",
- "android.intent.action.PACKAGE_NEEDS_INTEGRITY_VERIFICATION",
- "android.intent.action.PACKAGE_NEEDS_VERIFICATION",
- "android.intent.action.PACKAGE_VERIFIED",
- "android.intent.action.PACKAGES_SUSPENDED",
- "android.intent.action.PACKAGES_UNSUSPENDED",
- "android.intent.action.PACKAGES_SUSPENSION_CHANGED",
- "android.intent.action.PACKAGE_UNSUSPENDED_MANUALLY",
- "android.intent.action.DISTRACTING_PACKAGES_CHANGED",
- "android.intent.action.ACTION_PREFERRED_ACTIVITY_CHANGED",
- "android.intent.action.UID_REMOVED",
- "android.intent.action.QUERY_PACKAGE_RESTART",
- "android.intent.action.CONFIGURATION_CHANGED",
- "android.intent.action.SPLIT_CONFIGURATION_CHANGED",
- "android.intent.action.LOCALE_CHANGED",
- "android.intent.action.APPLICATION_LOCALE_CHANGED",
- "android.intent.action.BATTERY_CHANGED",
- "android.intent.action.BATTERY_LEVEL_CHANGED",
- "android.intent.action.BATTERY_LOW",
- "android.intent.action.BATTERY_OKAY",
- "android.intent.action.ACTION_POWER_CONNECTED",
- "android.intent.action.ACTION_POWER_DISCONNECTED",
- "android.intent.action.ACTION_SHUTDOWN",
- "android.intent.action.CHARGING",
- "android.intent.action.DISCHARGING",
- "android.intent.action.DEVICE_STORAGE_LOW",
- "android.intent.action.DEVICE_STORAGE_OK",
- "android.intent.action.DEVICE_STORAGE_FULL",
- "android.intent.action.DEVICE_STORAGE_NOT_FULL",
- "android.intent.action.NEW_OUTGOING_CALL",
- "android.intent.action.REBOOT",
- "android.intent.action.DOCK_EVENT",
- "android.intent.action.THERMAL_EVENT",
- "android.intent.action.MASTER_CLEAR_NOTIFICATION",
- "android.intent.action.USER_ADDED",
- "android.intent.action.USER_REMOVED",
- "android.intent.action.USER_STARTING",
- "android.intent.action.USER_STARTED",
- "android.intent.action.USER_STOPPING",
- "android.intent.action.USER_STOPPED",
- "android.intent.action.USER_BACKGROUND",
- "android.intent.action.USER_FOREGROUND",
- "android.intent.action.USER_SWITCHED",
- "android.intent.action.USER_INITIALIZE",
- "android.intent.action.INTENT_FILTER_NEEDS_VERIFICATION",
- "android.intent.action.DOMAINS_NEED_VERIFICATION",
- "android.intent.action.OVERLAY_ADDED",
- "android.intent.action.OVERLAY_CHANGED",
- "android.intent.action.OVERLAY_REMOVED",
- "android.intent.action.OVERLAY_PRIORITY_CHANGED",
- "android.intent.action.MY_PACKAGE_SUSPENDED",
- "android.intent.action.MY_PACKAGE_UNSUSPENDED",
- "android.os.action.POWER_SAVE_MODE_CHANGED",
- "android.os.action.DEVICE_IDLE_MODE_CHANGED",
- "android.os.action.POWER_SAVE_WHITELIST_CHANGED",
- "android.os.action.POWER_SAVE_TEMP_WHITELIST_CHANGED",
- "android.os.action.POWER_SAVE_MODE_CHANGED_INTERNAL",
- "android.os.action.LOW_POWER_STANDBY_ENABLED_CHANGED",
- "android.os.action.ENHANCED_DISCHARGE_PREDICTION_CHANGED",
- "android.os.action.SCREEN_BRIGHTNESS_BOOST_CHANGED",
- "android.app.action.CLOSE_NOTIFICATION_HANDLER_PANEL",
- "android.app.action.ENTER_CAR_MODE",
- "android.app.action.EXIT_CAR_MODE",
- "android.app.action.ENTER_CAR_MODE_PRIORITIZED",
- "android.app.action.EXIT_CAR_MODE_PRIORITIZED",
- "android.app.action.ENTER_DESK_MODE",
- "android.app.action.EXIT_DESK_MODE",
- "android.app.action.NEXT_ALARM_CLOCK_CHANGED",
- "android.app.action.USER_ADDED",
- "android.app.action.USER_REMOVED",
- "android.app.action.USER_STARTED",
- "android.app.action.USER_STOPPED",
- "android.app.action.USER_SWITCHED",
- "android.app.action.BUGREPORT_SHARING_DECLINED",
- "android.app.action.BUGREPORT_FAILED",
- "android.app.action.BUGREPORT_SHARE",
- "android.app.action.SHOW_DEVICE_MONITORING_DIALOG",
- "android.intent.action.PENDING_INCIDENT_REPORTS_CHANGED",
- "android.intent.action.INCIDENT_REPORT_READY",
- "android.appwidget.action.APPWIDGET_UPDATE_OPTIONS",
- "android.appwidget.action.APPWIDGET_DELETED",
- "android.appwidget.action.APPWIDGET_DISABLED",
- "android.appwidget.action.APPWIDGET_ENABLED",
- "android.appwidget.action.APPWIDGET_HOST_RESTORED",
- "android.appwidget.action.APPWIDGET_RESTORED",
- "android.appwidget.action.APPWIDGET_ENABLE_AND_UPDATE",
- "android.os.action.SETTING_RESTORED",
- "android.app.backup.intent.CLEAR",
- "android.app.backup.intent.INIT",
- "android.bluetooth.intent.DISCOVERABLE_TIMEOUT",
- "android.bluetooth.adapter.action.STATE_CHANGED",
- "android.bluetooth.adapter.action.SCAN_MODE_CHANGED",
- "android.bluetooth.adapter.action.DISCOVERY_STARTED",
- "android.bluetooth.adapter.action.DISCOVERY_FINISHED",
- "android.bluetooth.adapter.action.LOCAL_NAME_CHANGED",
- "android.bluetooth.adapter.action.BLUETOOTH_ADDRESS_CHANGED",
- "android.bluetooth.adapter.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.device.action.UUID",
- "android.bluetooth.device.action.MAS_INSTANCE",
- "android.bluetooth.device.action.ALIAS_CHANGED",
- "android.bluetooth.device.action.FOUND",
- "android.bluetooth.device.action.CLASS_CHANGED",
- "android.bluetooth.device.action.ACL_CONNECTED",
- "android.bluetooth.device.action.ACL_DISCONNECT_REQUESTED",
- "android.bluetooth.device.action.ACL_DISCONNECTED",
- "android.bluetooth.device.action.NAME_CHANGED",
- "android.bluetooth.device.action.BOND_STATE_CHANGED",
- "android.bluetooth.device.action.NAME_FAILED",
- "android.bluetooth.device.action.PAIRING_REQUEST",
- "android.bluetooth.device.action.PAIRING_CANCEL",
- "android.bluetooth.device.action.CONNECTION_ACCESS_REPLY",
- "android.bluetooth.device.action.CONNECTION_ACCESS_CANCEL",
- "android.bluetooth.device.action.CONNECTION_ACCESS_REQUEST",
- "android.bluetooth.device.action.SDP_RECORD",
- "android.bluetooth.device.action.BATTERY_LEVEL_CHANGED",
- "android.bluetooth.devicepicker.action.LAUNCH",
- "android.bluetooth.devicepicker.action.DEVICE_SELECTED",
- "android.bluetooth.action.CSIS_CONNECTION_STATE_CHANGED",
- "android.bluetooth.action.CSIS_DEVICE_AVAILABLE",
- "android.bluetooth.action.CSIS_SET_MEMBER_AVAILABLE",
- "android.bluetooth.mapmce.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.mapmce.profile.action.MESSAGE_RECEIVED",
- "android.bluetooth.mapmce.profile.action.MESSAGE_SENT_SUCCESSFULLY",
- "android.bluetooth.mapmce.profile.action.MESSAGE_DELIVERED_SUCCESSFULLY",
- "android.bluetooth.mapmce.profile.action.MESSAGE_READ_STATUS_CHANGED",
- "android.bluetooth.mapmce.profile.action.MESSAGE_DELETED_STATUS_CHANGED",
- "android.bluetooth.action.LE_AUDIO_CONNECTION_STATE_CHANGED",
- "android.bluetooth.action.LE_AUDIO_ACTIVE_DEVICE_CHANGED",
- "android.bluetooth.action.LE_AUDIO_CONF_CHANGED",
- "android.bluetooth.action.LE_AUDIO_GROUP_NODE_STATUS_CHANGED",
- "android.bluetooth.action.LE_AUDIO_GROUP_STATUS_CHANGED",
- "android.bluetooth.pbap.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.pbapclient.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.sap.profile.action.CONNECTION_STATE_CHANGED",
- "android.btopp.intent.action.INCOMING_FILE_NOTIFICATION",
- "android.btopp.intent.action.USER_CONFIRMATION_TIMEOUT",
- "android.btopp.intent.action.LIST",
- "android.btopp.intent.action.OPEN_OUTBOUND",
- "android.btopp.intent.action.HIDE_COMPLETE",
- "android.btopp.intent.action.CONFIRM",
- "android.btopp.intent.action.HIDE",
- "android.btopp.intent.action.RETRY",
- "android.btopp.intent.action.OPEN",
- "android.btopp.intent.action.OPEN_INBOUND",
- "android.btopp.intent.action.TRANSFER_COMPLETE",
- "android.btopp.intent.action.ACCEPT",
- "android.btopp.intent.action.DECLINE",
- "com.android.bluetooth.gatt.REFRESH_BATCHED_SCAN",
- "com.android.bluetooth.pbap.authchall",
- "com.android.bluetooth.pbap.userconfirmtimeout",
- "com.android.bluetooth.pbap.authresponse",
- "com.android.bluetooth.pbap.authcancelled",
- "com.android.bluetooth.sap.USER_CONFIRM_TIMEOUT",
- "com.android.bluetooth.sap.action.DISCONNECT_ACTION",
- "android.hardware.display.action.WIFI_DISPLAY_STATUS_CHANGED",
- "android.hardware.usb.action.USB_STATE",
- "android.hardware.usb.action.USB_PORT_CHANGED",
- "android.hardware.usb.action.USB_ACCESSORY_ATTACHED",
- "android.hardware.usb.action.USB_ACCESSORY_DETACHED",
- "android.hardware.usb.action.USB_ACCESSORY_HANDSHAKE",
- "android.hardware.usb.action.USB_DEVICE_ATTACHED",
- "android.hardware.usb.action.USB_DEVICE_DETACHED",
- "android.intent.action.HEADSET_PLUG",
- "android.media.action.HDMI_AUDIO_PLUG",
- "android.media.action.MICROPHONE_MUTE_CHANGED",
- "android.media.action.SPEAKERPHONE_STATE_CHANGED",
- "android.media.AUDIO_BECOMING_NOISY",
- "android.media.RINGER_MODE_CHANGED",
- "android.media.VIBRATE_SETTING_CHANGED",
- "android.media.VOLUME_CHANGED_ACTION",
- "android.media.MASTER_VOLUME_CHANGED_ACTION",
- "android.media.MASTER_MUTE_CHANGED_ACTION",
- "android.media.MASTER_MONO_CHANGED_ACTION",
- "android.media.MASTER_BALANCE_CHANGED_ACTION",
- "android.media.SCO_AUDIO_STATE_CHANGED",
- "android.media.ACTION_SCO_AUDIO_STATE_UPDATED",
- "android.intent.action.MEDIA_REMOVED",
- "android.intent.action.MEDIA_UNMOUNTED",
- "android.intent.action.MEDIA_CHECKING",
- "android.intent.action.MEDIA_NOFS",
- "android.intent.action.MEDIA_MOUNTED",
- "android.intent.action.MEDIA_SHARED",
- "android.intent.action.MEDIA_UNSHARED",
- "android.intent.action.MEDIA_BAD_REMOVAL",
- "android.intent.action.MEDIA_UNMOUNTABLE",
- "android.intent.action.MEDIA_EJECT",
- "android.net.conn.CAPTIVE_PORTAL",
- "android.net.conn.CONNECTIVITY_CHANGE",
- "android.net.conn.CONNECTIVITY_CHANGE_IMMEDIATE",
- "android.net.conn.DATA_ACTIVITY_CHANGE",
- "android.net.conn.RESTRICT_BACKGROUND_CHANGED",
- "android.net.conn.BACKGROUND_DATA_SETTING_CHANGED",
- "android.net.conn.CAPTIVE_PORTAL_TEST_COMPLETED",
- "android.net.nsd.STATE_CHANGED",
- "android.se.omapi.action.SECURE_ELEMENT_STATE_CHANGED",
- "android.nfc.action.ADAPTER_STATE_CHANGED",
- "android.nfc.action.PREFERRED_PAYMENT_CHANGED",
- "android.nfc.action.TRANSACTION_DETECTED",
- "android.nfc.action.REQUIRE_UNLOCK_FOR_NFC",
- "com.android.nfc.action.LLCP_UP",
- "com.android.nfc.action.LLCP_DOWN",
- "com.android.nfc.cardemulation.action.CLOSE_TAP_DIALOG",
- "com.android.nfc.handover.action.ALLOW_CONNECT",
- "com.android.nfc.handover.action.DENY_CONNECT",
- "com.android.nfc.handover.action.TIMEOUT_CONNECT",
- "com.android.nfc_extras.action.RF_FIELD_ON_DETECTED",
- "com.android.nfc_extras.action.RF_FIELD_OFF_DETECTED",
- "com.android.nfc_extras.action.AID_SELECTED",
- "android.btopp.intent.action.WHITELIST_DEVICE",
- "android.btopp.intent.action.STOP_HANDOVER_TRANSFER",
- "android.nfc.handover.intent.action.HANDOVER_SEND",
- "android.nfc.handover.intent.action.HANDOVER_SEND_MULTIPLE",
- "com.android.nfc.handover.action.CANCEL_HANDOVER_TRANSFER",
- "android.net.action.CLEAR_DNS_CACHE",
- "android.intent.action.PROXY_CHANGE",
- "android.os.UpdateLock.UPDATE_LOCK_CHANGED",
- "android.intent.action.DREAMING_STARTED",
- "android.intent.action.DREAMING_STOPPED",
- "android.intent.action.ANY_DATA_STATE",
- "com.android.server.stats.action.TRIGGER_COLLECTION",
- "com.android.server.WifiManager.action.START_SCAN",
- "com.android.server.WifiManager.action.START_PNO",
- "com.android.server.WifiManager.action.DELAYED_DRIVER_STOP",
- "com.android.server.WifiManager.action.DEVICE_IDLE",
- "com.android.server.action.REMOTE_BUGREPORT_SHARING_ACCEPTED",
- "com.android.server.action.REMOTE_BUGREPORT_SHARING_DECLINED",
- "com.android.internal.action.EUICC_FACTORY_RESET",
- "com.android.server.usb.ACTION_OPEN_IN_APPS",
- "com.android.server.am.DELETE_DUMPHEAP",
- "com.android.server.net.action.SNOOZE_WARNING",
- "com.android.server.net.action.SNOOZE_RAPID",
- "com.android.server.wifi.ACTION_SHOW_SET_RANDOMIZATION_DETAILS",
- "com.android.server.wifi.action.NetworkSuggestion.USER_ALLOWED_APP",
- "com.android.server.wifi.action.NetworkSuggestion.USER_DISALLOWED_APP",
- "com.android.server.wifi.action.NetworkSuggestion.USER_DISMISSED",
- "com.android.server.wifi.action.CarrierNetwork.USER_ALLOWED_CARRIER",
- "com.android.server.wifi.action.CarrierNetwork.USER_DISALLOWED_CARRIER",
- "com.android.server.wifi.action.CarrierNetwork.USER_DISMISSED",
- "com.android.server.wifi.ConnectToNetworkNotification.USER_DISMISSED_NOTIFICATION",
- "com.android.server.wifi.ConnectToNetworkNotification.CONNECT_TO_NETWORK",
- "com.android.server.wifi.ConnectToNetworkNotification.PICK_WIFI_NETWORK",
- "com.android.server.wifi.ConnectToNetworkNotification.PICK_NETWORK_AFTER_FAILURE",
- "com.android.server.wifi.wakeup.DISMISS_NOTIFICATION",
- "com.android.server.wifi.wakeup.OPEN_WIFI_PREFERENCES",
- "com.android.server.wifi.wakeup.OPEN_WIFI_SETTINGS",
- "com.android.server.wifi.wakeup.TURN_OFF_WIFI_WAKE",
- "android.net.wifi.WIFI_STATE_CHANGED",
- "android.net.wifi.WIFI_AP_STATE_CHANGED",
- "android.net.wifi.WIFI_CREDENTIAL_CHANGED",
- "android.net.wifi.aware.action.WIFI_AWARE_STATE_CHANGED",
- "android.net.wifi.aware.action.WIFI_AWARE_RESOURCE_CHANGED",
- "android.net.wifi.rtt.action.WIFI_RTT_STATE_CHANGED",
- "android.net.wifi.SCAN_RESULTS",
- "android.net.wifi.RSSI_CHANGED",
- "android.net.wifi.STATE_CHANGE",
- "android.net.wifi.LINK_CONFIGURATION_CHANGED",
- "android.net.wifi.CONFIGURED_NETWORKS_CHANGE",
- "android.net.wifi.action.NETWORK_SETTINGS_RESET",
- "android.net.wifi.action.PASSPOINT_DEAUTH_IMMINENT",
- "android.net.wifi.action.PASSPOINT_ICON",
- "android.net.wifi.action.PASSPOINT_OSU_PROVIDERS_LIST",
- "android.net.wifi.action.PASSPOINT_SUBSCRIPTION_REMEDIATION",
- "android.net.wifi.action.PASSPOINT_LAUNCH_OSU_VIEW",
- "android.net.wifi.action.REFRESH_USER_PROVISIONING",
- "android.net.wifi.action.WIFI_NETWORK_SUGGESTION_POST_CONNECTION",
- "android.net.wifi.action.WIFI_SCAN_AVAILABILITY_CHANGED",
- "android.net.wifi.supplicant.CONNECTION_CHANGE",
- "android.net.wifi.supplicant.STATE_CHANGE",
- "android.net.wifi.p2p.STATE_CHANGED",
- "android.net.wifi.p2p.DISCOVERY_STATE_CHANGE",
- "android.net.wifi.p2p.THIS_DEVICE_CHANGED",
- "android.net.wifi.p2p.PEERS_CHANGED",
- "android.net.wifi.p2p.CONNECTION_STATE_CHANGE",
- "android.net.wifi.p2p.action.WIFI_P2P_PERSISTENT_GROUPS_CHANGED",
- "android.net.conn.TETHER_STATE_CHANGED",
- "android.net.conn.INET_CONDITION_ACTION",
- "android.net.conn.NETWORK_CONDITIONS_MEASURED",
- "android.net.scoring.SCORE_NETWORKS",
- "android.net.scoring.SCORER_CHANGED",
- "android.intent.action.EXTERNAL_APPLICATIONS_AVAILABLE",
- "android.intent.action.EXTERNAL_APPLICATIONS_UNAVAILABLE",
- "android.intent.action.AIRPLANE_MODE",
- "android.intent.action.ADVANCED_SETTINGS",
- "android.intent.action.APPLICATION_RESTRICTIONS_CHANGED",
- "com.android.server.adb.WIRELESS_DEBUG_PAIRED_DEVICES",
- "com.android.server.adb.WIRELESS_DEBUG_PAIRING_RESULT",
- "com.android.server.adb.WIRELESS_DEBUG_STATUS",
- "android.intent.action.ACTION_IDLE_MAINTENANCE_START",
- "android.intent.action.ACTION_IDLE_MAINTENANCE_END",
- "com.android.server.ACTION_TRIGGER_IDLE",
- "android.intent.action.HDMI_PLUGGED",
- "android.intent.action.PHONE_STATE",
- "android.intent.action.SUB_DEFAULT_CHANGED",
- "android.location.PROVIDERS_CHANGED",
- "android.location.MODE_CHANGED",
- "android.location.action.GNSS_CAPABILITIES_CHANGED",
- "android.net.proxy.PAC_REFRESH",
- "android.telecom.action.DEFAULT_DIALER_CHANGED",
- "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED",
- "android.provider.action.SMS_MMS_DB_CREATED",
- "android.provider.action.SMS_MMS_DB_LOST",
- "android.intent.action.CONTENT_CHANGED",
- "android.provider.Telephony.MMS_DOWNLOADED",
- "android.content.action.PERMISSION_RESPONSE_RECEIVED",
- "android.content.action.REQUEST_PERMISSION",
- "android.nfc.handover.intent.action.HANDOVER_STARTED",
- "android.nfc.handover.intent.action.TRANSFER_DONE",
- "android.nfc.handover.intent.action.TRANSFER_PROGRESS",
- "android.nfc.handover.intent.action.TRANSFER_DONE",
- "android.intent.action.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED",
- "android.intent.action.ACTION_DEFAULT_VOICE_SUBSCRIPTION_CHANGED",
- "android.intent.action.ACTION_SET_RADIO_CAPABILITY_DONE",
- "android.intent.action.ACTION_SET_RADIO_CAPABILITY_FAILED",
- "android.internal.policy.action.BURN_IN_PROTECTION",
- "android.app.action.SYSTEM_UPDATE_POLICY_CHANGED",
- "android.app.action.RESET_PROTECTION_POLICY_CHANGED",
- "android.app.action.DEVICE_OWNER_CHANGED",
- "android.app.action.MANAGED_USER_CREATED",
- "android.intent.action.ANR",
- "android.intent.action.CALL",
- "android.intent.action.CALL_PRIVILEGED",
- "android.intent.action.DROPBOX_ENTRY_ADDED",
- "android.intent.action.INPUT_METHOD_CHANGED",
- "android.intent.action.internal_sim_state_changed",
- "android.intent.action.LOCKED_BOOT_COMPLETED",
- "android.intent.action.PRECISE_CALL_STATE",
- "android.intent.action.SUBSCRIPTION_PHONE_STATE",
- "android.intent.action.USER_INFO_CHANGED",
- "android.intent.action.USER_UNLOCKED",
- "android.intent.action.WALLPAPER_CHANGED",
- "android.app.action.DEVICE_POLICY_MANAGER_STATE_CHANGED",
- "android.app.action.CHOOSE_PRIVATE_KEY_ALIAS",
- "android.app.action.DEVICE_ADMIN_DISABLED",
- "android.app.action.DEVICE_ADMIN_DISABLE_REQUESTED",
- "android.app.action.DEVICE_ADMIN_ENABLED",
- "android.app.action.LOCK_TASK_ENTERING",
- "android.app.action.LOCK_TASK_EXITING",
- "android.app.action.NOTIFY_PENDING_SYSTEM_UPDATE",
- "android.app.action.ACTION_PASSWORD_CHANGED",
- "android.app.action.ACTION_PASSWORD_EXPIRING",
- "android.app.action.ACTION_PASSWORD_FAILED",
- "android.app.action.ACTION_PASSWORD_SUCCEEDED",
- "com.android.server.ACTION_EXPIRED_PASSWORD_NOTIFICATION",
- "com.android.server.ACTION_PROFILE_OFF_DEADLINE",
- "com.android.server.ACTION_TURN_PROFILE_ON_NOTIFICATION",
- "android.intent.action.MANAGED_PROFILE_ADDED",
- "android.intent.action.MANAGED_PROFILE_UNLOCKED",
- "android.intent.action.MANAGED_PROFILE_REMOVED",
- "android.app.action.MANAGED_PROFILE_PROVISIONED",
- "android.bluetooth.adapter.action.BLE_STATE_CHANGED",
- "com.android.bluetooth.map.USER_CONFIRM_TIMEOUT",
- "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT",
- "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY",
- "android.content.jobscheduler.JOB_DELAY_EXPIRED",
- "android.content.syncmanager.SYNC_ALARM",
- "android.media.INTERNAL_RINGER_MODE_CHANGED_ACTION",
- "android.media.STREAM_DEVICES_CHANGED_ACTION",
- "android.media.STREAM_MUTE_CHANGED_ACTION",
- "android.net.sip.SIP_SERVICE_UP",
- "android.nfc.action.ADAPTER_STATE_CHANGED",
- "android.os.action.CHARGING",
- "android.os.action.DISCHARGING",
- "android.search.action.SEARCHABLES_CHANGED",
- "android.security.STORAGE_CHANGED",
- "android.security.action.TRUST_STORE_CHANGED",
- "android.security.action.KEYCHAIN_CHANGED",
- "android.security.action.KEY_ACCESS_CHANGED",
- "android.telecom.action.NUISANCE_CALL_STATUS_CHANGED",
- "android.telecom.action.PHONE_ACCOUNT_REGISTERED",
- "android.telecom.action.PHONE_ACCOUNT_UNREGISTERED",
- "android.telecom.action.POST_CALL",
- "android.telecom.action.SHOW_MISSED_CALLS_NOTIFICATION",
- "android.telephony.action.CARRIER_CONFIG_CHANGED",
- "android.telephony.action.DEFAULT_SUBSCRIPTION_CHANGED",
- "android.telephony.action.DEFAULT_SMS_SUBSCRIPTION_CHANGED",
- "android.telephony.action.SECRET_CODE",
- "android.telephony.action.SHOW_VOICEMAIL_NOTIFICATION",
- "android.telephony.action.SUBSCRIPTION_PLANS_CHANGED",
- "com.android.bluetooth.btservice.action.ALARM_WAKEUP",
- "com.android.server.action.NETWORK_STATS_POLL",
- "com.android.server.action.NETWORK_STATS_UPDATED",
- "com.android.server.timedetector.NetworkTimeUpdateService.action.POLL",
- "com.android.server.telecom.intent.action.CALLS_ADD_ENTRY",
- "com.android.settings.location.MODE_CHANGING",
- "com.android.settings.bluetooth.ACTION_DISMISS_PAIRING",
- "com.android.settings.network.DELETE_SUBSCRIPTION",
- "com.android.settings.network.SWITCH_TO_SUBSCRIPTION",
- "com.android.settings.wifi.action.NETWORK_REQUEST",
- "NotificationManagerService.TIMEOUT",
- "NotificationHistoryDatabase.CLEANUP",
- "ScheduleConditionProvider.EVALUATE",
- "EventConditionProvider.EVALUATE",
- "SnoozeHelper.EVALUATE",
- "wifi_scan_available",
- "action.cne.started",
- "android.content.jobscheduler.JOB_DEADLINE_EXPIRED",
- "android.intent.action.ACTION_UNSOL_RESPONSE_OEM_HOOK_RAW",
- "android.net.conn.CONNECTIVITY_CHANGE_SUPL",
- "android.os.action.LIGHT_DEVICE_IDLE_MODE_CHANGED",
- "android.os.storage.action.VOLUME_STATE_CHANGED",
- "android.os.storage.action.DISK_SCANNED",
- "com.android.server.action.UPDATE_TWILIGHT_STATE",
- "com.android.server.action.RESET_TWILIGHT_AUTO",
- "com.android.server.device_idle.STEP_IDLE_STATE",
- "com.android.server.device_idle.STEP_LIGHT_IDLE_STATE",
- "com.android.server.Wifi.action.TOGGLE_PNO",
- "intent.action.ACTION_RF_BAND_INFO",
- "android.intent.action.MEDIA_RESOURCE_GRANTED",
- "android.app.action.NETWORK_LOGS_AVAILABLE",
- "android.app.action.SECURITY_LOGS_AVAILABLE",
- "android.app.action.COMPLIANCE_ACKNOWLEDGEMENT_REQUIRED",
- "android.app.action.INTERRUPTION_FILTER_CHANGED",
- "android.app.action.INTERRUPTION_FILTER_CHANGED_INTERNAL",
- "android.app.action.NOTIFICATION_POLICY_CHANGED",
- "android.app.action.NOTIFICATION_POLICY_ACCESS_GRANTED_CHANGED",
- "android.app.action.AUTOMATIC_ZEN_RULE_STATUS_CHANGED",
- "android.os.action.ACTION_EFFECTS_SUPPRESSOR_CHANGED",
- "android.app.action.NOTIFICATION_CHANNEL_BLOCK_STATE_CHANGED",
- "android.app.action.NOTIFICATION_CHANNEL_GROUP_BLOCK_STATE_CHANGED",
- "android.app.action.NOTIFICATION_LISTENER_ENABLED_CHANGED",
- "android.app.action.APP_BLOCK_STATE_CHANGED",
- "android.permission.GET_APP_GRANTED_URI_PERMISSIONS",
- "android.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS",
- "android.intent.action.DYNAMIC_SENSOR_CHANGED",
- "android.accounts.LOGIN_ACCOUNTS_CHANGED",
- "android.accounts.action.ACCOUNT_REMOVED",
- "android.accounts.action.VISIBLE_ACCOUNTS_CHANGED",
- "com.android.sync.SYNC_CONN_STATUS_CHANGED",
- "android.net.sip.action.SIP_INCOMING_CALL",
- "com.android.phone.SIP_ADD_PHONE",
- "android.net.sip.action.SIP_REMOVE_PROFILE",
- "android.net.sip.action.SIP_SERVICE_UP",
- "android.net.sip.action.SIP_CALL_OPTION_CHANGED",
- "android.net.sip.action.START_SIP",
- "android.bluetooth.adapter.action.BLE_ACL_CONNECTED",
- "android.bluetooth.adapter.action.BLE_ACL_DISCONNECTED",
- "android.bluetooth.input.profile.action.HANDSHAKE",
- "android.bluetooth.input.profile.action.REPORT",
- "android.intent.action.TWILIGHT_CHANGED",
- "com.android.server.fingerprint.ACTION_LOCKOUT_RESET",
- "android.net.wifi.PASSPOINT_ICON_RECEIVED",
- "com.android.server.notification.CountdownConditionProvider",
- "android.server.notification.action.ENABLE_NAS",
- "android.server.notification.action.DISABLE_NAS",
- "android.server.notification.action.LEARNMORE_NAS",
- "com.android.internal.location.ALARM_WAKEUP",
- "com.android.internal.location.ALARM_TIMEOUT",
- "android.intent.action.GLOBAL_BUTTON",
- "android.intent.action.MANAGED_PROFILE_AVAILABLE",
- "android.intent.action.MANAGED_PROFILE_UNAVAILABLE",
- "com.android.server.pm.DISABLE_QUIET_MODE_AFTER_UNLOCK",
- "android.intent.action.PROFILE_ACCESSIBLE",
- "android.intent.action.PROFILE_INACCESSIBLE",
- "com.android.server.retaildemo.ACTION_RESET_DEMO",
- "android.intent.action.DEVICE_LOCKED_CHANGED",
- "com.android.content.pm.action.CAN_INTERACT_ACROSS_PROFILES_CHANGED",
- "android.app.action.APPLICATION_DELEGATION_SCOPES_CHANGED",
- "com.android.server.wm.ACTION_REVOKE_SYSTEM_ALERT_WINDOW_PERMISSION",
- "android.media.tv.action.PARENTAL_CONTROLS_ENABLED_CHANGED",
- "android.content.pm.action.SESSION_COMMITTED",
- "android.os.action.USER_RESTRICTIONS_CHANGED",
- "android.media.tv.action.PREVIEW_PROGRAM_ADDED_TO_WATCH_NEXT",
- "android.media.tv.action.PREVIEW_PROGRAM_BROWSABLE_DISABLED",
- "android.media.tv.action.WATCH_NEXT_PROGRAM_BROWSABLE_DISABLED",
- "android.media.tv.action.CHANNEL_BROWSABLE_REQUESTED",
- "com.android.server.inputmethod.InputMethodManagerService.SHOW_INPUT_METHOD_PICKER",
- "com.android.intent.action.timezone.RULES_UPDATE_OPERATION",
- "com.android.intent.action.timezone.TRIGGER_RULES_UPDATE_CHECK",
- "android.intent.action.GET_RESTRICTION_ENTRIES",
- "android.telephony.euicc.action.OTA_STATUS_CHANGED",
- "android.app.action.PROFILE_OWNER_CHANGED",
- "android.app.action.TRANSFER_OWNERSHIP_COMPLETE",
- "android.app.action.AFFILIATED_PROFILE_TRANSFER_OWNERSHIP_COMPLETE",
- "android.app.action.STATSD_STARTED",
- "com.android.server.biometrics.fingerprint.ACTION_LOCKOUT_RESET",
- "com.android.server.biometrics.face.ACTION_LOCKOUT_RESET",
- "android.intent.action.DOCK_IDLE",
- "android.intent.action.DOCK_ACTIVE",
- "android.content.pm.action.SESSION_UPDATED",
- "android.settings.action.GRAYSCALE_CHANGED",
- "com.android.server.jobscheduler.GARAGE_MODE_ON",
- "com.android.server.jobscheduler.GARAGE_MODE_OFF",
- "com.android.server.jobscheduler.FORCE_IDLE",
- "com.android.server.jobscheduler.UNFORCE_IDLE",
- "android.provider.action.DEFAULT_SMS_PACKAGE_CHANGED_INTERNAL",
- "android.intent.action.DEVICE_CUSTOMIZATION_READY",
- "android.app.action.RESET_PROTECTION_POLICY_CHANGED",
- "com.android.internal.intent.action.BUGREPORT_REQUESTED",
- "android.scheduling.action.REBOOT_READY",
- "android.app.action.DEVICE_POLICY_CONSTANTS_CHANGED",
- "android.app.action.SCHEDULE_EXACT_ALARM_PERMISSION_STATE_CHANGED",
- "android.app.action.SHOW_NEW_USER_DISCLAIMER",
- "android.telecom.action.CURRENT_TTY_MODE_CHANGED",
- "android.intent.action.SERVICE_STATE",
- "android.intent.action.RADIO_TECHNOLOGY",
- "android.intent.action.EMERGENCY_CALLBACK_MODE_CHANGED",
- "android.intent.action.EMERGENCY_CALL_STATE_CHANGED",
- "android.intent.action.SIG_STR",
- "android.intent.action.ANY_DATA_STATE",
- "android.intent.action.DATA_STALL_DETECTED",
- "android.intent.action.SIM_STATE_CHANGED",
- "android.intent.action.USER_ACTIVITY_NOTIFICATION",
- "android.telephony.action.SHOW_NOTICE_ECM_BLOCK_OTHERS",
- "android.intent.action.ACTION_MDN_STATE_CHANGED",
- "android.telephony.action.SERVICE_PROVIDERS_UPDATED",
- "android.provider.Telephony.SIM_FULL",
- "com.android.internal.telephony.carrier_key_download_alarm",
- "com.android.internal.telephony.data-restart-trysetup",
- "com.android.internal.telephony.data-stall",
- "com.android.internal.telephony.provisioning_apn_alarm",
- "android.intent.action.DATA_SMS_RECEIVED",
- "android.provider.Telephony.SMS_RECEIVED",
- "android.provider.Telephony.SMS_DELIVER",
- "android.provider.Telephony.SMS_REJECTED",
- "android.provider.Telephony.WAP_PUSH_DELIVER",
- "android.provider.Telephony.WAP_PUSH_RECEIVED",
- "android.provider.Telephony.SMS_CB_RECEIVED",
- "android.provider.action.SMS_EMERGENCY_CB_RECEIVED",
- "android.provider.Telephony.SMS_SERVICE_CATEGORY_PROGRAM_DATA_RECEIVED",
- "android.provider.Telephony.SECRET_CODE",
- "com.android.internal.stk.command",
- "com.android.internal.stk.session_end",
- "com.android.internal.stk.icc_status_change",
- "com.android.internal.stk.alpha_notify",
- "com.android.internal.telephony.CARRIER_SIGNAL_REDIRECTED",
- "com.android.internal.telephony.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED",
- "com.android.internal.telephony.CARRIER_SIGNAL_PCO_VALUE",
- "com.android.internal.telephony.CARRIER_SIGNAL_RESET",
- "com.android.internal.telephony.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE",
- "com.android.internal.telephony.PROVISION",
- "com.android.internal.telephony.ACTION_LINE1_NUMBER_ERROR_DETECTED",
- "com.android.internal.provider.action.VOICEMAIL_SMS_RECEIVED",
- "com.android.intent.isim_refresh",
- "com.android.ims.ACTION_RCS_SERVICE_AVAILABLE",
- "com.android.ims.ACTION_RCS_SERVICE_UNAVAILABLE",
- "com.android.ims.ACTION_RCS_SERVICE_DIED",
- "com.android.ims.ACTION_PRESENCE_CHANGED",
- "com.android.ims.ACTION_PUBLISH_STATUS_CHANGED",
- "com.android.ims.IMS_SERVICE_UP",
- "com.android.ims.IMS_SERVICE_DOWN",
- "com.android.ims.IMS_INCOMING_CALL",
- "com.android.ims.internal.uce.UCE_SERVICE_UP",
- "com.android.ims.internal.uce.UCE_SERVICE_DOWN",
- "com.android.imsconnection.DISCONNECTED",
- "com.android.intent.action.IMS_FEATURE_CHANGED",
- "com.android.intent.action.IMS_CONFIG_CHANGED",
- "android.telephony.ims.action.WFC_IMS_REGISTRATION_ERROR",
- "com.android.phone.vvm.omtp.sms.REQUEST_SENT",
- "com.android.phone.vvm.ACTION_VISUAL_VOICEMAIL_SERVICE_EVENT",
- "com.android.internal.telephony.CARRIER_VVM_PACKAGE_INSTALLED",
- "com.android.cellbroadcastreceiver.GET_LATEST_CB_AREA_INFO",
- "com.android.internal.telephony.ACTION_CARRIER_CERTIFICATE_DOWNLOAD",
- "com.android.internal.telephony.action.COUNTRY_OVERRIDE",
- "com.android.internal.telephony.OPEN_DEFAULT_SMS_APP",
- "com.android.internal.telephony.ACTION_TEST_OVERRIDE_CARRIER_ID",
- "android.telephony.action.SIM_CARD_STATE_CHANGED",
- "android.telephony.action.SIM_APPLICATION_STATE_CHANGED",
- "android.telephony.action.SIM_SLOT_STATUS_CHANGED",
- "android.telephony.action.SUBSCRIPTION_CARRIER_IDENTITY_CHANGED",
- "android.telephony.action.SUBSCRIPTION_SPECIFIC_CARRIER_IDENTITY_CHANGED",
- "android.telephony.action.TOGGLE_PROVISION",
- "android.telephony.action.NETWORK_COUNTRY_CHANGED",
- "android.telephony.action.PRIMARY_SUBSCRIPTION_LIST_CHANGED",
- "android.telephony.action.MULTI_SIM_CONFIG_CHANGED",
- "android.telephony.action.CARRIER_SIGNAL_RESET",
- "android.telephony.action.CARRIER_SIGNAL_PCO_VALUE",
- "android.telephony.action.CARRIER_SIGNAL_DEFAULT_NETWORK_AVAILABLE",
- "android.telephony.action.CARRIER_SIGNAL_REDIRECTED",
- "android.telephony.action.CARRIER_SIGNAL_REQUEST_NETWORK_FAILED",
- "com.android.phone.settings.CARRIER_PROVISIONING",
- "com.android.phone.settings.TRIGGER_CARRIER_PROVISIONING",
- "com.android.internal.telephony.ACTION_VOWIFI_ENABLED",
- "android.telephony.action.ANOMALY_REPORTED",
- "android.intent.action.SUBSCRIPTION_INFO_RECORD_ADDED",
- "android.intent.action.ACTION_MANAGED_ROAMING_IND",
- "android.telephony.ims.action.RCS_SINGLE_REGISTRATION_CAPABILITY_UPDATE",
- "android.safetycenter.action.REFRESH_SAFETY_SOURCES",
- "android.safetycenter.action.SAFETY_CENTER_ENABLED_CHANGED",
- "android.app.action.DEVICE_POLICY_RESOURCE_UPDATED",
- "android.intent.action.SHOW_FOREGROUND_SERVICE_MANAGER",
- "android.service.autofill.action.DELAYED_FILL",
- "android.app.action.PROVISIONING_COMPLETED",
- "android.app.action.LOST_MODE_LOCATION_UPDATE",
- "android.bluetooth.headset.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.headset.profile.action.AUDIO_STATE_CHANGED",
- "android.bluetooth.headset.action.VENDOR_SPECIFIC_HEADSET_EVENT",
- "android.bluetooth.headset.action.HF_INDICATORS_VALUE_CHANGED",
- "android.bluetooth.headset.profile.action.ACTIVE_DEVICE_CHANGED",
- "android.bluetooth.headsetclient.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.headsetclient.profile.action.AUDIO_STATE_CHANGED",
- "android.bluetooth.headsetclient.profile.action.AG_EVENT",
- "android.bluetooth.headsetclient.profile.action.AG_CALL_CHANGED",
- "android.bluetooth.headsetclient.profile.action.RESULT",
- "android.bluetooth.headsetclient.profile.action.LAST_VTAG",
- "android.bluetooth.headsetclient.profile.action.NETWORK_SERVICE_STATE_CHANGED",
- "android.bluetooth.hearingaid.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.hearingaid.profile.action.PLAYING_STATE_CHANGED",
- "android.bluetooth.hearingaid.profile.action.ACTIVE_DEVICE_CHANGED",
- "android.bluetooth.volume-control.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.a2dp.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.a2dp.profile.action.ACTIVE_DEVICE_CHANGED",
- "android.bluetooth.a2dp.profile.action.PLAYING_STATE_CHANGED",
- "android.bluetooth.a2dp.profile.action.CODEC_CONFIG_CHANGED",
- "android.bluetooth.a2dp-sink.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.a2dp-sink.profile.action.PLAYING_STATE_CHANGED",
- "android.bluetooth.a2dp-sink.profile.action.AUDIO_CONFIG_CHANGED",
- "android.bluetooth.avrcp-controller.profile.action.BROWSE_CONNECTION_STATE_CHANGED",
- "android.bluetooth.avrcp-controller.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.avrcp-controller.profile.action.FOLDER_LIST",
- "android.bluetooth.avrcp-controller.profile.action.TRACK_EVENT",
- "android.bluetooth.input.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.input.profile.action.IDLE_TIME_CHANGED",
- "android.bluetooth.input.profile.action.PROTOCOL_MODE_CHANGED",
- "android.bluetooth.input.profile.action.VIRTUAL_UNPLUG_STATUS",
- "android.bluetooth.hiddevice.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.map.profile.action.CONNECTION_STATE_CHANGED",
- "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_SENT",
- "com.android.bluetooth.BluetoothMapContentObserver.action.MESSAGE_DELIVERY",
- "android.bluetooth.pan.profile.action.CONNECTION_STATE_CHANGED",
- "android.bluetooth.action.TETHERING_STATE_CHANGED",
- "com.android.internal.action.EUICC_REMOVE_INVISIBLE_SUBSCRIPTIONS",
- "android.net.ConnectivityService.action.PKT_CNT_SAMPLE_INTERVAL_ELAPSED",
- "com.android.server.connectivityservice.CONNECTED_TO_PROVISIONING_NETWORK_ACTION",
- "com.android.server.connectivity.tethering.PROVISIONING_RECHECK_ALARM"
- )
- }
-}
diff --git a/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt b/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
deleted file mode 100644
index 7c0ebca..0000000
--- a/tools/lint/framework/checks/src/test/java/com/google/android/lint/RegisterReceiverFlagDetectorTest.kt
+++ /dev/null
@@ -1,569 +0,0 @@
-/*
- * Copyright (C) 2021 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package com.google.android.lint
-
-import com.android.tools.lint.checks.infrastructure.LintDetectorTest
-import com.android.tools.lint.checks.infrastructure.TestFile
-import com.android.tools.lint.checks.infrastructure.TestLintTask
-import com.android.tools.lint.detector.api.Detector
-import com.android.tools.lint.detector.api.Issue
-
-@Suppress("UnstableApiUsage")
-class RegisterReceiverFlagDetectorTest : LintDetectorTest() {
-
- override fun getDetector(): Detector = RegisterReceiverFlagDetector()
-
- override fun getIssues(): List<Issue> = listOf(
- RegisterReceiverFlagDetector.ISSUE_RECEIVER_EXPORTED_FLAG
- )
-
- override fun lint(): TestLintTask = super.lint().allowMissingSdk(true)
-
- fun testProtectedBroadcast() {
- lint().files(
- java(
- """
- package test.pkg;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- public class TestClass1 {
- public void testMethod(Context context, BroadcastReceiver receiver) {
- IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
- context.registerReceiver(receiver, filter);
- }
- }
- """
- ).indented(),
- *stubs
- )
- .run()
- .expectClean()
- }
-
- fun testProtectedBroadcastCreate() {
- lint().files(
- java(
- """
- package test.pkg;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- public class TestClass1 {
- public void testMethod(Context context, BroadcastReceiver receiver) {
- IntentFilter filter =
- IntentFilter.create(Intent.ACTION_BATTERY_CHANGED, "foo/bar");
- context.registerReceiver(receiver, filter);
- }
- }
- """
- ).indented(),
- *stubs
- )
- .run()
- .expectClean()
- }
-
- fun testMultipleProtectedBroadcasts() {
- lint().files(
- java(
- """
- package test.pkg;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- public class TestClass1 {
- public void testMethod(Context context, BroadcastReceiver receiver) {
- IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
- filter.addAction(Intent.ACTION_BATTERY_LOW);
- filter.addAction(Intent.ACTION_BATTERY_OKAY);
- context.registerReceiver(receiver, filter);
- }
- }
- """
- ).indented(),
- *stubs
- )
- .run()
- .expectClean()
- }
-
- // TODO(b/267510341): Reenable this test
- // fun testSubsequentFilterModification() {
- // lint().files(
- // java(
- // """
- // package test.pkg;
- // import android.content.BroadcastReceiver;
- // import android.content.Context;
- // import android.content.Intent;
- // import android.content.IntentFilter;
- // public class TestClass1 {
- // public void testMethod(Context context, BroadcastReceiver receiver) {
- // IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
- // filter.addAction(Intent.ACTION_BATTERY_LOW);
- // filter.addAction(Intent.ACTION_BATTERY_OKAY);
- // context.registerReceiver(receiver, filter);
- // filter.addAction("querty");
- // context.registerReceiver(receiver, filter);
- // }
- // }
- // """
- // ).indented(),
- // *stubs
- // )
- // .run()
- // .expect("""
- // src/test/pkg/TestClass1.java:13: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
- // context.registerReceiver(receiver, filter);
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // 0 errors, 1 warnings
- // """.trimIndent())
- // }
-
- fun testNullReceiver() {
- lint().files(
- java(
- """
- package test.pkg;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- public class TestClass1 {
- public void testMethod(Context context) {
- IntentFilter filter = new IntentFilter("qwerty");
- context.registerReceiver(null, filter);
- }
- }
- """
- ).indented(),
- *stubs
- )
- .run()
- .expectClean()
- }
-
- fun testExportedFlagPresent() {
- lint().files(
- java(
- """
- package test.pkg;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- public class TestClass1 {
- public void testMethod(Context context, BroadcastReceiver receiver) {
- IntentFilter filter = new IntentFilter("qwerty");
- context.registerReceiver(receiver, filter, Context.RECEIVER_EXPORTED);
- }
- }
- """
- ).indented(),
- *stubs
- )
- .run()
- .expectClean()
- }
-
- fun testNotExportedFlagPresent() {
- lint().files(
- java(
- """
- package test.pkg;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- public class TestClass1 {
- public void testMethod(Context context, BroadcastReceiver receiver) {
- IntentFilter filter = new IntentFilter("qwerty");
- context.registerReceiver(receiver, filter,
- Context.RECEIVER_NOT_EXPORTED);
- }
- }
- """
- ).indented(),
- *stubs
- )
- .run()
- .expectClean()
- }
-
- // TODO(b/267510341): Reenable this test
- // fun testFlagArgumentAbsent() {
- // lint().files(
- // java(
- // """
- // package test.pkg;
- // import android.content.BroadcastReceiver;
- // import android.content.Context;
- // import android.content.Intent;
- // import android.content.IntentFilter;
- // public class TestClass1 {
- // public void testMethod(Context context, BroadcastReceiver receiver) {
- // IntentFilter filter = new IntentFilter("qwerty");
- // context.registerReceiver(receiver, filter);
- // }
- // }
- // """
- // ).indented(),
- // *stubs
- // )
- // .run()
- // .expect("""
- // src/test/pkg/TestClass1.java:9: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
- // context.registerReceiver(receiver, filter);
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // 0 errors, 1 warnings
- // """.trimIndent())
- // }
-
- // TODO(b/267510341): Reenable this test
- // fun testExportedFlagsAbsent() {
- // lint().files(
- // java(
- // """
- // package test.pkg;
- // import android.content.BroadcastReceiver;
- // import android.content.Context;
- // import android.content.Intent;
- // import android.content.IntentFilter;
- // public class TestClass1 {
- // public void testMethod(Context context, BroadcastReceiver receiver) {
- // IntentFilter filter = new IntentFilter("qwerty");
- // context.registerReceiver(receiver, filter, 0);
- // }
- // }
- // """
- // ).indented(),
- // *stubs
- // )
- // .run()
- // .expect("""
- // src/test/pkg/TestClass1.java:9: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
- // context.registerReceiver(receiver, filter, 0);
- // ~
- // 0 errors, 1 warnings
- // """.trimIndent())
- // }
-
- fun testExportedFlagVariable() {
- lint().files(
- java(
- """
- package test.pkg;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- public class TestClass1 {
- public void testMethod(Context context, BroadcastReceiver receiver) {
- IntentFilter filter = new IntentFilter("qwerty");
- var flags = Context.RECEIVER_EXPORTED;
- context.registerReceiver(receiver, filter, flags);
- }
- }
- """
- ).indented(),
- *stubs
- )
- .run()
- .expectClean()
- }
-
- // TODO(b/267510341): Reenable this test
- // fun testUnknownFilter() {
- // lint().files(
- // java(
- // """
- // package test.pkg;
- // import android.content.BroadcastReceiver;
- // import android.content.Context;
- // import android.content.Intent;
- // import android.content.IntentFilter;
- // public class TestClass1 {
- // public void testMethod(Context context, BroadcastReceiver receiver,
- // IntentFilter filter) {
- // context.registerReceiver(receiver, filter);
- // }
- // }
- // """
- // ).indented(),
- // *stubs
- // )
- // .run()
- // .expect("""
- // src/test/pkg/TestClass1.java:9: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
- // context.registerReceiver(receiver, filter);
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // 0 errors, 1 warnings
- // """.trimIndent())
- // }
-
- // TODO(b/267510341): Reenable this test
- // fun testFilterEscapes() {
- // lint().files(
- // java(
- // """
- // package test.pkg;
- // import android.content.BroadcastReceiver;
- // import android.content.Context;
- // import android.content.Intent;
- // import android.content.IntentFilter;
- // public class TestClass1 {
- // public void testMethod(Context context, BroadcastReceiver receiver) {
- // IntentFilter filter = new IntentFilter(Intent.ACTION_BATTERY_CHANGED);
- // updateFilter(filter);
- // context.registerReceiver(receiver, filter);
- // }
- // }
- // """
- // ).indented(),
- // *stubs
- // )
- // .run()
- // .expect("""
- // src/test/pkg/TestClass1.java:10: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
- // context.registerReceiver(receiver, filter);
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // 0 errors, 1 warnings
- // """.trimIndent())
- // }
-
- fun testInlineFilter() {
- lint().files(
- java(
- """
- package test.pkg;
- import android.content.BroadcastReceiver;
- import android.content.Context;
- import android.content.Intent;
- import android.content.IntentFilter;
- public class TestClass1 {
- public void testMethod(Context context, BroadcastReceiver receiver) {
- context.registerReceiver(receiver,
- new IntentFilter(Intent.ACTION_BATTERY_CHANGED));
- }
- }
- """
- ).indented(),
- *stubs
- )
- .run()
- .expectClean()
- }
-
- // TODO(b/267510341): Reenable this test
- // fun testInlineFilterApply() {
- // lint().files(
- // kotlin(
- // """
- // package test.pkg
- // import android.content.BroadcastReceiver
- // import android.content.Context
- // import android.content.Intent
- // import android.content.IntentFilter
- // class TestClass1 {
- // fun test(context: Context, receiver: BroadcastReceiver) {
- // context.registerReceiver(receiver,
- // IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
- // addAction("qwerty")
- // })
- // }
- // }
- // """
- // ).indented(),
- // *stubs
- // )
- // .run()
- // .expect("""
- // src/test/pkg/TestClass1.kt:8: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
- // context.registerReceiver(receiver,
- // ^
- // 0 errors, 1 warnings
- // """.trimIndent())
- // }
-
- // TODO(b/267510341): Reenable this test
- // fun testFilterVariableApply() {
- // lint().files(
- // kotlin(
- // """
- // package test.pkg
- // import android.content.BroadcastReceiver
- // import android.content.Context
- // import android.content.Intent
- // import android.content.IntentFilter
- // class TestClass1 {
- // fun test(context: Context, receiver: BroadcastReceiver) {
- // val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
- // addAction("qwerty")
- // }
- // context.registerReceiver(receiver, filter)
- // }
- // }
- // """
- // ).indented(),
- // *stubs
- // )
- // .run()
- // .expect("""
- // src/test/pkg/TestClass1.kt:11: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
- // context.registerReceiver(receiver, filter)
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // 0 errors, 1 warnings
- // """.trimIndent())
- // }
-
- // TODO(b/267510341): Reenable this test
- // fun testFilterVariableApply2() {
- // lint().files(
- // kotlin(
- // """
- // package test.pkg
- // import android.content.BroadcastReceiver
- // import android.content.Context
- // import android.content.Intent
- // import android.content.IntentFilter
- // class TestClass1 {
- // fun test(context: Context, receiver: BroadcastReceiver) {
- // val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
- // addAction(Intent.ACTION_BATTERY_OKAY)
- // }
- // context.registerReceiver(receiver, filter.apply {
- // addAction("qwerty")
- // })
- // }
- // }
- // """
- // ).indented(),
- // *stubs
- // )
- // .run()
- // .expect("""
- // src/test/pkg/TestClass1.kt:11: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
- // context.registerReceiver(receiver, filter.apply {
- // ^
- // 0 errors, 1 warnings
- // """.trimIndent())
- // }
-
- // TODO(b/267510341): Reenable this test
- // fun testFilterComplexChain() {
- // lint().files(
- // kotlin(
- // """
- // package test.pkg
- // import android.content.BroadcastReceiver
- // import android.content.Context
- // import android.content.Intent
- // import android.content.IntentFilter
- // class TestClass1 {
- // fun test(context: Context, receiver: BroadcastReceiver) {
- // val filter = IntentFilter(Intent.ACTION_BATTERY_CHANGED).apply {
- // addAction(Intent.ACTION_BATTERY_OKAY)
- // }
- // val filter2 = filter
- // val filter3 = filter2.apply {
- // addAction(Intent.ACTION_BATTERY_LOW)
- // }
- // context.registerReceiver(receiver, filter3)
- // val filter4 = filter3.apply {
- // addAction("qwerty")
- // }
- // context.registerReceiver(receiver, filter4)
- // }
- // }
- // """
- // ).indented(),
- // *stubs
- // )
- // .run()
- // .expect("""
- // src/test/pkg/TestClass1.kt:19: Warning: Missing RECEIVER_EXPORTED or RECEIVER_NOT_EXPORTED flag [UnspecifiedRegisterReceiverFlag]
- // context.registerReceiver(receiver, filter4)
- // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- // 0 errors, 1 warnings
- // """.trimIndent())
- // }
-
- private val broadcastReceiverStub: TestFile = java(
- """
- package android.content;
- public class BroadcastReceiver {
- // Stub
- }
- """
- ).indented()
-
- private val contextStub: TestFile = java(
- """
- package android.content;
- public class Context {
- public static final int RECEIVER_EXPORTED = 0x2;
- public static final int RECEIVER_NOT_EXPORTED = 0x4;
- @Nullable
- public abstract Intent registerReceiver(@Nullable BroadcastReceiver receiver,
- IntentFilter filter,
- @RegisterReceiverFlags int flags);
- }
- """
- ).indented()
-
- private val intentStub: TestFile = java(
- """
- package android.content;
- public class Intent {
- public static final String ACTION_BATTERY_CHANGED =
- "android.intent.action.BATTERY_CHANGED";
- public static final String ACTION_BATTERY_LOW = "android.intent.action.BATTERY_LOW";
- public static final String ACTION_BATTERY_OKAY =
- "android.intent.action.BATTERY_OKAY";
- }
- """
- ).indented()
-
- private val intentFilterStub: TestFile = java(
- """
- package android.content;
- public class IntentFilter {
- public IntentFilter() {
- // Stub
- }
- public IntentFilter(String action) {
- // Stub
- }
- public IntentFilter(String action, String dataType) {
- // Stub
- }
- public static IntentFilter create(String action, String dataType) {
- return null;
- }
- public final void addAction(String action) {
- // Stub
- }
- }
- """
- ).indented()
-
- private val stubs = arrayOf(broadcastReceiverStub, contextStub, intentStub, intentFilterStub)
-}
diff --git a/tools/locked_region_code_injection/Android.bp b/tools/locked_region_code_injection/Android.bp
index a0cc446..954b816 100644
--- a/tools/locked_region_code_injection/Android.bp
+++ b/tools/locked_region_code_injection/Android.bp
@@ -19,3 +19,20 @@
"ow2-asm-tree",
],
}
+
+java_library_host {
+ name: "lockedregioncodeinjection_input",
+ manifest: "test/manifest.txt",
+ srcs: ["test/*/*.java"],
+ static_libs: [
+ "guava",
+ "ow2-asm",
+ "ow2-asm-analysis",
+ "ow2-asm-commons",
+ "ow2-asm-tree",
+ "hamcrest-library",
+ "hamcrest",
+ "platform-test-annotations",
+ "junit",
+ ],
+}
diff --git a/tools/locked_region_code_injection/OWNERS b/tools/locked_region_code_injection/OWNERS
new file mode 100644
index 0000000..bd43f17
--- /dev/null
+++ b/tools/locked_region_code_injection/OWNERS
@@ -0,0 +1,4 @@
+# Everyone in frameworks/base is included by default
+shayba@google.com
+shombert@google.com
+timmurray@google.com
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java
index 81a0773..2067bb4 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockFindingClassVisitor.java
@@ -13,37 +13,51 @@
*/
package lockedregioncodeinjection;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.LinkedList;
-import java.util.List;
+import static com.google.common.base.Preconditions.checkElementIndex;
+import static com.google.common.base.Preconditions.checkNotNull;
+import static com.google.common.base.Preconditions.checkState;
+
import org.objectweb.asm.ClassVisitor;
import org.objectweb.asm.MethodVisitor;
import org.objectweb.asm.Opcodes;
import org.objectweb.asm.commons.TryCatchBlockSorter;
import org.objectweb.asm.tree.AbstractInsnNode;
import org.objectweb.asm.tree.InsnList;
+import org.objectweb.asm.tree.InsnNode;
import org.objectweb.asm.tree.LabelNode;
+import org.objectweb.asm.tree.LineNumberNode;
import org.objectweb.asm.tree.MethodInsnNode;
import org.objectweb.asm.tree.MethodNode;
+import org.objectweb.asm.tree.TypeInsnNode;
import org.objectweb.asm.tree.TryCatchBlockNode;
import org.objectweb.asm.tree.analysis.Analyzer;
import org.objectweb.asm.tree.analysis.AnalyzerException;
import org.objectweb.asm.tree.analysis.BasicValue;
import org.objectweb.asm.tree.analysis.Frame;
-import static com.google.common.base.Preconditions.checkElementIndex;
-import static com.google.common.base.Preconditions.checkNotNull;
-import static com.google.common.base.Preconditions.checkState;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.LinkedList;
+import java.util.List;
/**
- * This visitor does two things:
+ * This visitor operates on two kinds of targets. For a legacy target, it does the following:
*
- * 1. Finds all the MONITOR_ENTER / MONITOR_EXIT in the byte code and insert the corresponding pre
+ * 1. Finds all the MONITOR_ENTER / MONITOR_EXIT in the byte code and inserts the corresponding pre
* and post methods calls should it matches one of the given target type in the Configuration.
*
* 2. Find all methods that are synchronized and insert pre method calls in the beginning and post
* method calls just before all return instructions.
+ *
+ * For a scoped target, it does the following:
+ *
+ * 1. Finds all the MONITOR_ENTER instructions in the byte code. If the target of the opcode is
+ * named in a --scope switch, then the pre method is invoked ON THE TARGET immediately after
+ * MONITOR_ENTER opcode completes.
+ *
+ * 2. Finds all the MONITOR_EXIT instructions in the byte code. If the target of the opcode is
+ * named in a --scope switch, then the post method is invoked ON THE TARGET immediately before
+ * MONITOR_EXIT opcode completes.
*/
class LockFindingClassVisitor extends ClassVisitor {
private String className = null;
@@ -73,12 +87,16 @@
class LockFindingMethodVisitor extends MethodVisitor {
private String owner;
private MethodVisitor chain;
+ private final String className;
+ private final String methodName;
public LockFindingMethodVisitor(String owner, MethodNode mn, MethodVisitor chain) {
super(Utils.ASM_VERSION, mn);
assert owner != null;
this.owner = owner;
this.chain = chain;
+ className = owner;
+ methodName = mn.name;
}
@SuppressWarnings("unchecked")
@@ -93,6 +111,12 @@
for (LockTarget t : targets) {
if (t.getTargetDesc().equals("L" + owner + ";")) {
ownerMonitor = t;
+ if (ownerMonitor.getScoped()) {
+ final String emsg = String.format(
+ "scoped targets do not support synchronized methods in %s.%s()",
+ className, methodName);
+ throw new RuntimeException(emsg);
+ }
}
}
}
@@ -118,9 +142,11 @@
AbstractInsnNode s = instructions.getFirst();
MethodInsnNode call = new MethodInsnNode(Opcodes.INVOKESTATIC,
ownerMonitor.getPreOwner(), ownerMonitor.getPreMethod(), "()V", false);
- insertMethodCallBefore(mn, frameMap, handlersMap, s, 0, call);
+ insertMethodCallBeforeSync(mn, frameMap, handlersMap, s, 0, call);
}
+ boolean anyDup = false;
+
for (int i = 0; i < instructions.size(); i++) {
AbstractInsnNode s = instructions.get(i);
@@ -131,9 +157,15 @@
LockTargetState state = (LockTargetState) operand;
for (int j = 0; j < state.getTargets().size(); j++) {
LockTarget target = state.getTargets().get(j);
- MethodInsnNode call = new MethodInsnNode(Opcodes.INVOKESTATIC,
- target.getPreOwner(), target.getPreMethod(), "()V", false);
- insertMethodCallAfter(mn, frameMap, handlersMap, s, i, call);
+ MethodInsnNode call = methodCall(target, true);
+ if (target.getScoped()) {
+ TypeInsnNode cast = typeCast(target);
+ i += insertInvokeAcquire(mn, frameMap, handlersMap, s, i,
+ call, cast);
+ anyDup = true;
+ } else {
+ i += insertMethodCallBefore(mn, frameMap, handlersMap, s, i, call);
+ }
}
}
}
@@ -144,8 +176,9 @@
if (operand instanceof LockTargetState) {
LockTargetState state = (LockTargetState) operand;
for (int j = 0; j < state.getTargets().size(); j++) {
- // The instruction after a monitor_exit should be a label for the end of the implicit
- // catch block that surrounds the synchronized block to call monitor_exit when an exception
+ // The instruction after a monitor_exit should be a label for
+ // the end of the implicit catch block that surrounds the
+ // synchronized block to call monitor_exit when an exception
// occurs.
checkState(instructions.get(i + 1).getType() == AbstractInsnNode.LABEL,
"Expected to find label after monitor exit");
@@ -161,9 +194,16 @@
"Expected label to be the end of monitor exit's try block");
LockTarget target = state.getTargets().get(j);
- MethodInsnNode call = new MethodInsnNode(Opcodes.INVOKESTATIC,
- target.getPostOwner(), target.getPostMethod(), "()V", false);
- insertMethodCallAfter(mn, frameMap, handlersMap, label, labelIndex, call);
+ MethodInsnNode call = methodCall(target, false);
+ if (target.getScoped()) {
+ TypeInsnNode cast = typeCast(target);
+ i += insertInvokeRelease(mn, frameMap, handlersMap, s, i,
+ call, cast);
+ anyDup = true;
+ } else {
+ insertMethodCallAfter(mn, frameMap, handlersMap, label,
+ labelIndex, call);
+ }
}
}
}
@@ -174,16 +214,116 @@
MethodInsnNode call =
new MethodInsnNode(Opcodes.INVOKESTATIC, ownerMonitor.getPostOwner(),
ownerMonitor.getPostMethod(), "()V", false);
- insertMethodCallBefore(mn, frameMap, handlersMap, s, i, call);
+ insertMethodCallBeforeSync(mn, frameMap, handlersMap, s, i, call);
i++; // Skip ahead. Otherwise, we will revisit this instruction again.
}
}
+
+ if (anyDup) {
+ mn.maxStack++;
+ }
+
super.visitEnd();
mn.accept(chain);
}
+
+ // Insert a call to a monitor pre handler. The node and the index identify the
+ // monitorenter call itself. Insert DUP immediately prior to the MONITORENTER.
+ // Insert the typecast and call (in that order) after the MONITORENTER.
+ public int insertInvokeAcquire(MethodNode mn, List<Frame> frameMap,
+ List<List<TryCatchBlockNode>> handlersMap, AbstractInsnNode node, int index,
+ MethodInsnNode call, TypeInsnNode cast) {
+ InsnList instructions = mn.instructions;
+
+ // Insert a DUP right before MONITORENTER, to capture the object being locked.
+ // Note that the object will be typed as java.lang.Object.
+ instructions.insertBefore(node, new InsnNode(Opcodes.DUP));
+ frameMap.add(index, frameMap.get(index));
+ handlersMap.add(index, handlersMap.get(index));
+
+ // Insert the call right after the MONITORENTER. These entries are pushed after
+ // MONITORENTER so they are inserted in reverse order. MONITORENTER should be
+ // the target of a try/catch block, which means it must be immediately
+ // followed by a label (which is part of the try/catch block definition).
+ // Move forward past the label so the invocation in inside the proper block.
+ // Throw an error if the next instruction is not a label.
+ node = node.getNext();
+ if (!(node instanceof LabelNode)) {
+ throw new RuntimeException(String.format("invalid bytecode sequence in %s.%s()",
+ className, methodName));
+ }
+ node = node.getNext();
+ index = instructions.indexOf(node);
+
+ instructions.insertBefore(node, cast);
+ frameMap.add(index, frameMap.get(index));
+ handlersMap.add(index, handlersMap.get(index));
+
+ instructions.insertBefore(node, call);
+ frameMap.add(index, frameMap.get(index));
+ handlersMap.add(index, handlersMap.get(index));
+
+ return 3;
+ }
+
+ // Insert instructions completely before the current opcode. This is slightly
+ // different from insertMethodCallBefore(), which inserts the call before MONITOREXIT
+ // but inserts the start and end labels after MONITOREXIT.
+ public int insertInvokeRelease(MethodNode mn, List<Frame> frameMap,
+ List<List<TryCatchBlockNode>> handlersMap, AbstractInsnNode node, int index,
+ MethodInsnNode call, TypeInsnNode cast) {
+ InsnList instructions = mn.instructions;
+
+ instructions.insertBefore(node, new InsnNode(Opcodes.DUP));
+ frameMap.add(index, frameMap.get(index));
+ handlersMap.add(index, handlersMap.get(index));
+
+ instructions.insertBefore(node, cast);
+ frameMap.add(index, frameMap.get(index));
+ handlersMap.add(index, handlersMap.get(index));
+
+ instructions.insertBefore(node, call);
+ frameMap.add(index, frameMap.get(index));
+ handlersMap.add(index, handlersMap.get(index));
+
+ return 3;
+ }
}
- public static void insertMethodCallBefore(MethodNode mn, List<Frame> frameMap,
+ public static MethodInsnNode methodCall(LockTarget target, boolean pre) {
+ String spec = "()V";
+ if (!target.getScoped()) {
+ if (pre) {
+ return new MethodInsnNode(
+ Opcodes.INVOKESTATIC, target.getPreOwner(), target.getPreMethod(), spec);
+ } else {
+ return new MethodInsnNode(
+ Opcodes.INVOKESTATIC, target.getPostOwner(), target.getPostMethod(), spec);
+ }
+ } else {
+ if (pre) {
+ return new MethodInsnNode(
+ Opcodes.INVOKEVIRTUAL, target.getPreOwner(), target.getPreMethod(), spec);
+ } else {
+ return new MethodInsnNode(
+ Opcodes.INVOKEVIRTUAL, target.getPostOwner(), target.getPostMethod(), spec);
+ }
+ }
+ }
+
+ public static TypeInsnNode typeCast(LockTarget target) {
+ if (!target.getScoped()) {
+ return null;
+ } else {
+ // preOwner and postOwner return the same string for scoped targets.
+ return new TypeInsnNode(Opcodes.CHECKCAST, target.getPreOwner());
+ }
+ }
+
+ /**
+ * Insert a method call before the beginning or end of a synchronized method.
+ */
+ public static void insertMethodCallBeforeSync(MethodNode mn, List<Frame> frameMap,
List<List<TryCatchBlockNode>> handlersMap, AbstractInsnNode node, int index,
MethodInsnNode call) {
List<TryCatchBlockNode> handlers = handlersMap.get(index);
@@ -226,6 +366,22 @@
updateCatchHandler(mn, handlers, start, end, handlersMap);
}
+ // Insert instructions completely before the current opcode. This is slightly different from
+ // insertMethodCallBeforeSync(), which inserts the call before MONITOREXIT but inserts the
+ // start and end labels after MONITOREXIT.
+ public int insertMethodCallBefore(MethodNode mn, List<Frame> frameMap,
+ List<List<TryCatchBlockNode>> handlersMap, AbstractInsnNode node, int index,
+ MethodInsnNode call) {
+ InsnList instructions = mn.instructions;
+
+ instructions.insertBefore(node, call);
+ frameMap.add(index, frameMap.get(index));
+ handlersMap.add(index, handlersMap.get(index));
+
+ return 1;
+ }
+
+
@SuppressWarnings("unchecked")
public static void updateCatchHandler(MethodNode mn, List<TryCatchBlockNode> handlers,
LabelNode start, LabelNode end, List<List<TryCatchBlockNode>> handlersMap) {
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockTarget.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockTarget.java
index c5e59e3..5f62403 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockTarget.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockTarget.java
@@ -21,14 +21,28 @@
public class LockTarget {
public static final LockTarget NO_TARGET = new LockTarget("", null, null);
+ // The lock which must be instrumented, in Java internal form (L<path>;).
private final String targetDesc;
+ // The methods to be called when the lock is taken (released). For non-scoped locks,
+ // these are fully qualified static methods. For scoped locks, these are the
+ // unqualified names of a member method of the target lock.
private final String pre;
private final String post;
+ // If true, the pre and post methods are virtual on the target class. The pre and post methods
+ // are both called while the lock is held. If this field is false then the pre and post methods
+ // take no parameters and the post method is called after the lock is released. This is legacy
+ // behavior.
+ private final boolean scoped;
- public LockTarget(String targetDesc, String pre, String post) {
+ public LockTarget(String targetDesc, String pre, String post, boolean scoped) {
this.targetDesc = targetDesc;
this.pre = pre;
this.post = post;
+ this.scoped = scoped;
+ }
+
+ public LockTarget(String targetDesc, String pre, String post) {
+ this(targetDesc, pre, post, false);
}
public String getTargetDesc() {
@@ -40,7 +54,11 @@
}
public String getPreOwner() {
- return pre.substring(0, pre.lastIndexOf('.'));
+ if (scoped) {
+ return targetDesc.substring(1, targetDesc.length() - 1);
+ } else {
+ return pre.substring(0, pre.lastIndexOf('.'));
+ }
}
public String getPreMethod() {
@@ -52,10 +70,23 @@
}
public String getPostOwner() {
- return post.substring(0, post.lastIndexOf('.'));
+ if (scoped) {
+ return targetDesc.substring(1, targetDesc.length() - 1);
+ } else {
+ return post.substring(0, post.lastIndexOf('.'));
+ }
}
public String getPostMethod() {
return post.substring(post.lastIndexOf('.') + 1);
}
+
+ public boolean getScoped() {
+ return scoped;
+ }
+
+ @Override
+ public String toString() {
+ return targetDesc + ":" + pre + ":" + post;
+ }
}
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockTargetState.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockTargetState.java
index 99d8418..5df0160 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockTargetState.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/LockTargetState.java
@@ -13,10 +13,11 @@
*/
package lockedregioncodeinjection;
-import java.util.List;
import org.objectweb.asm.Type;
import org.objectweb.asm.tree.analysis.BasicValue;
+import java.util.List;
+
public class LockTargetState extends BasicValue {
private final List<LockTarget> lockTargets;
@@ -31,4 +32,10 @@
public List<LockTarget> getTargets() {
return lockTargets;
}
+
+ @Override
+ public String toString() {
+ return "LockTargetState(" + getType().getDescriptor()
+ + ", " + lockTargets.size() + ")";
+ }
}
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java
index 828cce7..d22ea23 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Main.java
@@ -21,7 +21,7 @@
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
-import java.util.Collections;
+import java.util.ArrayList;
import java.util.Enumeration;
import java.util.List;
import java.util.zip.ZipEntry;
@@ -36,6 +36,7 @@
String legacyTargets = null;
String legacyPreMethods = null;
String legacyPostMethods = null;
+ List<LockTarget> targets = new ArrayList<>();
for (int i = 0; i < args.length; i++) {
if ("-i".equals(args[i].trim())) {
i++;
@@ -52,23 +53,25 @@
} else if ("--post".equals(args[i].trim())) {
i++;
legacyPostMethods = args[i].trim();
+ } else if ("--scoped".equals(args[i].trim())) {
+ i++;
+ targets.add(Utils.getScopedTarget(args[i].trim()));
}
-
}
- // TODO(acleung): Better help message than asserts.
- assert inJar != null;
- assert outJar != null;
+ if (inJar == null) {
+ throw new RuntimeException("missing input jar path");
+ }
+ if (outJar == null) {
+ throw new RuntimeException("missing output jar path");
+ }
assert legacyTargets == null || (legacyPreMethods != null && legacyPostMethods != null);
ZipFile zipSrc = new ZipFile(inJar);
ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(outJar));
- List<LockTarget> targets = null;
if (legacyTargets != null) {
- targets = Utils.getTargetsFromLegacyJackConfig(legacyTargets, legacyPreMethods,
- legacyPostMethods);
- } else {
- targets = Collections.emptyList();
+ targets.addAll(Utils.getTargetsFromLegacyJackConfig(legacyTargets, legacyPreMethods,
+ legacyPostMethods));
}
Enumeration<? extends ZipEntry> srcEntries = zipSrc.entries();
diff --git a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Utils.java b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Utils.java
index b44e8b4..bfef106 100644
--- a/tools/locked_region_code_injection/src/lockedregioncodeinjection/Utils.java
+++ b/tools/locked_region_code_injection/src/lockedregioncodeinjection/Utils.java
@@ -44,4 +44,27 @@
return config;
}
+
+ /**
+ * Returns a single {@link LockTarget} from a string. The target is a comma-separated list of
+ * the target class, the request method, the release method, and a boolean which is true if this
+ * is a scoped target and false if this is a legacy target. The boolean is optional and
+ * defaults to true.
+ */
+ public static LockTarget getScopedTarget(String arg) {
+ String[] c = arg.split(",");
+ if (c.length == 3) {
+ return new LockTarget(c[0], c[1], c[2], true);
+ } else if (c.length == 4) {
+ if (c[3].equals("true")) {
+ return new LockTarget(c[0], c[1], c[2], true);
+ } else if (c[3].equals("false")) {
+ return new LockTarget(c[0], c[1], c[2], false);
+ } else {
+ System.err.println("illegal target parameter \"" + c[3] + "\"");
+ }
+ }
+ // Fall through
+ throw new RuntimeException("invalid scoped target format");
+ }
}
diff --git a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java
index 31fa0bf..28f00b9 100644
--- a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java
+++ b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestMain.java
@@ -17,7 +17,10 @@
import org.junit.Test;
/**
- * To run the unit tests:
+ * To run the unit tests, first build the two necessary artifacts. Do this explicitly as they are
+ * not generally retained by a normal "build all". After lunching a target:
+ * m lockedregioncodeinjection
+ * m lockedregioncodeinjection_input
*
* <pre>
* <code>
@@ -29,31 +32,25 @@
* mkdir -p out
* rm -fr out/*
*
- * # Make booster
- * javac -cp lib/asm-7.0_BETA.jar:lib/asm-commons-7.0_BETA.jar:lib/asm-tree-7.0_BETA.jar:lib/asm-analysis-7.0_BETA.jar:lib/guava-21.0.jar src/*/*.java -d out/
- * pushd out
- * jar cfe lockedregioncodeinjection.jar lockedregioncodeinjection.Main */*.class
- * popd
- *
- * # Make unit tests.
- * javac -cp lib/junit-4.12.jar test/*/*.java -d out/
- *
- * pushd out
- * jar cfe test_input.jar lockedregioncodeinjection.Test */*.class
- * popd
+ * # Paths to the build artifacts. These assume linux-x86; YMMV.
+ * ROOT=$TOP/out/host/linux-x86
+ * EXE=$ROOT/bin/lockedregioncodeinjection
+ * INPUT=$ROOT/frameworkd/lockedregioncodeinjection_input.jar
*
* # Run tool on unit tests.
- * java -ea -cp lib/asm-7.0_BETA.jar:lib/asm-commons-7.0_BETA.jar:lib/asm-tree-7.0_BETA.jar:lib/asm-analysis-7.0_BETA.jar:lib/guava-21.0.jar:out/lockedregioncodeinjection.jar \
- * lockedregioncodeinjection.Main \
- * -i out/test_input.jar -o out/test_output.jar \
+ * $EXE -i $INPUT -o out/test_output.jar \
* --targets 'Llockedregioncodeinjection/TestTarget;' \
* --pre 'lockedregioncodeinjection/TestTarget.boost' \
* --post 'lockedregioncodeinjection/TestTarget.unboost'
*
* # Run unit tests.
- * java -ea -cp lib/hamcrest-core-1.3.jar:lib/junit-4.12.jar:out/test_output.jar \
+ * java -ea -cp out/test_output.jar \
* org.junit.runner.JUnitCore lockedregioncodeinjection.TestMain
* </code>
+ * OR
+ * <code>
+ * bash test/unit-test.sh
+ * </code>
* </pre>
*/
public class TestMain {
@@ -64,7 +61,9 @@
Assert.assertEquals(TestTarget.boostCount, 0);
Assert.assertEquals(TestTarget.unboostCount, 0);
- Assert.assertEquals(TestTarget.unboostCount, 0);
+ Assert.assertEquals(TestTarget.invokeCount, 0);
+ Assert.assertEquals(TestTarget.boostCountLocked, 0);
+ Assert.assertEquals(TestTarget.unboostCountLocked, 0);
synchronized (t) {
Assert.assertEquals(TestTarget.boostCount, 1);
@@ -75,6 +74,8 @@
Assert.assertEquals(TestTarget.boostCount, 1);
Assert.assertEquals(TestTarget.unboostCount, 1);
Assert.assertEquals(TestTarget.invokeCount, 1);
+ Assert.assertEquals(TestTarget.boostCountLocked, 0);
+ Assert.assertEquals(TestTarget.unboostCountLocked, 0);
}
@Test
@@ -84,12 +85,16 @@
Assert.assertEquals(TestTarget.boostCount, 0);
Assert.assertEquals(TestTarget.unboostCount, 0);
+ Assert.assertEquals(TestTarget.boostCountLocked, 0);
+ Assert.assertEquals(TestTarget.unboostCountLocked, 0);
t.synchronizedCall();
Assert.assertEquals(TestTarget.boostCount, 1);
Assert.assertEquals(TestTarget.unboostCount, 1);
Assert.assertEquals(TestTarget.invokeCount, 1);
+ Assert.assertEquals(TestTarget.boostCountLocked, 0);
+ Assert.assertEquals(TestTarget.unboostCountLocked, 0);
}
@Test
@@ -99,12 +104,16 @@
Assert.assertEquals(TestTarget.boostCount, 0);
Assert.assertEquals(TestTarget.unboostCount, 0);
+ Assert.assertEquals(TestTarget.boostCountLocked, 0);
+ Assert.assertEquals(TestTarget.unboostCountLocked, 0);
t.synchronizedCallReturnInt();
Assert.assertEquals(TestTarget.boostCount, 1);
Assert.assertEquals(TestTarget.unboostCount, 1);
Assert.assertEquals(TestTarget.invokeCount, 1);
+ Assert.assertEquals(TestTarget.boostCountLocked, 0);
+ Assert.assertEquals(TestTarget.unboostCountLocked, 0);
}
@Test
@@ -253,4 +262,125 @@
Assert.assertEquals(TestTarget.invokeCount, 1);
}
+ @Test
+ public void testScopedTarget() {
+ TestScopedTarget target = new TestScopedTarget();
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+
+ synchronized (target.scopedLock()) {
+ Assert.assertEquals(1, target.scopedLock().mLevel);
+ }
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+
+ synchronized (target.scopedLock()) {
+ synchronized (target.scopedLock()) {
+ Assert.assertEquals(2, target.scopedLock().mLevel);
+ }
+ }
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+ }
+
+ @Test
+ public void testScopedExceptionHandling() {
+ TestScopedTarget target = new TestScopedTarget();
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+
+ boolean handled;
+
+ // 1: an exception inside the block properly releases the lock.
+ handled = false;
+ try {
+ synchronized (target.scopedLock()) {
+ Assert.assertEquals(true, Thread.holdsLock(target.scopedLock()));
+ Assert.assertEquals(1, target.scopedLock().mLevel);
+ throw new RuntimeException();
+ }
+ } catch (RuntimeException e) {
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+ handled = true;
+ }
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+ Assert.assertEquals(true, handled);
+ // Just verify that the lock can still be taken
+ Assert.assertEquals(false, Thread.holdsLock(target.scopedLock()));
+
+ // 2: An exception inside the monitor enter function
+ handled = false;
+ target.throwOnEnter(true);
+ try {
+ synchronized (target.scopedLock()) {
+ // The exception was thrown inside monitorEnter(), so the code should
+ // never reach this point.
+ Assert.assertEquals(0, 1);
+ }
+ } catch (RuntimeException e) {
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+ handled = true;
+ }
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+ Assert.assertEquals(true, handled);
+ // Just verify that the lock can still be taken
+ Assert.assertEquals(false, Thread.holdsLock(target.scopedLock()));
+
+ // 3: An exception inside the monitor exit function
+ handled = false;
+ target.throwOnEnter(true);
+ try {
+ synchronized (target.scopedLock()) {
+ Assert.assertEquals(true, Thread.holdsLock(target.scopedLock()));
+ Assert.assertEquals(1, target.scopedLock().mLevel);
+ }
+ } catch (RuntimeException e) {
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+ handled = true;
+ }
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+ Assert.assertEquals(true, handled);
+ // Just verify that the lock can still be taken
+ Assert.assertEquals(false, Thread.holdsLock(target.scopedLock()));
+ }
+
+ // Provide an in-class type conversion for the scoped target.
+ private Object untypedLock(TestScopedTarget target) {
+ return target.scopedLock();
+ }
+
+ @Test
+ public void testScopedLockTyping() {
+ TestScopedTarget target = new TestScopedTarget();
+ Assert.assertEquals(target.scopedLock().mLevel, 0);
+
+ // Scoped lock injection works on the static type of an object. In general, it is
+ // a very bad idea to do type conversion on scoped locks, but the general rule is
+ // that conversions within a single method are recognized by the lock injection
+ // tool and injection occurs. Conversions outside a single method are not
+ // recognized and injection does not occur.
+
+ // 1. Conversion occurs outside the class. The visible type of the lock is Object
+ // in this block, so no injection takes place on 'untypedLock', even though the
+ // dynamic type is TestScopedLock.
+ synchronized (target.untypedLock()) {
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+ Assert.assertEquals(true, target.untypedLock() instanceof TestScopedLock);
+ Assert.assertEquals(true, Thread.holdsLock(target.scopedLock()));
+ }
+
+ // 2. Conversion occurs inside the class but in another method. The visible type
+ // of the lock is Object in this block, so no injection takes place on
+ // 'untypedLock', even though the dynamic type is TestScopedLock.
+ synchronized (untypedLock(target)) {
+ Assert.assertEquals(0, target.scopedLock().mLevel);
+ Assert.assertEquals(true, target.untypedLock() instanceof TestScopedLock);
+ Assert.assertEquals(true, Thread.holdsLock(target.scopedLock()));
+ }
+
+ // 3. Conversion occurs inside the method. The compiler can determine the type of
+ // the lock within a single function, so injection does take place here.
+ Object untypedLock = target.scopedLock();
+ synchronized (untypedLock) {
+ Assert.assertEquals(1, target.scopedLock().mLevel);
+ Assert.assertEquals(true, untypedLock instanceof TestScopedLock);
+ Assert.assertEquals(true, Thread.holdsLock(target.scopedLock()));
+ }
+ }
}
diff --git a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestScopedLock.java b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestScopedLock.java
new file mode 100644
index 0000000..7441d2b
--- /dev/null
+++ b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestScopedLock.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package lockedregioncodeinjection;
+
+public class TestScopedLock {
+ public int mEntered = 0;
+ public int mExited = 0;
+
+ public int mLevel = 0;
+ private final TestScopedTarget mTarget;
+
+ TestScopedLock(TestScopedTarget target) {
+ mTarget = target;
+ }
+
+ void monitorEnter() {
+ mLevel++;
+ mEntered++;
+ mTarget.enter(mLevel);
+ }
+
+ void monitorExit() {
+ mLevel--;
+ mExited++;
+ mTarget.exit(mLevel);
+ }
+}
diff --git a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestScopedTarget.java b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestScopedTarget.java
new file mode 100644
index 0000000..c80975e
--- /dev/null
+++ b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestScopedTarget.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright (C) 2017 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+ * in compliance with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software distributed under the License
+ * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+ * or implied. See the License for the specific language governing permissions and limitations under
+ * the License.
+ */
+package lockedregioncodeinjection;
+
+public class TestScopedTarget {
+
+ public final TestScopedLock mLock;;
+
+ private boolean mNextEnterThrows = false;
+ private boolean mNextExitThrows = false;
+
+ TestScopedTarget() {
+ mLock = new TestScopedLock(this);
+ }
+
+ TestScopedLock scopedLock() {
+ return mLock;
+ }
+
+ Object untypedLock() {
+ return mLock;
+ }
+
+ void enter(int level) {
+ if (mNextEnterThrows) {
+ mNextEnterThrows = false;
+ throw new RuntimeException();
+ }
+ }
+
+ void exit(int level) {
+ if (mNextExitThrows) {
+ mNextExitThrows = false;
+ throw new RuntimeException();
+ }
+ }
+
+ void throwOnEnter(boolean b) {
+ mNextEnterThrows = b;
+ }
+
+ void throwOnExit(boolean b) {
+ mNextExitThrows = b;
+ }
+}
diff --git a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestTarget.java b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestTarget.java
index d1c8f34..e3ba6a7 100644
--- a/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestTarget.java
+++ b/tools/locked_region_code_injection/test/lockedregioncodeinjection/TestTarget.java
@@ -19,8 +19,17 @@
public static int invokeCount = 0;
public static boolean nextUnboostThrows = false;
+ // If this is not null, then this is the lock under test. The lock must not be held when boost()
+ // or unboost() are called.
+ public static Object mLock = null;
+ public static int boostCountLocked = 0;
+ public static int unboostCountLocked = 0;
+
public static void boost() {
boostCount++;
+ if (mLock != null && Thread.currentThread().holdsLock(mLock)) {
+ boostCountLocked++;
+ }
}
public static void unboost() {
@@ -29,6 +38,9 @@
throw new RuntimeException();
}
unboostCount++;
+ if (mLock != null && Thread.currentThread().holdsLock(mLock)) {
+ unboostCountLocked++;
+ }
}
public static void invoke() {
diff --git a/tools/locked_region_code_injection/test/manifest.txt b/tools/locked_region_code_injection/test/manifest.txt
new file mode 100644
index 0000000..2314c18
--- /dev/null
+++ b/tools/locked_region_code_injection/test/manifest.txt
@@ -0,0 +1 @@
+Main-Class: org.junit.runner.JUnitCore
diff --git a/tools/locked_region_code_injection/test/unit-test.sh b/tools/locked_region_code_injection/test/unit-test.sh
new file mode 100755
index 0000000..9fa6f39
--- /dev/null
+++ b/tools/locked_region_code_injection/test/unit-test.sh
@@ -0,0 +1,98 @@
+#! /bin/bash
+#
+
+# Copyright (C) 2023 The Android Open Source Project
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
+# in compliance with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software distributed under the License
+# is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
+# or implied. See the License for the specific language governing permissions and limitations under
+# the License.
+
+# This script runs the tests for the lockedregioninjectioncode. See
+# TestMain.java for the invocation. The script expects that a full build has
+# already been done and artifacts are in $TOP/out.
+
+# Compute the default top of the workspace. The following code copies the
+# strategy of croot. (croot cannot be usd directly because it is a function and
+# functions are not carried over into subshells.) This gives the correct answer
+# if run from inside a workspace. If run from outside a workspace, supply TOP
+# on the command line.
+TOPFILE=build/make/core/envsetup.mk
+TOP=$(dirname $(realpath $0))
+while [[ ! $TOP = / && ! -f $TOP/$TOPFILE ]]; do
+ TOP=$(dirname $TOP)
+done
+# TOP is "/" if this script is located outside a workspace.
+
+# If the user supplied a top directory, use it instead
+if [[ -n $1 ]]; then
+ TOP=$1
+ shift
+fi
+if [[ -z $TOP || $TOP = / ]]; then
+ echo "usage: $0 <workspace-root>"
+ exit 1
+elif [[ ! -d $TOP ]]; then
+ echo "$TOP is not a directory"
+ exit 1
+elif [[ ! -d $TOP/prebuilts/misc/common ]]; then
+ echo "$TOP does not look like w workspace"
+ exit 1
+fi
+echo "Using workspace $TOP"
+
+# Pick up the current java compiler. The lunch target is not very important,
+# since most, if not all, will use the same host binaries.
+pushd $TOP > /dev/null
+. build/envsetup.sh > /dev/null 2>&1
+lunch redfin-userdebug > /dev/null 2>&1
+popd > /dev/null
+
+# Bail on any error
+set -o pipefail
+trap 'exit 1' ERR
+
+# Create the two sources
+pushd $TOP > /dev/null
+m lockedregioncodeinjection
+m lockedregioncodeinjection_input
+popd > /dev/null
+
+# Create a temporary directory outside of the workspace.
+OUT=$TOP/out/host/test/lockedregioncodeinjection
+echo
+
+# Clean the directory
+if [[ -d $OUT ]]; then rm -r $OUT; fi
+mkdir -p $OUT
+
+ROOT=$TOP/out/host/linux-x86
+EXE=$ROOT/bin/lockedregioncodeinjection
+INP=$ROOT/framework/lockedregioncodeinjection_input.jar
+
+# Run tool on unit tests.
+$EXE \
+ -i $INP -o $OUT/test_output.jar \
+ --targets 'Llockedregioncodeinjection/TestTarget;' \
+ --pre 'lockedregioncodeinjection/TestTarget.boost' \
+ --post 'lockedregioncodeinjection/TestTarget.unboost' \
+ --scoped 'Llockedregioncodeinjection/TestScopedLock;,monitorEnter,monitorExit'
+
+# Run unit tests.
+java -ea -cp $OUT/test_output.jar \
+ org.junit.runner.JUnitCore lockedregioncodeinjection.TestMain
+
+# Extract the class files and decompile them for possible post-analysis.
+pushd $OUT > /dev/null
+jar -x --file test_output.jar lockedregioncodeinjection
+for class in lockedregioncodeinjection/*.class; do
+ javap -c -v $class > ${class%.class}.asm
+done
+popd > /dev/null
+
+echo "artifacts are in $OUT"
diff --git a/wifi/TEST_MAPPING b/wifi/TEST_MAPPING
index 94e4f4d..14f5af3 100644
--- a/wifi/TEST_MAPPING
+++ b/wifi/TEST_MAPPING
@@ -3,5 +3,15 @@
{
"name": "FrameworksWifiNonUpdatableApiTests"
}
+ ],
+ "presubmit-large": [
+ {
+ "name": "CtsWifiTestCases",
+ "options": [
+ {
+ "exclude-annotation": "android.net.wifi.cts.VirtualDeviceNotSupported"
+ }
+ ]
+ }
]
}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/HotspotNetwork.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/HotspotNetwork.java
index 9bfeb63..fe397d9 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/HotspotNetwork.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/HotspotNetwork.java
@@ -23,6 +23,7 @@
import android.annotation.Nullable;
import android.annotation.SystemApi;
import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.util.ArraySet;
@@ -86,6 +87,7 @@
@Nullable
@SecurityType
private final ArraySet<Integer> mHotspotSecurityTypes;
+ private final Bundle mExtras;
/**
* Builder class for {@link HotspotNetwork}.
@@ -102,8 +104,8 @@
private String mHotspotBssid;
@Nullable
@SecurityType
- private final ArraySet<Integer> mHotspotSecurityTypes =
- new ArraySet<>();
+ private final ArraySet<Integer> mHotspotSecurityTypes = new ArraySet<>();
+ private Bundle mExtras = Bundle.EMPTY;
/**
* Set the remote device ID.
@@ -190,6 +192,17 @@
}
/**
+ * Sets the extras bundle
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
* Builds the {@link HotspotNetwork} object.
*
* @return Returns the built {@link HotspotNetwork} object.
@@ -203,7 +216,8 @@
mNetworkName,
mHotspotSsid,
mHotspotBssid,
- mHotspotSecurityTypes);
+ mHotspotSecurityTypes,
+ mExtras);
}
}
@@ -231,7 +245,8 @@
@NonNull String networkName,
@Nullable String hotspotSsid,
@Nullable String hotspotBssid,
- @Nullable @SecurityType ArraySet<Integer> hotspotSecurityTypes) {
+ @Nullable @SecurityType ArraySet<Integer> hotspotSecurityTypes,
+ @NonNull Bundle extras) {
validate(deviceId,
networkType,
networkName,
@@ -243,6 +258,7 @@
mHotspotSsid = hotspotSsid;
mHotspotBssid = hotspotBssid;
mHotspotSecurityTypes = new ArraySet<>(hotspotSecurityTypes);
+ mExtras = extras;
}
/**
@@ -315,6 +331,16 @@
return mHotspotSecurityTypes;
}
+ /**
+ * Gets the extras Bundle.
+ *
+ * @return Returns a Bundle object.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
@Override
public boolean equals(Object obj) {
if (!(obj instanceof HotspotNetwork)) return false;
@@ -348,6 +374,7 @@
dest.writeString(mHotspotSsid);
dest.writeString(mHotspotBssid);
dest.writeArraySet(mHotspotSecurityTypes);
+ dest.writeBundle(mExtras);
}
/**
@@ -359,7 +386,7 @@
public static HotspotNetwork readFromParcel(@NonNull Parcel in) {
return new HotspotNetwork(in.readLong(), NetworkProviderInfo.readFromParcel(in),
in.readInt(), in.readString(), in.readString(), in.readString(),
- (ArraySet<Integer>) in.readArraySet(null));
+ (ArraySet<Integer>) in.readArraySet(null), in.readBundle());
}
@NonNull
@@ -385,6 +412,7 @@
.append(", hotspotSsid=").append(mHotspotSsid)
.append(", hotspotBssid=").append(mHotspotBssid)
.append(", hotspotSecurityTypes=").append(mHotspotSecurityTypes.toString())
+ .append(", extras=").append(mExtras.toString())
.append("]").toString();
}
}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatus.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatus.java
index 69767f3..72acf2c 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatus.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkConnectionStatus.java
@@ -117,7 +117,7 @@
@ConnectionStatus
private int mStatus;
private HotspotNetwork mHotspotNetwork;
- private Bundle mExtras;
+ private Bundle mExtras = Bundle.EMPTY;
/**
* Sets the status of the connection
@@ -179,7 +179,7 @@
}
private HotspotNetworkConnectionStatus(@ConnectionStatus int status,
- HotspotNetwork hotspotNetwork, Bundle extras) {
+ HotspotNetwork hotspotNetwork, @NonNull Bundle extras) {
validate(status);
mStatus = status;
mHotspotNetwork = hotspotNetwork;
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.java
index 64412bc..c390e42 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetwork.java
@@ -22,6 +22,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
import android.text.TextUtils;
@@ -73,6 +74,7 @@
@SecurityType
private final ArraySet<Integer> mSecurityTypes;
private final NetworkProviderInfo mNetworkProviderInfo;
+ private final Bundle mExtras;
/**
* Builder class for {@link KnownNetwork}.
@@ -84,6 +86,7 @@
@SecurityType
private final ArraySet<Integer> mSecurityTypes = new ArraySet<>();
private NetworkProviderInfo mNetworkProviderInfo;
+ private Bundle mExtras = Bundle.EMPTY;
/**
* Sets the indicated source of the known network.
@@ -135,6 +138,17 @@
}
/**
+ * Sets the extras bundle
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
* Builds the {@link KnownNetwork} object.
*
* @return Returns the built {@link KnownNetwork} object.
@@ -145,7 +159,8 @@
mNetworkSource,
mSsid,
mSecurityTypes,
- mNetworkProviderInfo);
+ mNetworkProviderInfo,
+ mExtras);
}
}
@@ -173,12 +188,14 @@
@NetworkSource int networkSource,
@NonNull String ssid,
@NonNull @SecurityType ArraySet<Integer> securityTypes,
- @Nullable NetworkProviderInfo networkProviderInfo) {
+ @Nullable NetworkProviderInfo networkProviderInfo,
+ @NonNull Bundle extras) {
validate(networkSource, ssid, securityTypes, networkProviderInfo);
mNetworkSource = networkSource;
mSsid = ssid;
mSecurityTypes = new ArraySet<>(securityTypes);
mNetworkProviderInfo = networkProviderInfo;
+ mExtras = extras;
}
/**
@@ -223,6 +240,16 @@
return mNetworkProviderInfo;
}
+ /**
+ * Gets the extras Bundle.
+ *
+ * @return Returns a Bundle object.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
@Override
public boolean equals(Object obj) {
if (!(obj instanceof KnownNetwork)) return false;
@@ -249,6 +276,7 @@
dest.writeString(mSsid);
dest.writeArraySet(mSecurityTypes);
mNetworkProviderInfo.writeToParcel(dest, flags);
+ dest.writeBundle(mExtras);
}
/**
@@ -260,7 +288,7 @@
public static KnownNetwork readFromParcel(@NonNull Parcel in) {
return new KnownNetwork(in.readInt(), in.readString(),
(ArraySet<Integer>) in.readArraySet(null),
- NetworkProviderInfo.readFromParcel(in));
+ NetworkProviderInfo.readFromParcel(in), in.readBundle());
}
@NonNull
@@ -283,6 +311,7 @@
.append(", ssid=").append(mSsid)
.append(", securityTypes=").append(mSecurityTypes.toString())
.append(", networkProviderInfo=").append(mNetworkProviderInfo.toString())
+ .append(", extras=").append(mExtras.toString())
.append("]").toString();
}
}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.java
index 6bd0a5e..b30dc3f 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/KnownNetworkConnectionStatus.java
@@ -72,7 +72,7 @@
public static final class Builder {
@ConnectionStatus private int mStatus;
private KnownNetwork mKnownNetwork;
- private Bundle mExtras;
+ private Bundle mExtras = Bundle.EMPTY;
public Builder() {}
@@ -128,7 +128,7 @@
}
private KnownNetworkConnectionStatus(@ConnectionStatus int status, KnownNetwork knownNetwork,
- Bundle extras) {
+ @NonNull Bundle extras) {
validate(status);
mStatus = status;
mKnownNetwork = knownNetwork;
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java
index ed4d699..25fbabc 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfo.java
@@ -21,6 +21,7 @@
import android.annotation.NonNull;
import android.annotation.SystemApi;
import android.net.wifi.sharedconnectivity.service.SharedConnectivityService;
+import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -89,6 +90,7 @@
private final String mModelName;
private final int mBatteryPercentage;
private final int mConnectionStrength;
+ private final Bundle mExtras;
/**
* Builder class for {@link NetworkProviderInfo}.
@@ -99,6 +101,7 @@
private String mModelName;
private int mBatteryPercentage;
private int mConnectionStrength;
+ private Bundle mExtras = Bundle.EMPTY;
public Builder(@NonNull String deviceName, @NonNull String modelName) {
Objects.requireNonNull(deviceName);
@@ -170,6 +173,17 @@
}
/**
+ * Sets the extras bundle
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setExtras(@NonNull Bundle extras) {
+ mExtras = extras;
+ return this;
+ }
+
+ /**
* Builds the {@link NetworkProviderInfo} object.
*
* @return Returns the built {@link NetworkProviderInfo} object.
@@ -177,7 +191,7 @@
@NonNull
public NetworkProviderInfo build() {
return new NetworkProviderInfo(mDeviceType, mDeviceName, mModelName, mBatteryPercentage,
- mConnectionStrength);
+ mConnectionStrength, mExtras);
}
}
@@ -197,13 +211,15 @@
}
private NetworkProviderInfo(@DeviceType int deviceType, @NonNull String deviceName,
- @NonNull String modelName, int batteryPercentage, int connectionStrength) {
+ @NonNull String modelName, int batteryPercentage, int connectionStrength,
+ @NonNull Bundle extras) {
validate(deviceType, deviceName, modelName, batteryPercentage, connectionStrength);
mDeviceType = deviceType;
mDeviceName = deviceName;
mModelName = modelName;
mBatteryPercentage = batteryPercentage;
mConnectionStrength = connectionStrength;
+ mExtras = extras;
}
/**
@@ -256,6 +272,16 @@
return mConnectionStrength;
}
+ /**
+ * Gets the extras Bundle.
+ *
+ * @return Returns a Bundle object.
+ */
+ @NonNull
+ public Bundle getExtras() {
+ return mExtras;
+ }
+
@Override
public boolean equals(Object obj) {
if (!(obj instanceof NetworkProviderInfo)) return false;
@@ -280,6 +306,7 @@
dest.writeString(mModelName);
dest.writeInt(mBatteryPercentage);
dest.writeInt(mConnectionStrength);
+ dest.writeBundle(mExtras);
}
@Override
@@ -295,7 +322,7 @@
@NonNull
public static NetworkProviderInfo readFromParcel(@NonNull Parcel in) {
return new NetworkProviderInfo(in.readInt(), in.readString(), in.readString(), in.readInt(),
- in.readInt());
+ in.readInt(), in.readBundle());
}
@NonNull
@@ -319,6 +346,7 @@
.append(", modelName=").append(mModelName)
.append(", batteryPercentage=").append(mBatteryPercentage)
.append(", connectionStrength=").append(mConnectionStrength)
+ .append(", extras=").append(mExtras.toString())
.append("]").toString();
}
}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.java b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.java
index 4809bef..30bb989 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsState.java
@@ -17,7 +17,11 @@
package android.net.wifi.sharedconnectivity.app;
import android.annotation.NonNull;
+import android.annotation.Nullable;
import android.annotation.SystemApi;
+import android.app.PendingIntent;
+import android.content.Context;
+import android.content.Intent;
import android.os.Bundle;
import android.os.Parcel;
import android.os.Parcelable;
@@ -37,6 +41,7 @@
public final class SharedConnectivitySettingsState implements Parcelable {
private final boolean mInstantTetherEnabled;
+ private final PendingIntent mInstantTetherSettingsPendingIntent;
private final Bundle mExtras;
/**
@@ -44,9 +49,13 @@
*/
public static final class Builder {
private boolean mInstantTetherEnabled;
- private Bundle mExtras;
+ private Intent mInstantTetherSettingsIntent;
+ private final Context mContext;
+ private Bundle mExtras = Bundle.EMPTY;
- public Builder() {}
+ public Builder(@NonNull Context context) {
+ mContext = context;
+ }
/**
* Sets the state of Instant Tether in settings
@@ -60,6 +69,20 @@
}
/**
+ * Sets the intent that will open the Instant Tether settings page.
+ * The intent will be stored as a {@link PendingIntent} in the settings object. The pending
+ * intent will be set as {@link PendingIntent#FLAG_IMMUTABLE} and
+ * {@link PendingIntent#FLAG_ONE_SHOT}.
+ *
+ * @return Returns the Builder object.
+ */
+ @NonNull
+ public Builder setInstantTetherSettingsPendingIntent(@NonNull Intent intent) {
+ mInstantTetherSettingsIntent = intent;
+ return this;
+ }
+
+ /**
* Sets the extras bundle
*
* @return Returns the Builder object.
@@ -77,12 +100,21 @@
*/
@NonNull
public SharedConnectivitySettingsState build() {
- return new SharedConnectivitySettingsState(mInstantTetherEnabled, mExtras);
+ if (mInstantTetherSettingsIntent != null) {
+ PendingIntent pendingIntent = PendingIntent.getActivity(mContext, 0,
+ mInstantTetherSettingsIntent,
+ PendingIntent.FLAG_IMMUTABLE | PendingIntent.FLAG_ONE_SHOT);
+ return new SharedConnectivitySettingsState(mInstantTetherEnabled,
+ pendingIntent, mExtras);
+ }
+ return new SharedConnectivitySettingsState(mInstantTetherEnabled, null, mExtras);
}
}
- private SharedConnectivitySettingsState(boolean instantTetherEnabled, Bundle extras) {
+ private SharedConnectivitySettingsState(boolean instantTetherEnabled,
+ PendingIntent pendingIntent, @NonNull Bundle extras) {
mInstantTetherEnabled = instantTetherEnabled;
+ mInstantTetherSettingsPendingIntent = pendingIntent;
mExtras = extras;
}
@@ -96,6 +128,16 @@
}
/**
+ * Gets the pending intent to open Instant Tether settings page.
+ *
+ * @return Returns the pending intent that opens the settings page, null if none.
+ */
+ @Nullable
+ public PendingIntent getInstantTetherSettingsPendingIntent() {
+ return mInstantTetherSettingsPendingIntent;
+ }
+
+ /**
* Gets the extras Bundle.
*
* @return Returns a Bundle object.
@@ -109,12 +151,14 @@
public boolean equals(Object obj) {
if (!(obj instanceof SharedConnectivitySettingsState)) return false;
SharedConnectivitySettingsState other = (SharedConnectivitySettingsState) obj;
- return mInstantTetherEnabled == other.isInstantTetherEnabled();
+ return mInstantTetherEnabled == other.isInstantTetherEnabled()
+ && Objects.equals(mInstantTetherSettingsPendingIntent,
+ other.getInstantTetherSettingsPendingIntent());
}
@Override
public int hashCode() {
- return Objects.hash(mInstantTetherEnabled);
+ return Objects.hash(mInstantTetherEnabled, mInstantTetherSettingsPendingIntent);
}
@Override
@@ -124,6 +168,7 @@
@Override
public void writeToParcel(@NonNull Parcel dest, int flags) {
+ mInstantTetherSettingsPendingIntent.writeToParcel(dest, 0);
dest.writeBoolean(mInstantTetherEnabled);
dest.writeBundle(mExtras);
}
@@ -135,8 +180,10 @@
*/
@NonNull
public static SharedConnectivitySettingsState readFromParcel(@NonNull Parcel in) {
- return new SharedConnectivitySettingsState(in.readBoolean(),
- in.readBundle());
+ PendingIntent pendingIntent = PendingIntent.CREATOR.createFromParcel(in);
+ boolean instantTetherEnabled = in.readBoolean();
+ Bundle extras = in.readBundle();
+ return new SharedConnectivitySettingsState(instantTetherEnabled, pendingIntent, extras);
}
@NonNull
@@ -156,6 +203,7 @@
public String toString() {
return new StringBuilder("SharedConnectivitySettingsState[")
.append("instantTetherEnabled=").append(mInstantTetherEnabled)
+ .append("PendingIntent=").append(mInstantTetherSettingsPendingIntent.toString())
.append("extras=").append(mExtras.toString())
.append("]").toString();
}
diff --git a/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
index 57108e4..06a86cc 100644
--- a/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
+++ b/wifi/java/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityService.java
@@ -46,6 +46,7 @@
import java.util.Collections;
import java.util.List;
import java.util.Objects;
+import java.util.concurrent.CountDownLatch;
/**
@@ -68,9 +69,7 @@
new RemoteCallbackList<>();
private List<HotspotNetwork> mHotspotNetworks = Collections.emptyList();
private List<KnownNetwork> mKnownNetworks = Collections.emptyList();
- private SharedConnectivitySettingsState mSettingsState =
- new SharedConnectivitySettingsState.Builder().setInstantTetherEnabled(false)
- .setExtras(Bundle.EMPTY).build();
+ private SharedConnectivitySettingsState mSettingsState = null;
private HotspotNetworkConnectionStatus mHotspotNetworkConnectionStatus =
new HotspotNetworkConnectionStatus.Builder()
.setStatus(HotspotNetworkConnectionStatus.CONNECTION_STATUS_UNKNOWN)
@@ -79,6 +78,8 @@
new KnownNetworkConnectionStatus.Builder()
.setStatus(KnownNetworkConnectionStatus.CONNECTION_STATUS_UNKNOWN)
.setExtras(Bundle.EMPTY).build();
+ // Used for testing
+ private CountDownLatch mCountDownLatch;
@Override
@Nullable
@@ -202,6 +203,13 @@
@Override
public SharedConnectivitySettingsState getSettingsState() {
checkPermissions();
+ // Done lazily since creating it needs a context.
+ if (mSettingsState == null) {
+ mSettingsState = new SharedConnectivitySettingsState
+ .Builder(getApplicationContext())
+ .setInstantTetherEnabled(false)
+ .setExtras(Bundle.EMPTY).build();
+ }
return mSettingsState;
}
@@ -260,12 +268,24 @@
public void onBind() {
}
+ /** @hide */
+ @TestApi
+ public final void setCountdownLatch(@Nullable CountDownLatch latch) {
+ mCountDownLatch = latch;
+ }
+
private void onRegisterCallback(ISharedConnectivityCallback callback) {
mRemoteCallbackList.register(callback);
+ if (mCountDownLatch != null) {
+ mCountDownLatch.countDown();
+ }
}
private void onUnregisterCallback(ISharedConnectivityCallback callback) {
mRemoteCallbackList.unregister(callback);
+ if (mCountDownLatch != null) {
+ mCountDownLatch.countDown();
+ }
}
/**
diff --git a/wifi/tests/Android.bp b/wifi/tests/Android.bp
index c9105f7..7a29969 100644
--- a/wifi/tests/Android.bp
+++ b/wifi/tests/Android.bp
@@ -36,6 +36,7 @@
static_libs: [
"androidx.test.rules",
+ "androidx.test.core",
"frameworks-base-testutils",
"guava",
"mockito-target-minus-junit4",
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java
index 8302094..0827ffa 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/HotspotNetworkTest.java
@@ -28,6 +28,7 @@
import static org.junit.Assert.assertThrows;
+import android.os.Bundle;
import android.os.Parcel;
import android.util.ArraySet;
@@ -55,6 +56,8 @@
private static final String HOTSPOT_SSID = "TEST_SSID";
private static final String HOTSPOT_BSSID = "TEST _BSSID";
private static final int[] HOTSPOT_SECURITY_TYPES = {SECURITY_TYPE_WEP, SECURITY_TYPE_EAP};
+ private static final String BUNDLE_KEY = "INT-KEY";
+ private static final int BUNDLE_VALUE = 1;
private static final long DEVICE_ID_1 = 111L;
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO1 =
@@ -138,6 +141,7 @@
assertThat(network.getHotspotSsid()).isEqualTo(HOTSPOT_SSID);
assertThat(network.getHotspotBssid()).isEqualTo(HOTSPOT_BSSID);
assertThat(network.getHotspotSecurityTypes()).containsExactlyElementsIn(securityTypes);
+ assertThat(network.getExtras().getInt(BUNDLE_KEY)).isEqualTo(BUNDLE_VALUE);
}
@Test
@@ -161,11 +165,18 @@
.setHostNetworkType(NETWORK_TYPE)
.setNetworkName(NETWORK_NAME)
.setHotspotSsid(HOTSPOT_SSID)
- .setHotspotBssid(HOTSPOT_BSSID);
+ .setHotspotBssid(HOTSPOT_BSSID)
+ .setExtras(buildBundle());
Arrays.stream(HOTSPOT_SECURITY_TYPES).forEach(builder::addHotspotSecurityType);
if (withNetworkProviderInfo) {
builder.setNetworkProviderInfo(NETWORK_PROVIDER_INFO);
}
return builder;
}
+
+ private Bundle buildBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putInt(BUNDLE_KEY, BUNDLE_VALUE);
+ return bundle;
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
index 1ecba76..81d7b44 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/KnownNetworkTest.java
@@ -25,6 +25,7 @@
import static com.google.common.truth.Truth.assertThat;
+import android.os.Bundle;
import android.os.Parcel;
import android.util.ArraySet;
@@ -47,6 +48,9 @@
new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
.setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
.setBatteryPercentage(50).build();
+ private static final String BUNDLE_KEY = "INT-KEY";
+ private static final int BUNDLE_VALUE = 1;
+
private static final int NETWORK_SOURCE_1 = NETWORK_SOURCE_CLOUD_SELF;
private static final String SSID_1 = "TEST_SSID1";
private static final int[] SECURITY_TYPES_1 = {SECURITY_TYPE_PSK};
@@ -113,6 +117,7 @@
assertThat(network.getSsid()).isEqualTo(SSID);
assertThat(network.getSecurityTypes()).containsExactlyElementsIn(securityTypes);
assertThat(network.getNetworkProviderInfo()).isEqualTo(NETWORK_PROVIDER_INFO);
+ assertThat(network.getExtras().getInt(BUNDLE_KEY)).isEqualTo(BUNDLE_VALUE);
}
@Test
@@ -125,8 +130,15 @@
private KnownNetwork.Builder buildKnownNetworkBuilder() {
KnownNetwork.Builder builder = new KnownNetwork.Builder().setNetworkSource(NETWORK_SOURCE)
- .setSsid(SSID).setNetworkProviderInfo(NETWORK_PROVIDER_INFO);
+ .setSsid(SSID).setNetworkProviderInfo(NETWORK_PROVIDER_INFO)
+ .setExtras(buildBundle());
Arrays.stream(SECURITY_TYPES).forEach(builder::addSecurityType);
return builder;
}
+
+ private Bundle buildBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putInt(BUNDLE_KEY, BUNDLE_VALUE);
+ return bundle;
+ }
}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java
index 8f35d8d..4aa9ca6 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/NetworkProviderInfoTest.java
@@ -21,6 +21,7 @@
import static com.google.common.truth.Truth.assertThat;
+import android.os.Bundle;
import android.os.Parcel;
import androidx.test.filters.SmallTest;
@@ -38,6 +39,8 @@
private static final String DEVICE_MODEL = "TEST_MODEL";
private static final int BATTERY_PERCENTAGE = 50;
private static final int CONNECTION_STRENGTH = 2;
+ private static final String BUNDLE_KEY = "INT-KEY";
+ private static final int BUNDLE_VALUE = 1;
private static final int DEVICE_TYPE_1 = DEVICE_TYPE_LAPTOP;
private static final String DEVICE_NAME_1 = "TEST_NAME1";
@@ -105,6 +108,7 @@
assertThat(info.getModelName()).isEqualTo(DEVICE_MODEL);
assertThat(info.getBatteryPercentage()).isEqualTo(BATTERY_PERCENTAGE);
assertThat(info.getConnectionStrength()).isEqualTo(CONNECTION_STRENGTH);
+ assertThat(info.getExtras().getInt(BUNDLE_KEY)).isEqualTo(BUNDLE_VALUE);
}
@Test
@@ -118,6 +122,13 @@
private NetworkProviderInfo.Builder buildNetworkProviderInfoBuilder() {
return new NetworkProviderInfo.Builder(DEVICE_NAME, DEVICE_MODEL).setDeviceType(DEVICE_TYPE)
.setBatteryPercentage(BATTERY_PERCENTAGE)
- .setConnectionStrength(CONNECTION_STRENGTH);
+ .setConnectionStrength(CONNECTION_STRENGTH)
+ .setExtras(buildBundle());
+ }
+
+ private Bundle buildBundle() {
+ Bundle bundle = new Bundle();
+ bundle.putInt(BUNDLE_KEY, BUNDLE_VALUE);
+ return bundle;
}
}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
index 7578dfd..71239087 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivityManagerTest.java
@@ -497,8 +497,9 @@
@Test
public void getSettingsState_serviceConnected_shouldReturnState() throws RemoteException {
SharedConnectivityManager manager = SharedConnectivityManager.create(mContext);
- SharedConnectivitySettingsState state = new SharedConnectivitySettingsState.Builder()
- .setInstantTetherEnabled(true).setExtras(new Bundle()).build();
+ SharedConnectivitySettingsState state =
+ new SharedConnectivitySettingsState.Builder(mContext).setInstantTetherEnabled(true)
+ .setExtras(new Bundle()).build();
manager.setService(mService);
when(mService.getSettingsState()).thenReturn(state);
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsStateTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsStateTest.java
index 752b749..5e17dfb 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsStateTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/app/SharedConnectivitySettingsStateTest.java
@@ -18,8 +18,10 @@
import static com.google.common.truth.Truth.assertThat;
+import android.content.Intent;
import android.os.Parcel;
+import androidx.test.core.app.ApplicationProvider;
import androidx.test.filters.SmallTest;
import org.junit.Test;
@@ -30,8 +32,12 @@
@SmallTest
public class SharedConnectivitySettingsStateTest {
private static final boolean INSTANT_TETHER_STATE = true;
+ private static final String INTENT_ACTION = "instant.tether.settings";
private static final boolean INSTANT_TETHER_STATE_1 = false;
+ private static final String INTENT_ACTION_1 = "instant.tether.settings1";
+
+
/**
* Verifies parcel serialization/deserialization.
*/
@@ -39,16 +45,11 @@
public void testParcelOperation() {
SharedConnectivitySettingsState state = buildSettingsStateBuilder().build();
- Parcel parcelW = Parcel.obtain();
- state.writeToParcel(parcelW, 0);
- byte[] bytes = parcelW.marshall();
- parcelW.recycle();
-
- Parcel parcelR = Parcel.obtain();
- parcelR.unmarshall(bytes, 0, bytes.length);
- parcelR.setDataPosition(0);
+ Parcel parcel = Parcel.obtain();
+ state.writeToParcel(parcel, 0);
+ parcel.setDataPosition(0);
SharedConnectivitySettingsState fromParcel =
- SharedConnectivitySettingsState.CREATOR.createFromParcel(parcelR);
+ SharedConnectivitySettingsState.CREATOR.createFromParcel(parcel);
assertThat(fromParcel).isEqualTo(state);
assertThat(fromParcel.hashCode()).isEqualTo(state.hashCode());
@@ -66,6 +67,10 @@
SharedConnectivitySettingsState.Builder builder = buildSettingsStateBuilder()
.setInstantTetherEnabled(INSTANT_TETHER_STATE_1);
assertThat(builder.build()).isNotEqualTo(state1);
+
+ builder = buildSettingsStateBuilder()
+ .setInstantTetherSettingsPendingIntent(new Intent(INTENT_ACTION_1));
+ assertThat(builder.build()).isNotEqualTo(state1);
}
/**
@@ -86,7 +91,9 @@
}
private SharedConnectivitySettingsState.Builder buildSettingsStateBuilder() {
- return new SharedConnectivitySettingsState.Builder()
- .setInstantTetherEnabled(INSTANT_TETHER_STATE);
+ return new SharedConnectivitySettingsState.Builder(
+ ApplicationProvider.getApplicationContext())
+ .setInstantTetherEnabled(INSTANT_TETHER_STATE)
+ .setInstantTetherSettingsPendingIntent(new Intent(INTENT_ACTION));
}
}
diff --git a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
index b8b6b767..4a293cb 100644
--- a/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
+++ b/wifi/tests/src/android/net/wifi/sharedconnectivity/service/SharedConnectivityServiceTest.java
@@ -26,7 +26,10 @@
import static com.google.common.truth.Truth.assertThat;
+import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
+import static org.mockito.Mockito.never;
+import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
import android.content.Context;
@@ -39,6 +42,7 @@
import android.net.wifi.sharedconnectivity.app.NetworkProviderInfo;
import android.net.wifi.sharedconnectivity.app.SharedConnectivitySettingsState;
import android.os.Bundle;
+import android.os.IBinder;
import android.os.Looper;
import android.os.RemoteException;
@@ -51,12 +55,16 @@
import org.mockito.MockitoAnnotations;
import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
/**
* Unit tests for {@link SharedConnectivityService}.
*/
@SmallTest
public class SharedConnectivityServiceTest {
+ private static final int LATCH_TIMEOUT = 2;
+
private static final NetworkProviderInfo NETWORK_PROVIDER_INFO =
new NetworkProviderInfo.Builder("TEST_NAME", "TEST_MODEL")
.setDeviceType(DEVICE_TYPE_TABLET).setConnectionStrength(2)
@@ -75,10 +83,7 @@
.addSecurityType(SECURITY_TYPE_EAP).setNetworkProviderInfo(
NETWORK_PROVIDER_INFO).build();
private static final List<KnownNetwork> KNOWN_NETWORKS = List.of(KNOWN_NETWORK);
- private static final SharedConnectivitySettingsState SETTINGS_STATE =
- new SharedConnectivitySettingsState.Builder().setInstantTetherEnabled(true)
- .setExtras(Bundle.EMPTY).build();
- private static final HotspotNetworkConnectionStatus TETHER_NETWORK_CONNECTION_STATUS =
+ private static final HotspotNetworkConnectionStatus HOTSPOT_NETWORK_CONNECTION_STATUS =
new HotspotNetworkConnectionStatus.Builder().setStatus(CONNECTION_STATUS_UNKNOWN)
.setHotspotNetwork(HOTSPOT_NETWORK).setExtras(Bundle.EMPTY).build();
private static final KnownNetworkConnectionStatus KNOWN_NETWORK_CONNECTION_STATUS =
@@ -91,25 +96,77 @@
@Mock
Resources mResources;
+ @Mock
+ ISharedConnectivityCallback mCallback;
+
+ @Mock
+ IBinder mBinder;
+
static class FakeSharedConnectivityService extends SharedConnectivityService {
public void attachBaseContext(Context context) {
super.attachBaseContext(context);
}
+ private HotspotNetwork mConnectedHotspotNetwork;
+ private HotspotNetwork mDisconnectedHotspotNetwork;
+ private KnownNetwork mConnectedKnownNetwork;
+ private KnownNetwork mForgottenKnownNetwork;
+ private CountDownLatch mLatch;
+
+ public HotspotNetwork getConnectedHotspotNetwork() {
+ return mConnectedHotspotNetwork;
+ }
+
+ public HotspotNetwork getDisconnectedHotspotNetwork() {
+ return mDisconnectedHotspotNetwork;
+ }
+
+ public KnownNetwork getConnectedKnownNetwork() {
+ return mConnectedKnownNetwork;
+ }
+
+ public KnownNetwork getForgottenKnownNetwork() {
+ return mForgottenKnownNetwork;
+ }
+
+ public void initializeLatch() {
+ mLatch = new CountDownLatch(1);
+ }
+
+ public CountDownLatch getLatch() {
+ return mLatch;
+ }
+
@Override
public void onConnectHotspotNetwork(@NonNull HotspotNetwork network) {
+ mConnectedHotspotNetwork = network;
+ if (mLatch != null) {
+ mLatch.countDown();
+ }
}
@Override
public void onDisconnectHotspotNetwork(@NonNull HotspotNetwork network) {
+ mDisconnectedHotspotNetwork = network;
+ if (mLatch != null) {
+ mLatch.countDown();
+ }
}
@Override
public void onConnectKnownNetwork(@NonNull KnownNetwork network) {
+ mConnectedKnownNetwork = network;
+ if (mLatch != null) {
+ mLatch.countDown();
+ }
}
@Override
public void onForgetKnownNetwork(@NonNull KnownNetwork network) {
+ mForgottenKnownNetwork = network;
+ if (mLatch != null) {
+ mLatch.countDown();
+ }
}
}
@@ -155,10 +212,11 @@
SharedConnectivityService service = createService();
ISharedConnectivityService.Stub binder =
(ISharedConnectivityService.Stub) service.onBind(new Intent());
+ when(mContext.getPackageName()).thenReturn("android.net.wifi.nonupdatable.test");
- service.setSettingsState(SETTINGS_STATE);
+ service.setSettingsState(buildSettingsState());
- assertThat(binder.getSettingsState()).isEqualTo(SETTINGS_STATE);
+ assertThat(binder.getSettingsState()).isEqualTo(buildSettingsState());
}
@Test
@@ -167,10 +225,10 @@
ISharedConnectivityService.Stub binder =
(ISharedConnectivityService.Stub) service.onBind(new Intent());
- service.updateHotspotNetworkConnectionStatus(TETHER_NETWORK_CONNECTION_STATUS);
+ service.updateHotspotNetworkConnectionStatus(HOTSPOT_NETWORK_CONNECTION_STATUS);
assertThat(binder.getHotspotNetworkConnectionStatus())
- .isEqualTo(TETHER_NETWORK_CONNECTION_STATUS);
+ .isEqualTo(HOTSPOT_NETWORK_CONNECTION_STATUS);
}
@Test
@@ -227,9 +285,123 @@
assertThat(SharedConnectivityService.areKnownNetworksEnabledForService(mContext)).isFalse();
}
- private SharedConnectivityService createService() {
+ @Test
+ public void connectHotspotNetwork() throws RemoteException, InterruptedException {
+ FakeSharedConnectivityService service = createService();
+ ISharedConnectivityService.Stub binder =
+ (ISharedConnectivityService.Stub) service.onBind(new Intent());
+ service.initializeLatch();
+
+ binder.connectHotspotNetwork(HOTSPOT_NETWORK);
+
+ assertThat(service.getLatch().await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+ assertThat(service.getConnectedHotspotNetwork()).isEqualTo(HOTSPOT_NETWORK);
+ }
+
+ @Test
+ public void disconnectHotspotNetwork() throws RemoteException, InterruptedException {
+ FakeSharedConnectivityService service = createService();
+ ISharedConnectivityService.Stub binder =
+ (ISharedConnectivityService.Stub) service.onBind(new Intent());
+ service.initializeLatch();
+
+ binder.disconnectHotspotNetwork(HOTSPOT_NETWORK);
+
+ assertThat(service.getLatch().await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+ assertThat(service.getDisconnectedHotspotNetwork()).isEqualTo(HOTSPOT_NETWORK);
+ }
+
+ @Test
+ public void connectKnownNetwork() throws RemoteException , InterruptedException {
+ FakeSharedConnectivityService service = createService();
+ ISharedConnectivityService.Stub binder =
+ (ISharedConnectivityService.Stub) service.onBind(new Intent());
+ service.initializeLatch();
+
+ binder.connectKnownNetwork(KNOWN_NETWORK);
+
+ assertThat(service.getLatch().await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+ assertThat(service.getConnectedKnownNetwork()).isEqualTo(KNOWN_NETWORK);
+ }
+
+ @Test
+ public void forgetKnownNetwork() throws RemoteException, InterruptedException {
+ FakeSharedConnectivityService service = createService();
+ ISharedConnectivityService.Stub binder =
+ (ISharedConnectivityService.Stub) service.onBind(new Intent());
+ service.initializeLatch();
+
+ binder.forgetKnownNetwork(KNOWN_NETWORK);
+
+ assertThat(service.getLatch().await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+ assertThat(service.getForgottenKnownNetwork()).isEqualTo(KNOWN_NETWORK);
+ }
+
+ @Test
+ public void registerCallback() throws RemoteException, InterruptedException {
+ SharedConnectivityService service = createService();
+ ISharedConnectivityService.Stub binder =
+ (ISharedConnectivityService.Stub) service.onBind(new Intent());
+ when(mCallback.asBinder()).thenReturn(mBinder);
+ when(mContext.getPackageName()).thenReturn("android.net.wifi.nonupdatable.test");
+ SharedConnectivitySettingsState state = buildSettingsState();
+
+ CountDownLatch latch = new CountDownLatch(1);
+ service.setCountdownLatch(latch);
+ binder.registerCallback(mCallback);
+ assertThat(latch.await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+ service.setHotspotNetworks(HOTSPOT_NETWORKS);
+ service.setKnownNetworks(KNOWN_NETWORKS);
+ service.setSettingsState(state);
+ service.updateHotspotNetworkConnectionStatus(HOTSPOT_NETWORK_CONNECTION_STATUS);
+ service.updateKnownNetworkConnectionStatus(KNOWN_NETWORK_CONNECTION_STATUS);
+
+ verify(mCallback).onHotspotNetworksUpdated(HOTSPOT_NETWORKS);
+ verify(mCallback).onKnownNetworksUpdated(KNOWN_NETWORKS);
+ verify(mCallback).onSharedConnectivitySettingsChanged(state);
+ verify(mCallback).onHotspotNetworkConnectionStatusChanged(
+ HOTSPOT_NETWORK_CONNECTION_STATUS);
+ verify(mCallback).onKnownNetworkConnectionStatusChanged(KNOWN_NETWORK_CONNECTION_STATUS);
+ }
+
+ @Test
+ public void unregisterCallback() throws RemoteException, InterruptedException {
+ SharedConnectivityService service = createService();
+ ISharedConnectivityService.Stub binder =
+ (ISharedConnectivityService.Stub) service.onBind(new Intent());
+ when(mCallback.asBinder()).thenReturn(mBinder);
+ when(mContext.getPackageName()).thenReturn("android.net.wifi.nonupdatable.test");
+
+ CountDownLatch latch = new CountDownLatch(1);
+ service.setCountdownLatch(latch);
+ binder.registerCallback(mCallback);
+ assertThat(latch.await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+ latch = new CountDownLatch(1);
+ service.setCountdownLatch(latch);
+ binder.unregisterCallback(mCallback);
+ assertThat(latch.await(LATCH_TIMEOUT, TimeUnit.SECONDS)).isTrue();
+ service.setHotspotNetworks(HOTSPOT_NETWORKS);
+ service.setKnownNetworks(KNOWN_NETWORKS);
+ service.setSettingsState(buildSettingsState());
+ service.updateHotspotNetworkConnectionStatus(HOTSPOT_NETWORK_CONNECTION_STATUS);
+ service.updateKnownNetworkConnectionStatus(KNOWN_NETWORK_CONNECTION_STATUS);
+
+ verify(mCallback, never()).onHotspotNetworksUpdated(any());
+ verify(mCallback, never()).onKnownNetworksUpdated(any());
+ verify(mCallback, never()).onSharedConnectivitySettingsChanged(any());
+ verify(mCallback, never()).onHotspotNetworkConnectionStatusChanged(any());
+ verify(mCallback, never()).onKnownNetworkConnectionStatusChanged(any());
+ }
+
+ private FakeSharedConnectivityService createService() {
FakeSharedConnectivityService service = new FakeSharedConnectivityService();
service.attachBaseContext(mContext);
return service;
}
+
+ private SharedConnectivitySettingsState buildSettingsState() {
+ return new SharedConnectivitySettingsState.Builder(mContext).setInstantTetherEnabled(true)
+ .setInstantTetherSettingsPendingIntent(new Intent())
+ .setExtras(Bundle.EMPTY).build();
+ }
}