Merge "Camera2: add deferred output config support" into nyc-mr1-dev
diff --git a/api/current.txt b/api/current.txt
index 01aa843..e751dcc 100644
--- a/api/current.txt
+++ b/api/current.txt
@@ -1040,6 +1040,7 @@
field public static final int rotation = 16843558; // 0x1010326
field public static final int rotationX = 16843559; // 0x1010327
field public static final int rotationY = 16843560; // 0x1010328
+ field public static final int roundIcon = 16844083; // 0x1010533
field public static final int rowCount = 16843637; // 0x1010375
field public static final int rowDelay = 16843216; // 0x10101d0
field public static final int rowEdgeFlags = 16843329; // 0x1010241
@@ -1107,15 +1108,14 @@
field public static final int shareInterpolator = 16843195; // 0x10101bb
field public static final int sharedUserId = 16842763; // 0x101000b
field public static final int sharedUserLabel = 16843361; // 0x1010261
- field public static final int shortcutCategories = 16844081; // 0x1010531
- field public static final int shortcutDisabledMessage = 16844080; // 0x1010530
- field public static final int shortcutIcon = 16844077; // 0x101052d
+ field public static final int shortcutCategories = 16844080; // 0x1010530
+ field public static final int shortcutDisabledMessage = 16844079; // 0x101052f
+ field public static final int shortcutIcon = 16844076; // 0x101052c
field public static final int shortcutId = 16844075; // 0x101052b
- field public static final int shortcutIntentAction = 16844082; // 0x1010532
- field public static final int shortcutIntentData = 16844083; // 0x1010533
- field public static final int shortcutRank = 16844076; // 0x101052c
- field public static final int shortcutText = 16844079; // 0x101052f
- field public static final int shortcutTitle = 16844078; // 0x101052e
+ field public static final int shortcutIntentAction = 16844081; // 0x1010531
+ field public static final int shortcutIntentData = 16844082; // 0x1010532
+ field public static final int shortcutLongLabel = 16844078; // 0x101052e
+ field public static final int shortcutShortLabel = 16844077; // 0x101052d
field public static final int shouldDisableView = 16843246; // 0x10101ee
field public static final int showAsAction = 16843481; // 0x10102d9
field public static final int showDefault = 16843258; // 0x10101fa
@@ -10058,18 +10058,18 @@
method public android.content.ComponentName getActivity();
method public java.util.Set<java.lang.String> getCategories();
method public java.lang.CharSequence getDisabledMessage();
- method public int getDisabledMessageResId();
+ method public int getDisabledMessageResourceId();
method public android.os.PersistableBundle getExtras();
method public int getIconResourceId();
method public java.lang.String getId();
method public android.content.Intent getIntent();
method public long getLastChangedTimestamp();
+ method public java.lang.CharSequence getLongLabel();
+ method public int getLongLabelResourceId();
method public java.lang.String getPackage();
method public int getRank();
- method public java.lang.CharSequence getText();
- method public int getTextResId();
- method public java.lang.CharSequence getTitle();
- method public int getTitleResId();
+ method public java.lang.CharSequence getShortLabel();
+ method public int getShortLabelResourceId();
method public android.os.UserHandle getUserHandle();
method public boolean hasIconFile();
method public boolean hasIconResource();
@@ -10107,9 +10107,9 @@
method public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
method public android.content.pm.ShortcutInfo.Builder setId(java.lang.String);
method public android.content.pm.ShortcutInfo.Builder setIntent(android.content.Intent);
+ method public android.content.pm.ShortcutInfo.Builder setLongLabel(java.lang.String);
method public android.content.pm.ShortcutInfo.Builder setRank(int);
- method public android.content.pm.ShortcutInfo.Builder setText(java.lang.String);
- method public android.content.pm.ShortcutInfo.Builder setTitle(java.lang.String);
+ method public android.content.pm.ShortcutInfo.Builder setShortLabel(java.lang.String);
}
public class ShortcutManager {
@@ -33101,6 +33101,7 @@
field public static final int QUOTA_UNAVAILABLE = -1; // 0xffffffff
field public static final java.lang.String SETTINGS_URI = "settings_uri";
field public static final java.lang.String SOURCE_PACKAGE = "source_package";
+ field public static final java.lang.String SOURCE_TYPE = "source_type";
field public static final java.lang.String VOICEMAIL_ACCESS_URI = "voicemail_access_uri";
}
diff --git a/api/system-current.txt b/api/system-current.txt
index c18b916..2e6f7a4 100644
--- a/api/system-current.txt
+++ b/api/system-current.txt
@@ -1146,6 +1146,7 @@
field public static final int rotation = 16843558; // 0x1010326
field public static final int rotationX = 16843559; // 0x1010327
field public static final int rotationY = 16843560; // 0x1010328
+ field public static final int roundIcon = 16844083; // 0x1010533
field public static final int rowCount = 16843637; // 0x1010375
field public static final int rowDelay = 16843216; // 0x10101d0
field public static final int rowEdgeFlags = 16843329; // 0x1010241
@@ -1217,15 +1218,14 @@
field public static final int shareInterpolator = 16843195; // 0x10101bb
field public static final int sharedUserId = 16842763; // 0x101000b
field public static final int sharedUserLabel = 16843361; // 0x1010261
- field public static final int shortcutCategories = 16844081; // 0x1010531
- field public static final int shortcutDisabledMessage = 16844080; // 0x1010530
- field public static final int shortcutIcon = 16844077; // 0x101052d
+ field public static final int shortcutCategories = 16844080; // 0x1010530
+ field public static final int shortcutDisabledMessage = 16844079; // 0x101052f
+ field public static final int shortcutIcon = 16844076; // 0x101052c
field public static final int shortcutId = 16844075; // 0x101052b
- field public static final int shortcutIntentAction = 16844082; // 0x1010532
- field public static final int shortcutIntentData = 16844083; // 0x1010533
- field public static final int shortcutRank = 16844076; // 0x101052c
- field public static final int shortcutText = 16844079; // 0x101052f
- field public static final int shortcutTitle = 16844078; // 0x101052e
+ field public static final int shortcutIntentAction = 16844081; // 0x1010531
+ field public static final int shortcutIntentData = 16844082; // 0x1010532
+ field public static final int shortcutLongLabel = 16844078; // 0x101052e
+ field public static final int shortcutShortLabel = 16844077; // 0x101052d
field public static final int shouldDisableView = 16843246; // 0x10101ee
field public static final int showAsAction = 16843481; // 0x10102d9
field public static final int showDefault = 16843258; // 0x10101fa
@@ -10481,18 +10481,18 @@
method public android.content.ComponentName getActivity();
method public java.util.Set<java.lang.String> getCategories();
method public java.lang.CharSequence getDisabledMessage();
- method public int getDisabledMessageResId();
+ method public int getDisabledMessageResourceId();
method public android.os.PersistableBundle getExtras();
method public int getIconResourceId();
method public java.lang.String getId();
method public android.content.Intent getIntent();
method public long getLastChangedTimestamp();
+ method public java.lang.CharSequence getLongLabel();
+ method public int getLongLabelResourceId();
method public java.lang.String getPackage();
method public int getRank();
- method public java.lang.CharSequence getText();
- method public int getTextResId();
- method public java.lang.CharSequence getTitle();
- method public int getTitleResId();
+ method public java.lang.CharSequence getShortLabel();
+ method public int getShortLabelResourceId();
method public android.os.UserHandle getUserHandle();
method public boolean hasIconFile();
method public boolean hasIconResource();
@@ -10530,9 +10530,9 @@
method public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
method public android.content.pm.ShortcutInfo.Builder setId(java.lang.String);
method public android.content.pm.ShortcutInfo.Builder setIntent(android.content.Intent);
+ method public android.content.pm.ShortcutInfo.Builder setLongLabel(java.lang.String);
method public android.content.pm.ShortcutInfo.Builder setRank(int);
- method public android.content.pm.ShortcutInfo.Builder setText(java.lang.String);
- method public android.content.pm.ShortcutInfo.Builder setTitle(java.lang.String);
+ method public android.content.pm.ShortcutInfo.Builder setShortLabel(java.lang.String);
}
public class ShortcutManager {
@@ -35807,6 +35807,7 @@
field public static final int QUOTA_UNAVAILABLE = -1; // 0xffffffff
field public static final java.lang.String SETTINGS_URI = "settings_uri";
field public static final java.lang.String SOURCE_PACKAGE = "source_package";
+ field public static final java.lang.String SOURCE_TYPE = "source_type";
field public static final java.lang.String VOICEMAIL_ACCESS_URI = "voicemail_access_uri";
}
diff --git a/api/test-current.txt b/api/test-current.txt
index 7de82b3..02ee580 100644
--- a/api/test-current.txt
+++ b/api/test-current.txt
@@ -1040,6 +1040,7 @@
field public static final int rotation = 16843558; // 0x1010326
field public static final int rotationX = 16843559; // 0x1010327
field public static final int rotationY = 16843560; // 0x1010328
+ field public static final int roundIcon = 16844083; // 0x1010533
field public static final int rowCount = 16843637; // 0x1010375
field public static final int rowDelay = 16843216; // 0x10101d0
field public static final int rowEdgeFlags = 16843329; // 0x1010241
@@ -1107,15 +1108,14 @@
field public static final int shareInterpolator = 16843195; // 0x10101bb
field public static final int sharedUserId = 16842763; // 0x101000b
field public static final int sharedUserLabel = 16843361; // 0x1010261
- field public static final int shortcutCategories = 16844081; // 0x1010531
- field public static final int shortcutDisabledMessage = 16844080; // 0x1010530
- field public static final int shortcutIcon = 16844077; // 0x101052d
+ field public static final int shortcutCategories = 16844080; // 0x1010530
+ field public static final int shortcutDisabledMessage = 16844079; // 0x101052f
+ field public static final int shortcutIcon = 16844076; // 0x101052c
field public static final int shortcutId = 16844075; // 0x101052b
- field public static final int shortcutIntentAction = 16844082; // 0x1010532
- field public static final int shortcutIntentData = 16844083; // 0x1010533
- field public static final int shortcutRank = 16844076; // 0x101052c
- field public static final int shortcutText = 16844079; // 0x101052f
- field public static final int shortcutTitle = 16844078; // 0x101052e
+ field public static final int shortcutIntentAction = 16844081; // 0x1010531
+ field public static final int shortcutIntentData = 16844082; // 0x1010532
+ field public static final int shortcutLongLabel = 16844078; // 0x101052e
+ field public static final int shortcutShortLabel = 16844077; // 0x101052d
field public static final int shouldDisableView = 16843246; // 0x10101ee
field public static final int showAsAction = 16843481; // 0x10102d9
field public static final int showDefault = 16843258; // 0x10101fa
@@ -10071,18 +10071,18 @@
method public android.content.ComponentName getActivity();
method public java.util.Set<java.lang.String> getCategories();
method public java.lang.CharSequence getDisabledMessage();
- method public int getDisabledMessageResId();
+ method public int getDisabledMessageResourceId();
method public android.os.PersistableBundle getExtras();
method public int getIconResourceId();
method public java.lang.String getId();
method public android.content.Intent getIntent();
method public long getLastChangedTimestamp();
+ method public java.lang.CharSequence getLongLabel();
+ method public int getLongLabelResourceId();
method public java.lang.String getPackage();
method public int getRank();
- method public java.lang.CharSequence getText();
- method public int getTextResId();
- method public java.lang.CharSequence getTitle();
- method public int getTitleResId();
+ method public java.lang.CharSequence getShortLabel();
+ method public int getShortLabelResourceId();
method public android.os.UserHandle getUserHandle();
method public boolean hasIconFile();
method public boolean hasIconResource();
@@ -10120,9 +10120,9 @@
method public android.content.pm.ShortcutInfo.Builder setIcon(android.graphics.drawable.Icon);
method public android.content.pm.ShortcutInfo.Builder setId(java.lang.String);
method public android.content.pm.ShortcutInfo.Builder setIntent(android.content.Intent);
+ method public android.content.pm.ShortcutInfo.Builder setLongLabel(java.lang.String);
method public android.content.pm.ShortcutInfo.Builder setRank(int);
- method public android.content.pm.ShortcutInfo.Builder setText(java.lang.String);
- method public android.content.pm.ShortcutInfo.Builder setTitle(java.lang.String);
+ method public android.content.pm.ShortcutInfo.Builder setShortLabel(java.lang.String);
}
public class ShortcutManager {
@@ -33178,6 +33178,7 @@
field public static final int QUOTA_UNAVAILABLE = -1; // 0xffffffff
field public static final java.lang.String SETTINGS_URI = "settings_uri";
field public static final java.lang.String SOURCE_PACKAGE = "source_package";
+ field public static final java.lang.String SOURCE_TYPE = "source_type";
field public static final java.lang.String VOICEMAIL_ACCESS_URI = "voicemail_access_uri";
}
diff --git a/core/java/android/app/AlarmManager.java b/core/java/android/app/AlarmManager.java
index 2ae437e..c561a19 100644
--- a/core/java/android/app/AlarmManager.java
+++ b/core/java/android/app/AlarmManager.java
@@ -606,6 +606,22 @@
*
* @hide
*/
+ public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
+ String tag, OnAlarmListener listener, Handler targetHandler, WorkSource workSource) {
+ setImpl(type, triggerAtMillis, windowMillis, intervalMillis, 0, null, listener, tag,
+ targetHandler, workSource, null);
+ }
+
+ /**
+ * Direct callback version of {@link #set(int, long, long, long, PendingIntent, WorkSource)}.
+ * Note that repeating alarms must use the PendingIntent variant, not an OnAlarmListener.
+ * <p>
+ * The OnAlarmListener's {@link OnAlarmListener#onAlarm() onAlarm()} method will be
+ * invoked via the specified target Handler, or on the application's main looper
+ * if {@code null} is passed as the {@code targetHandler} parameter.
+ *
+ * @hide
+ */
@SystemApi
public void set(int type, long triggerAtMillis, long windowMillis, long intervalMillis,
OnAlarmListener listener, Handler targetHandler, WorkSource workSource) {
diff --git a/core/java/android/app/LoadedApk.java b/core/java/android/app/LoadedApk.java
index 1f3dfa7..152f45e 100644
--- a/core/java/android/app/LoadedApk.java
+++ b/core/java/android/app/LoadedApk.java
@@ -543,12 +543,7 @@
// It is NOT ok to call this function from the system_server (for any of the packages it
// loads code from) so we explicitly disallow it there.
if (needToSetupJitProfiles && !ActivityThread.isSystem()) {
- // Temporarily disable logging of disk reads/writes on the Looper thread
- // as this is early and necessary. Write is only needed to create the
- // profile file if it's not already there.
- StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskWrites();
setupJitProfileSupport();
- StrictMode.setThreadPolicy(oldPolicy);
}
}
@@ -572,6 +567,15 @@
if (!SystemProperties.getBoolean("dalvik.vm.usejitprofiles", false)) {
return;
}
+ // Only set up profile support if the loaded apk has the same uid as the
+ // current process.
+ // Currently, we do not support profiling across different apps.
+ // (e.g. application's uid might be different when the code is
+ // loaded by another app via createApplicationContext)
+ if (mApplicationInfo.uid != Process.myUid()) {
+ return;
+ }
+
final List<String> codePaths = new ArrayList<>();
if ((mApplicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
codePaths.add(mApplicationInfo.sourceDir);
@@ -587,55 +591,11 @@
}
final File profileFile = getPrimaryProfileFile(mPackageName);
- if (profileFile.exists()) {
- if (!profileFile.canRead() || !profileFile.canWrite()) {
- // The apk might be loaded in a context where we don't have permissions
- // to track the profile (e.g. when loaded by another app via
- // createApplicationContext)
- return;
- }
- } else {
- // Profile does not exist. Create it.
- FileDescriptor fd = null;
- try {
- final int permissions = 0600; // read-write for user.
- fd = Os.open(profileFile.getAbsolutePath(), OsConstants.O_CREAT, permissions);
- Os.fchmod(fd, permissions);
- Os.fchown(fd, mApplicationInfo.uid, mApplicationInfo.uid);
- } catch (ErrnoException e) {
- if (e.errno == OsConstants.EACCES) {
- // It can happen that the profile file does not exist but the apk is loaded in a
- // context where we don't have permissions (e.g. when loaded by another app via
- // createApplicationContext)
- return;
- }
- Log.v(TAG, "Unable to create jit profile file "
- + profileFile + ": " + e.getMessage());
- try {
- Os.unlink(profileFile.getAbsolutePath());
- } catch (ErrnoException unlinkErr) {
- if (unlinkErr.errno != OsConstants.ENOENT) {
- Log.v(TAG, "Unable to unlink jit profile file "
- + profileFile + ": " + unlinkErr.getMessage());
- }
- }
- return;
- } finally {
- IoUtils.closeQuietly(fd);
- }
- }
-
final File foreignDexProfilesFile =
Environment.getDataProfilesDeForeignDexDirectory(UserHandle.myUserId());
- String foreignDexProfilesPath = null;
- if (!foreignDexProfilesFile.exists()) {
- Log.v(TAG, "ForeignDexProfilesPath does not exists:" +
- foreignDexProfilesFile.getPath());
- } else {
- foreignDexProfilesPath = foreignDexProfilesFile.getAbsolutePath();
- }
- VMRuntime.registerAppInfo(profileFile.getAbsolutePath(), mApplicationInfo.dataDir,
- codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesPath);
+
+ VMRuntime.registerAppInfo(profileFile.getPath(), mApplicationInfo.dataDir,
+ codePaths.toArray(new String[codePaths.size()]), foreignDexProfilesFile.getPath());
}
/**
diff --git a/core/java/android/app/Notification.java b/core/java/android/app/Notification.java
index e108dd6e..83a2066 100644
--- a/core/java/android/app/Notification.java
+++ b/core/java/android/app/Notification.java
@@ -4479,6 +4479,35 @@
if (!mMessages.isEmpty()) { extras.putParcelableArray(EXTRA_MESSAGES,
Message.getBundleArrayForMessages(mMessages));
}
+
+ fixTitleAndTextExtras(extras);
+ }
+
+ private void fixTitleAndTextExtras(Bundle extras) {
+ Message m = findLatestIncomingMessage();
+ CharSequence text = (m == null) ? null : m.mText;
+ CharSequence sender = m == null ? null
+ : TextUtils.isEmpty(m.mSender) ? mUserDisplayName : m.mSender;
+ CharSequence title;
+ if (!TextUtils.isEmpty(mConversationTitle)) {
+ if (!TextUtils.isEmpty(sender)) {
+ BidiFormatter bidi = BidiFormatter.getInstance();
+ title = mBuilder.mContext.getString(
+ com.android.internal.R.string.notification_messaging_title_template,
+ bidi.unicodeWrap(mConversationTitle), bidi.unicodeWrap(m.mSender));
+ } else {
+ title = mConversationTitle;
+ }
+ } else {
+ title = sender;
+ }
+
+ if (title != null) {
+ extras.putCharSequence(EXTRA_TITLE, title);
+ }
+ if (text != null) {
+ extras.putCharSequence(EXTRA_TEXT, text);
+ }
}
/**
@@ -4524,6 +4553,10 @@
return m;
}
}
+ if (!mMessages.isEmpty()) {
+ // No incoming messages, fall back to outgoing message
+ return mMessages.get(mMessages.size() - 1);
+ }
return null;
}
diff --git a/core/java/android/app/ResourcesManager.java b/core/java/android/app/ResourcesManager.java
index 25a8b66..31d254dc 100644
--- a/core/java/android/app/ResourcesManager.java
+++ b/core/java/android/app/ResourcesManager.java
@@ -29,7 +29,6 @@
import android.content.res.ResourcesKey;
import android.hardware.display.DisplayManagerGlobal;
import android.os.IBinder;
-import android.os.LocaleList;
import android.os.Trace;
import android.util.ArrayMap;
import android.util.DisplayMetrics;
@@ -38,13 +37,12 @@
import android.util.Slog;
import android.view.Display;
import android.view.DisplayAdjustments;
+
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.HashSet;
import java.util.Objects;
import java.util.WeakHashMap;
import java.util.function.Predicate;
@@ -120,6 +118,30 @@
}
}
+ /**
+ * Invalidate and destroy any resources that reference content under the
+ * given filesystem path. Typically used when unmounting a storage device to
+ * try as hard as possible to release any open FDs.
+ */
+ public void invalidatePath(String path) {
+ synchronized (this) {
+ int count = 0;
+ for (int i = 0; i < mResourceImpls.size();) {
+ final ResourcesKey key = mResourceImpls.keyAt(i);
+ if (key.isPathReferenced(path)) {
+ final ResourcesImpl res = mResourceImpls.removeAt(i).get();
+ if (res != null) {
+ res.flushLayoutCache();
+ }
+ count++;
+ } else {
+ i++;
+ }
+ }
+ Log.i(TAG, "Invalidated " + count + " asset managers that referenced " + path);
+ }
+ }
+
public Configuration getConfiguration() {
synchronized (this) {
return mResConfiguration;
diff --git a/core/java/android/app/job/JobInfo.java b/core/java/android/app/job/JobInfo.java
index 61790ea..c4ca82e 100644
--- a/core/java/android/app/job/JobInfo.java
+++ b/core/java/android/app/job/JobInfo.java
@@ -192,7 +192,8 @@
private final int flags;
/**
- * Unique job id associated with this class. This is assigned to your job by the scheduler.
+ * Unique job id associated with this application (uid). This is the same job ID
+ * you supplied in the {@link Builder} constructor.
*/
public int getId() {
return jobId;
@@ -524,9 +525,9 @@
/** Builder class for constructing {@link JobInfo} objects. */
public static final class Builder {
- private int mJobId;
+ private final int mJobId;
+ private final ComponentName mJobService;
private PersistableBundle mExtras = PersistableBundle.EMPTY;
- private ComponentName mJobService;
private int mPriority = PRIORITY_DEFAULT;
private int mFlags;
// Requirements.
@@ -553,11 +554,15 @@
private boolean mBackoffPolicySet = false;
/**
+ * Initialize a new Builder to construct a {@link JobInfo}.
+ *
* @param jobId Application-provided id for this job. Subsequent calls to cancel, or
- * jobs created with the same jobId, will update the pre-existing job with
- * the same id.
+ * jobs created with the same jobId, will update the pre-existing job with
+ * the same id. This ID must be unique across all clients of the same uid
+ * (not just the same package). You will want to make sure this is a stable
+ * id across app updates, so probably not based on a resource ID.
* @param jobService The endpoint that you implement that will receive the callback from the
- * JobScheduler.
+ * JobScheduler.
*/
public Builder(int jobId, ComponentName jobService) {
mJobService = jobService;
@@ -635,6 +640,13 @@
* <p>Because because setting this property is not compatible with periodic or
* persisted jobs, doing so will throw an {@link java.lang.IllegalArgumentException} when
* {@link android.app.job.JobInfo.Builder#build()} is called.</p>
+ *
+ * <p>The following example shows how this feature can be used to monitor for changes
+ * in the photos on a device.</p>
+ *
+ * {@sample development/samples/ApiDemos/src/com/example/android/apis/content/PhotosContentJob.java
+ * job}
+ *
* @param uri The content: URI to monitor.
*/
public Builder addTriggerContentUri(@NonNull TriggerContentUri uri) {
diff --git a/core/java/android/bluetooth/BluetoothHeadset.java b/core/java/android/bluetooth/BluetoothHeadset.java
index 09a15de..f46a3b3 100644
--- a/core/java/android/bluetooth/BluetoothHeadset.java
+++ b/core/java/android/bluetooth/BluetoothHeadset.java
@@ -220,6 +220,46 @@
* {@link #EXTRA_STATE} or {@link #EXTRA_PREVIOUS_STATE} of
* {@link #ACTION_AUDIO_STATE_CHANGED} intent.
*/
+
+ /**
+ * Intent used to broadcast the headset's indicator status
+ *
+ * <p>This intent will have 3 extras:
+ * <ul>
+ * <li> {@link #EXTRA_IND_ID} - The Assigned number of headset Indicator which is supported by
+ the headset ( as indicated by AT+BIND
+ command in the SLC sequence).or whose value
+ is changed (indicated by AT+BIEV command)</li>
+ * <li> {@link #EXTRA_IND_VALUE}- The updated value of headset indicator. </li>
+ * <li> {@link BluetoothDevice#EXTRA_DEVICE} - The remote device. </li>
+ * </ul>
+ * <p>{@link #EXTRA_IND_ID} is defined by Bluetooth SIG and each of the indicators are
+ * given an assigned number. Below shows the assigned number of Indicator added so far
+ * - Enhanced Safety - 1
+ * <p>Requires {@link android.Manifest.permission#BLUETOOTH} permission to
+ * receive.
+ * @hide
+ */
+ public static final String ACTION_HF_INDICATORS_VALUE_CHANGED =
+ "android.bluetooth.headset.action.HF_INDICATORS_VALUE_CHANGED";
+
+ /**
+ * A String extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
+ * intents that contains the UUID of the headset indicator (as defined by Bluetooth SIG)
+ * that is being sent.
+ * @hide
+ */
+ public static final String EXTRA_HF_INDICATORS_IND_ID =
+ "android.bluetooth.headset.extra.HF_INDICATORS_IND_ID";
+
+ /**
+ * A int extra field in {@link #ACTION_HF_INDICATORS_VALUE_CHANGED}
+ * intents that contains the value of the Headset indicator that is being sent.
+ * @hide
+ */
+ public static final String EXTRA_HF_INDICATORS_IND_VALUE =
+ "android.bluetooth.headset.extra.HF_INDICATORS_IND_VALUE";
+
public static final int STATE_AUDIO_CONNECTED = 12;
private static final int MESSAGE_HEADSET_SERVICE_CONNECTED = 100;
@@ -969,6 +1009,29 @@
return false;
}
+ /**
+ * Send Headset the BIND response from AG to report change in the status of the
+ * HF indicators to the headset
+ *
+ * @param ind_id Assigned Number of the indicator (defined by SIG)
+ * @param ind_status
+ * possible values- false-Indicator is disabled, no value changes shall be sent for this indicator
+ * true-Indicator is enabled, value changes may be sent for this indicator
+ * @hide
+ */
+ public void bindResponse(int ind_id, boolean ind_status) {
+ if (mService != null && isEnabled()) {
+ try {
+ mService.bindResponse(ind_id, ind_status);
+ } catch (RemoteException e) {
+ Log.e(TAG, e.toString());
+ }
+ } else {
+ Log.w(TAG, "Proxy not attached to service");
+ if (DBG) Log.d(TAG, Log.getStackTraceString(new Throwable()));
+ }
+ }
+
private final IBluetoothProfileServiceConnection mConnection
= new IBluetoothProfileServiceConnection.Stub() {
@Override
diff --git a/core/java/android/bluetooth/IBluetoothHeadset.aidl b/core/java/android/bluetooth/IBluetoothHeadset.aidl
index 0bb4088..6ad442b 100755
--- a/core/java/android/bluetooth/IBluetoothHeadset.aidl
+++ b/core/java/android/bluetooth/IBluetoothHeadset.aidl
@@ -59,4 +59,5 @@
String number, int type);
boolean enableWBS();
boolean disableWBS();
+ void bindResponse(int ind_id, boolean ind_status);
}
diff --git a/core/java/android/content/Intent.java b/core/java/android/content/Intent.java
index 9118f01..df2c6fc 100644
--- a/core/java/android/content/Intent.java
+++ b/core/java/android/content/Intent.java
@@ -3174,6 +3174,14 @@
public static final String ACTION_MASTER_CLEAR = "android.intent.action.MASTER_CLEAR";
/**
+ * Boolean intent extra to be used with {@link ACTION_MASTER_CLEAR} in order to force a factory
+ * reset even if {@link android.os.UserManager.DISALLOW_FACTORY_RESET} is set.
+ * @hide
+ */
+ public static final String EXTRA_FORCE_MASTER_CLEAR =
+ "android.intent.extra.FORCE_MASTER_CLEAR";
+
+ /**
* Broadcast action: report that a settings element is being restored from backup. The intent
* contains three extras: EXTRA_SETTING_NAME is a string naming the restored setting,
* EXTRA_SETTING_NEW_VALUE is the value being restored, and EXTRA_SETTING_PREVIOUS_VALUE
diff --git a/core/java/android/content/pm/IPackageManager.aidl b/core/java/android/content/pm/IPackageManager.aidl
index 4bbbdee..11f0eb6 100644
--- a/core/java/android/content/pm/IPackageManager.aidl
+++ b/core/java/android/content/pm/IPackageManager.aidl
@@ -482,6 +482,11 @@
boolean performDexOptMode(String packageName, boolean checkProfiles,
String targetCompilerFilter, boolean force);
+ /**
+ * Ask the package manager to dump profiles associated with a package.
+ */
+ void dumpProfiles(String packageName);
+
void forceDexOpt(String packageName);
/**
diff --git a/core/java/android/content/pm/PackageItemInfo.java b/core/java/android/content/pm/PackageItemInfo.java
index edd888b..30da03c 100644
--- a/core/java/android/content/pm/PackageItemInfo.java
+++ b/core/java/android/content/pm/PackageItemInfo.java
@@ -25,6 +25,7 @@
import android.os.Parcel;
import android.os.UserHandle;
import android.text.BidiFormatter;
+import android.text.Html;
import android.text.TextPaint;
import android.text.TextUtils;
import android.util.Printer;
@@ -164,12 +165,13 @@
@SystemApi
public @NonNull CharSequence loadSafeLabel(@NonNull PackageManager pm) {
// loadLabel() always returns non-null
- CharSequence label = loadLabel(pm);
+ String label = loadLabel(pm).toString();
+ // strip HTML tags to avoid <br> and other tags overwriting original message
+ String labelStr = Html.fromHtml(label).toString();
// If the label contains new line characters it may push the UI
// down to hide a part of it. Labels shouldn't have new line
// characters, so just truncate at the first time one is seen.
- String labelStr = label.toString();
final int labelLength = labelStr.length();
int offset = 0;
while (offset < labelLength) {
@@ -181,13 +183,18 @@
labelStr = labelStr.substring(0, offset);
break;
}
+ // replace all non-break space to " " in order to be trimmed
+ if (type == Character.SPACE_SEPARATOR) {
+ labelStr = labelStr.substring(0, offset) + " " + labelStr.substring(offset +
+ Character.charCount(codePoint));
+ }
offset += Character.charCount(codePoint);
}
+ labelStr = labelStr.trim();
if (labelStr.isEmpty()) {
- return labelStr;
+ return packageName;
}
-
TextPaint paint = new TextPaint();
paint.setTextSize(42);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index adf9fe6..fffdf71 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -270,6 +270,7 @@
final int nameRes;
final int labelRes;
final int iconRes;
+ final int roundIconRes;
final int logoRes;
final int bannerRes;
@@ -277,7 +278,8 @@
TypedArray sa;
ParsePackageItemArgs(Package _owner, String[] _outError,
- int _nameRes, int _labelRes, int _iconRes, int _logoRes, int _bannerRes) {
+ int _nameRes, int _labelRes, int _iconRes, int _roundIconRes, int _logoRes,
+ int _bannerRes) {
owner = _owner;
outError = _outError;
nameRes = _nameRes;
@@ -285,6 +287,7 @@
iconRes = _iconRes;
logoRes = _logoRes;
bannerRes = _bannerRes;
+ roundIconRes = _roundIconRes;
}
}
@@ -296,10 +299,12 @@
int flags;
ParseComponentArgs(Package _owner, String[] _outError,
- int _nameRes, int _labelRes, int _iconRes, int _logoRes, int _bannerRes,
+ int _nameRes, int _labelRes, int _iconRes, int _roundIconRes, int _logoRes,
+ int _bannerRes,
String[] _sepProcesses, int _processRes,
int _descriptionRes, int _enabledRes) {
- super(_owner, _outError, _nameRes, _labelRes, _iconRes, _logoRes, _bannerRes);
+ super(_owner, _outError, _nameRes, _labelRes, _iconRes, _roundIconRes, _logoRes,
+ _bannerRes);
sepProcesses = _sepProcesses;
processRes = _processRes;
descriptionRes = _descriptionRes;
@@ -2508,10 +2513,11 @@
com.android.internal.R.styleable.AndroidManifestPermissionGroup);
if (!parsePackageItemInfo(owner, perm.info, outError,
- "<permission-group>", sa,
+ "<permission-group>", sa, true /*nameRequired*/,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_name,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_label,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_icon,
+ com.android.internal.R.styleable.AndroidManifestPermissionGroup_roundIcon,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_logo,
com.android.internal.R.styleable.AndroidManifestPermissionGroup_banner)) {
sa.recycle();
@@ -2552,10 +2558,11 @@
com.android.internal.R.styleable.AndroidManifestPermission);
if (!parsePackageItemInfo(owner, perm.info, outError,
- "<permission>", sa,
+ "<permission>", sa, true /*nameRequired*/,
com.android.internal.R.styleable.AndroidManifestPermission_name,
com.android.internal.R.styleable.AndroidManifestPermission_label,
com.android.internal.R.styleable.AndroidManifestPermission_icon,
+ com.android.internal.R.styleable.AndroidManifestPermission_roundIcon,
com.android.internal.R.styleable.AndroidManifestPermission_logo,
com.android.internal.R.styleable.AndroidManifestPermission_banner)) {
sa.recycle();
@@ -2621,10 +2628,11 @@
com.android.internal.R.styleable.AndroidManifestPermissionTree);
if (!parsePackageItemInfo(owner, perm.info, outError,
- "<permission-tree>", sa,
+ "<permission-tree>", sa, true /*nameRequired*/,
com.android.internal.R.styleable.AndroidManifestPermissionTree_name,
com.android.internal.R.styleable.AndroidManifestPermissionTree_label,
com.android.internal.R.styleable.AndroidManifestPermissionTree_icon,
+ com.android.internal.R.styleable.AndroidManifestPermissionTree_roundIcon,
com.android.internal.R.styleable.AndroidManifestPermissionTree_logo,
com.android.internal.R.styleable.AndroidManifestPermissionTree_banner)) {
sa.recycle();
@@ -2671,6 +2679,7 @@
com.android.internal.R.styleable.AndroidManifestInstrumentation_name,
com.android.internal.R.styleable.AndroidManifestInstrumentation_label,
com.android.internal.R.styleable.AndroidManifestInstrumentation_icon,
+ com.android.internal.R.styleable.AndroidManifestInstrumentation_roundIcon,
com.android.internal.R.styleable.AndroidManifestInstrumentation_logo,
com.android.internal.R.styleable.AndroidManifestInstrumentation_banner);
mParseInstrumentationArgs.tag = "<instrumentation>";
@@ -2736,10 +2745,21 @@
TypedArray sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestApplication);
- String name = sa.getNonConfigurationString(
- com.android.internal.R.styleable.AndroidManifestApplication_name, 0);
- if (name != null) {
- ai.className = buildClassName(pkgName, name, outError);
+ if (!parsePackageItemInfo(owner, ai, outError,
+ "<application>", sa, false /*nameRequired*/,
+ com.android.internal.R.styleable.AndroidManifestApplication_name,
+ com.android.internal.R.styleable.AndroidManifestApplication_label,
+ com.android.internal.R.styleable.AndroidManifestApplication_icon,
+ com.android.internal.R.styleable.AndroidManifestApplication_roundIcon,
+ com.android.internal.R.styleable.AndroidManifestApplication_logo,
+ com.android.internal.R.styleable.AndroidManifestApplication_banner)) {
+ sa.recycle();
+ mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+ return false;
+ }
+
+ if (ai.name != null) {
+ ai.className = buildClassName(pkgName, ai.name, outError);
if (ai.className == null) {
sa.recycle();
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
@@ -2810,18 +2830,6 @@
}
}
- TypedValue v = sa.peekValue(
- com.android.internal.R.styleable.AndroidManifestApplication_label);
- if (v != null && (ai.labelRes=v.resourceId) == 0) {
- ai.nonLocalizedLabel = v.coerceToString();
- }
-
- ai.icon = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestApplication_icon, 0);
- ai.logo = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestApplication_logo, 0);
- ai.banner = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestApplication_banner, 0);
ai.theme = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestApplication_theme, 0);
ai.descriptionRes = sa.getResourceId(
@@ -3335,25 +3343,33 @@
return true;
}
- private boolean parsePackageItemInfo(Package owner, PackageItemInfo outInfo,
- String[] outError, String tag, TypedArray sa,
- int nameRes, int labelRes, int iconRes, int logoRes, int bannerRes) {
+ private static boolean parsePackageItemInfo(Package owner, PackageItemInfo outInfo,
+ String[] outError, String tag, TypedArray sa, boolean nameRequired,
+ int nameRes, int labelRes, int iconRes, int roundIconRes, int logoRes, int bannerRes) {
String name = sa.getNonConfigurationString(nameRes, 0);
if (name == null) {
- outError[0] = tag + " does not specify android:name";
- return false;
+ if (nameRequired) {
+ outError[0] = tag + " does not specify android:name";
+ return false;
+ }
+ } else {
+ outInfo.name
+ = buildClassName(owner.applicationInfo.packageName, name, outError);
+ if (outInfo.name == null) {
+ return false;
+ }
}
- outInfo.name
- = buildClassName(owner.applicationInfo.packageName, name, outError);
- if (outInfo.name == null) {
- return false;
- }
-
- int iconVal = sa.getResourceId(iconRes, 0);
- if (iconVal != 0) {
- outInfo.icon = iconVal;
+ int roundIconVal = sa.getResourceId(roundIconRes, 0);
+ if (roundIconVal != 0) {
+ outInfo.icon = roundIconVal;
outInfo.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(iconRes, 0);
+ if (iconVal != 0) {
+ outInfo.icon = iconVal;
+ outInfo.nonLocalizedLabel = null;
+ }
}
int logoVal = sa.getResourceId(logoRes, 0);
@@ -3387,6 +3403,7 @@
R.styleable.AndroidManifestActivity_name,
R.styleable.AndroidManifestActivity_label,
R.styleable.AndroidManifestActivity_icon,
+ R.styleable.AndroidManifestActivity_roundIcon,
R.styleable.AndroidManifestActivity_logo,
R.styleable.AndroidManifestActivity_banner,
mSeparateProcesses,
@@ -3761,6 +3778,7 @@
com.android.internal.R.styleable.AndroidManifestActivityAlias_name,
com.android.internal.R.styleable.AndroidManifestActivityAlias_label,
com.android.internal.R.styleable.AndroidManifestActivityAlias_icon,
+ com.android.internal.R.styleable.AndroidManifestActivityAlias_roundIcon,
com.android.internal.R.styleable.AndroidManifestActivityAlias_logo,
com.android.internal.R.styleable.AndroidManifestActivityAlias_banner,
mSeparateProcesses,
@@ -3915,6 +3933,7 @@
com.android.internal.R.styleable.AndroidManifestProvider_name,
com.android.internal.R.styleable.AndroidManifestProvider_label,
com.android.internal.R.styleable.AndroidManifestProvider_icon,
+ com.android.internal.R.styleable.AndroidManifestProvider_roundIcon,
com.android.internal.R.styleable.AndroidManifestProvider_logo,
com.android.internal.R.styleable.AndroidManifestProvider_banner,
mSeparateProcesses,
@@ -4234,6 +4253,7 @@
com.android.internal.R.styleable.AndroidManifestService_name,
com.android.internal.R.styleable.AndroidManifestService_label,
com.android.internal.R.styleable.AndroidManifestService_icon,
+ com.android.internal.R.styleable.AndroidManifestService_roundIcon,
com.android.internal.R.styleable.AndroidManifestService_logo,
com.android.internal.R.styleable.AndroidManifestService_banner,
mSeparateProcesses,
@@ -4550,8 +4570,14 @@
outInfo.nonLocalizedLabel = v.coerceToString();
}
- outInfo.icon = sa.getResourceId(
- com.android.internal.R.styleable.AndroidManifestIntentFilter_icon, 0);
+ int roundIcon = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestIntentFilter_roundIcon, 0);
+ if (roundIcon != 0) {
+ outInfo.icon = roundIcon;
+ } else {
+ outInfo.icon = sa.getResourceId(
+ com.android.internal.R.styleable.AndroidManifestIntentFilter_icon, 0);
+ }
outInfo.logo = sa.getResourceId(
com.android.internal.R.styleable.AndroidManifestIntentFilter_logo, 0);
@@ -5180,45 +5206,13 @@
public Component(final ParsePackageItemArgs args, final PackageItemInfo outInfo) {
owner = args.owner;
intents = new ArrayList<II>(0);
- String name = args.sa.getNonConfigurationString(args.nameRes, 0);
- if (name == null) {
+ if (parsePackageItemInfo(args.owner, outInfo, args.outError, args.tag, args.sa,
+ true /*nameRequired*/, args.nameRes, args.labelRes, args.iconRes,
+ args.roundIconRes, args.logoRes, args.bannerRes)) {
+ className = outInfo.name;
+ } else {
className = null;
- args.outError[0] = args.tag + " does not specify android:name";
- return;
}
-
- outInfo.name
- = buildClassName(owner.applicationInfo.packageName, name, args.outError);
- if (outInfo.name == null) {
- className = null;
- args.outError[0] = args.tag + " does not have valid android:name";
- return;
- }
-
- className = outInfo.name;
-
- int iconVal = args.sa.getResourceId(args.iconRes, 0);
- if (iconVal != 0) {
- outInfo.icon = iconVal;
- outInfo.nonLocalizedLabel = null;
- }
-
- int logoVal = args.sa.getResourceId(args.logoRes, 0);
- if (logoVal != 0) {
- outInfo.logo = logoVal;
- }
-
- int bannerVal = args.sa.getResourceId(args.bannerRes, 0);
- if (bannerVal != 0) {
- outInfo.banner = bannerVal;
- }
-
- TypedValue v = args.sa.peekValue(args.labelRes);
- if (v != null && (outInfo.labelRes=v.resourceId) == 0) {
- outInfo.nonLocalizedLabel = v.coerceToString();
- }
-
- outInfo.packageName = owner.packageName;
}
public Component(final ParseComponentArgs args, final ComponentInfo outInfo) {
diff --git a/core/java/android/content/pm/ShortcutInfo.java b/core/java/android/content/pm/ShortcutInfo.java
index c83aa22..28e7887 100644
--- a/core/java/android/content/pm/ShortcutInfo.java
+++ b/core/java/android/content/pm/ShortcutInfo.java
@@ -350,7 +350,7 @@
mTitleResId = 0;
} else if (source.mTitleResId != 0) {
mTitle = null;
- mTitleResId = source.getTitleResId();
+ mTitleResId = source.mTitleResId;
}
if (source.mText != null) {
mText = source.mText;
@@ -490,47 +490,77 @@
return this;
}
- /** @hide */
- public Builder setTitleResId(int titleResId) {
- Preconditions.checkState(mTitle == null, "title already set");
- mTitleResId = titleResId;
+ /**
+ * @hide We don't support resource strings for dynamic shortcuts for now. (But unit tests
+ * use it.)
+ */
+ public Builder setShortLabelResId(int shortLabelResId) {
+ Preconditions.checkState(mTitle == null, "shortLabel already set");
+ mTitleResId = shortLabelResId;
return this;
}
/**
- * Sets the title of a shortcut. This is a mandatory field.
+ * Sets the short title of a shortcut. This is a mandatory field.
*
* <p>This field is intended for a concise description of a shortcut displayed under
* an icon. The recommend max length is 10 characters.
*/
@NonNull
- public Builder setTitle(@NonNull String title) {
- Preconditions.checkState(mTitleResId == 0, "titleResId already set");
- mTitle = Preconditions.checkStringNotEmpty(title, "title");
+ public Builder setShortLabel(@NonNull String shortLabel) {
+ Preconditions.checkState(mTitleResId == 0, "shortLabelResId already set");
+ mTitle = Preconditions.checkStringNotEmpty(shortLabel, "shortLabel");
return this;
}
- /** @hide */
- public Builder setTextResId(int textResId) {
- Preconditions.checkState(mText == null, "text already set");
- mTextResId = textResId;
+ /**
+ * @hide We don't support resource strings for dynamic shortcuts for now. (But unit tests
+ * use it.)
+ */
+ public Builder setLongLabelResId(int longLabelResId) {
+ Preconditions.checkState(mText == null, "longLabel already set");
+ mTextResId = longLabelResId;
return this;
}
/**
* Sets the text of a shortcut. This is an optional field.
*
- * <p>This field is intended to be more descriptive than the shortcut title.
+ * <p>This field is intended to be more descriptive than the shortcut title. The launcher
+ * shows this instead of the short title, when it has enough space.
* The recommend max length is 25 characters.
*/
@NonNull
- public Builder setText(@NonNull String text) {
- Preconditions.checkState(mTextResId == 0, "textResId already set");
- mText = Preconditions.checkStringNotEmpty(text, "text");
+ public Builder setLongLabel(@NonNull String longLabel) {
+ Preconditions.checkState(mTextResId == 0, "longLabelResId already set");
+ mText = Preconditions.checkStringNotEmpty(longLabel, "longLabel");
return this;
}
- /** @hide */
+ /** @hide -- old signature, the internal code still uses it. */
+ public Builder setTitle(@NonNull String value) {
+ return setShortLabel(value);
+ }
+
+ /** @hide -- old signature, the internal code still uses it. */
+ public Builder setTitleResId(int value) {
+ return setShortLabelResId(value);
+ }
+
+ /** @hide -- old signature, the internal code still uses it. */
+ public Builder setText(@NonNull String value) {
+ return setLongLabel(value);
+ }
+
+ /** @hide -- old signature, the internal code still uses it. */
+ public Builder setTextResId(int value) {
+ return setLongLabelResId(value);
+ }
+
+ /**
+ * @hide We don't support resource strings for dynamic shortcuts for now. (But unit tests
+ * use it.)
+ */
public Builder setDisabledMessageResId(int disabledMessageResId) {
Preconditions.checkState(mDisabledMessage == null, "disabledMessage already set");
mDisabledMessageResId = disabledMessageResId;
@@ -641,32 +671,54 @@
return mIcon;
}
- /**
- * Return the shortcut title.
- *
- * <p>All shortcuts must have a non-empty title, but this method will return null when
- * {@link #hasKeyFieldsOnly()} is true.
- */
+ /** @hide -- old signature, the internal code still uses it. */
@Nullable
public CharSequence getTitle() {
return mTitle;
}
- /** TODO Javadoc */
+ /** @hide -- old signature, the internal code still uses it. */
public int getTitleResId() {
return mTitleResId;
}
+ /** @hide -- old signature, the internal code still uses it. */
+ @Nullable
+ public CharSequence getText() {
+ return mText;
+ }
+
+ /** @hide -- old signature, the internal code still uses it. */
+ public int getTextResId() {
+ return mTextResId;
+ }
+
+ /**
+ * Return the shorter version of the shortcut title.
+ *
+ * <p>All shortcuts must have a non-empty title, but this method will return null when
+ * {@link #hasKeyFieldsOnly()} is true.
+ */
+ @Nullable
+ public CharSequence getShortLabel() {
+ return mTitle;
+ }
+
+ /** TODO Javadoc */
+ public int getShortLabelResourceId() {
+ return mTitleResId;
+ }
+
/**
* Return the shortcut text.
*/
@Nullable
- public CharSequence getText() {
+ public CharSequence getLongLabel() {
return mText;
}
/** TODO Javadoc */
- public int getTextResId() {
+ public int getLongLabelResourceId() {
return mTextResId;
}
@@ -679,7 +731,7 @@
}
/** TODO Javadoc */
- public int getDisabledMessageResId() {
+ public int getDisabledMessageResourceId() {
return mDisabledMessageResId;
}
@@ -1104,19 +1156,19 @@
sb.append(", activity=");
sb.append(mActivity);
- sb.append(", title=");
+ sb.append(", shortLabel=");
sb.append(secure ? "***" : mTitle);
- sb.append(", titleResId=");
+ sb.append(", resId=");
sb.append(mTitleResId);
- sb.append(", text=");
+ sb.append(", longLabel=");
sb.append(secure ? "***" : mText);
- sb.append(", textResId=");
+ sb.append(", resId=");
sb.append(mTextResId);
sb.append(", disabledMessage=");
sb.append(secure ? "***" : mDisabledMessage);
- sb.append(", disabledMessageResId=");
+ sb.append(", resId=");
sb.append(mDisabledMessageResId);
sb.append(", categories=");
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index f6445e6..6f43d99 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -207,7 +207,7 @@
public static final int SCREENLAYOUT_COMPAT_NEEDED = 0x10000000;
/**
- * Bit mask of overall layout of the screen. Currently there are two
+ * Bit mask of overall layout of the screen. Currently there are four
* fields:
* <p>The {@link #SCREENLAYOUT_SIZE_MASK} bits define the overall size
* of the screen. They may be one of
diff --git a/core/java/android/content/res/ResourcesKey.java b/core/java/android/content/res/ResourcesKey.java
index e894492..64b6bf1 100644
--- a/core/java/android/content/res/ResourcesKey.java
+++ b/core/java/android/content/res/ResourcesKey.java
@@ -77,6 +77,26 @@
return !Configuration.EMPTY.equals(mOverrideConfiguration);
}
+ public boolean isPathReferenced(String path) {
+ if (mResDir != null && mResDir.startsWith(path)) {
+ return true;
+ } else {
+ return anyStartsWith(mSplitResDirs, path) || anyStartsWith(mOverlayDirs, path)
+ || anyStartsWith(mLibDirs, path);
+ }
+ }
+
+ private static boolean anyStartsWith(String[] list, String prefix) {
+ if (list != null) {
+ for (String s : list) {
+ if (s != null && s.startsWith(prefix)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
@Override
public int hashCode() {
return mHash;
diff --git a/core/java/android/os/PowerManagerInternal.java b/core/java/android/os/PowerManagerInternal.java
index b3cf710..9bbe8f9 100644
--- a/core/java/android/os/PowerManagerInternal.java
+++ b/core/java/android/os/PowerManagerInternal.java
@@ -57,14 +57,19 @@
/**
* Power hint:
* Interaction: The user is interacting with the device. The corresponding data field must be
- * the expected duration of the fling, or 0 if unknown.
+ * the expected duration of the interaction, or 0 if unknown.
*
- * Sustained Performance Mode: Enable/Disables Sustained Performance Mode.
+ * Sustained Performance Mode: The corresponding data field must be Enable/Disable
+ * Sustained Performance Mode.
+ *
+ * Launch: This is specific for activity launching. The corresponding data field must be
+ * the expected duration of the required boost, or 0 if unknown.
*
* These must be kept in sync with the values in hardware/libhardware/include/hardware/power.h
*/
public static final int POWER_HINT_INTERACTION = 2;
public static final int POWER_HINT_SUSTAINED_PERFORMANCE_MODE = 6;
+ public static final int POWER_HINT_LAUNCH = 8;
public static String wakefulnessToString(int wakefulness) {
switch (wakefulness) {
diff --git a/core/java/android/os/RecoverySystem.java b/core/java/android/os/RecoverySystem.java
index 4abbf0e..acb24e1 100644
--- a/core/java/android/os/RecoverySystem.java
+++ b/core/java/android/os/RecoverySystem.java
@@ -570,18 +570,19 @@
* @throws SecurityException if the current user is not allowed to wipe data.
*/
public static void rebootWipeUserData(Context context) throws IOException {
- rebootWipeUserData(context, false, context.getPackageName());
+ rebootWipeUserData(context, false /* shutdown */, context.getPackageName(),
+ false /* force */);
}
/** {@hide} */
public static void rebootWipeUserData(Context context, String reason) throws IOException {
- rebootWipeUserData(context, false, reason);
+ rebootWipeUserData(context, false /* shutdown */, reason, false /* force */);
}
/** {@hide} */
public static void rebootWipeUserData(Context context, boolean shutdown)
throws IOException {
- rebootWipeUserData(context, shutdown, context.getPackageName());
+ rebootWipeUserData(context, shutdown, context.getPackageName(), false /* force */);
}
/**
@@ -595,6 +596,9 @@
* @param shutdown if true, the device will be powered down after
* the wipe completes, rather than being rebooted
* back to the regular system.
+ * @param reason the reason for the wipe that is visible in the logs
+ * @param force whether the {@link UserManager.DISALLOW_FACTORY_RESET} user restriction
+ * should be ignored
*
* @throws IOException if writing the recovery command file
* fails, or if the reboot itself fails.
@@ -602,10 +606,10 @@
*
* @hide
*/
- public static void rebootWipeUserData(Context context, boolean shutdown, String reason)
- throws IOException {
+ public static void rebootWipeUserData(Context context, boolean shutdown, String reason,
+ boolean force) throws IOException {
UserManager um = (UserManager) context.getSystemService(Context.USER_SERVICE);
- if (um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
+ if (!force && um.hasUserRestriction(UserManager.DISALLOW_FACTORY_RESET)) {
throw new SecurityException("Wiping data is not allowed for this user.");
}
final ConditionVariable condition = new ConditionVariable();
diff --git a/core/java/android/provider/Settings.java b/core/java/android/provider/Settings.java
index 1b4c15d..d558070 100755
--- a/core/java/android/provider/Settings.java
+++ b/core/java/android/provider/Settings.java
@@ -6269,7 +6269,6 @@
ACCESSIBILITY_DISPLAY_MAGNIFICATION_AUTO_UPDATE,
ACCESSIBILITY_SCRIPT_INJECTION,
ACCESSIBILITY_WEB_CONTENT_KEY_BINDINGS,
- BACKUP_AUTO_RESTORE,
ENABLED_ACCESSIBILITY_SERVICES,
ENABLED_NOTIFICATION_LISTENERS,
ENABLED_VR_LISTENERS,
@@ -8037,6 +8036,36 @@
public static final String ALARM_MANAGER_CONSTANTS = "alarm_manager_constants";
/**
+ * Job scheduler specific settings.
+ * This is encoded as a key=value list, separated by commas. Ex:
+ *
+ * "min_ready_jobs_count=2,moderate_use_factor=.5"
+ *
+ * The following keys are supported:
+ *
+ * <pre>
+ * min_idle_count (int)
+ * min_charging_count (int)
+ * min_connectivity_count (int)
+ * min_content_count (int)
+ * min_ready_jobs_count (int)
+ * heavy_use_factor (float)
+ * moderate_use_factor (float)
+ * fg_job_count (int)
+ * bg_normal_job_count (int)
+ * bg_moderate_job_count (int)
+ * bg_low_job_count (int)
+ * bg_critical_job_count (int)
+ * </pre>
+ *
+ * <p>
+ * Type: string
+ * @hide
+ * @see com.android.server.job.JobSchedulerService.Constants
+ */
+ public static final String JOB_SCHEDULER_CONSTANTS = "job_scheduler_constants";
+
+ /**
* ShortcutManager specific settings.
* This is encoded as a key=value list, separated by commas. Ex:
*
@@ -8988,6 +9017,14 @@
* @hide
*/
public static final String OEM_UNLOCK_DISALLOWED = "oem_unlock_disallowed";
+
+ /**
+ * The maximum allowed notification enqueue rate in Hertz.
+ *
+ * Should be a float, and includes both posts and updates.
+ * @hide
+ */
+ public static final String MAX_NOTIFICATION_ENQUEUE_RATE = "max_notification_enqueue_rate";
}
/**
diff --git a/core/java/android/provider/VoicemailContract.java b/core/java/android/provider/VoicemailContract.java
index 55aac9f..ab9e497 100644
--- a/core/java/android/provider/VoicemailContract.java
+++ b/core/java/android/provider/VoicemailContract.java
@@ -25,7 +25,6 @@
import android.content.Context;
import android.content.Intent;
import android.database.ContentObserver;
-import android.database.Cursor;
import android.net.Uri;
import android.provider.CallLog.Calls;
import android.telecom.PhoneAccount;
@@ -401,6 +400,20 @@
*/
public static final String SOURCE_PACKAGE = SOURCE_PACKAGE_FIELD;
+ /**
+ * The type of the source, which determines how to interpret source-specific states.
+ * Typically this will be set to the same string as
+ * {@link android.telephony.CarrierConfigManager#KEY_VVM_TYPE_STRING}. For example,
+ * "vvm_type_omtp".
+ *
+ * <P>Type: TEXT</P>
+ *
+ * @see #CONFIGURATION_STATE
+ * @see #DATA_CHANNEL_STATE
+ * @see #NOTIFICATION_CHANNEL_STATE
+ */
+ public static final String SOURCE_TYPE = "source_type";
+
// Note: Multiple entries may exist for a single source if they are differentiated by the
// PHONE_ACCOUNT_* fields.
@@ -433,6 +446,10 @@
public static final String VOICEMAIL_ACCESS_URI = "voicemail_access_uri";
/**
* The configuration state of the voicemail source.
+ *
+ * <P>Negative values are reserved to the source for source-specific states, see
+ * {@link #SOURCE_TYPE}
+ *
* <P> Possible values:
* {@link #CONFIGURATION_STATE_OK},
* {@link #CONFIGURATION_STATE_NOT_CONFIGURED},
@@ -440,14 +457,7 @@
* <P>Type: INTEGER</P>
*/
public static final String CONFIGURATION_STATE = "configuration_state";
- /**
- * Value of {@link #CONFIGURATION_STATE} passed into
- * {@link #setStatus(Context, PhoneAccountHandle, int, int, int)} to indicate that the
- * {@link #CONFIGURATION_STATE} field is not to be changed
- *
- * @hide
- */
- public static final int CONFIGURATION_STATE_IGNORE = -1;
+
/** Value of {@link #CONFIGURATION_STATE} to indicate an all OK configuration status. */
public static final int CONFIGURATION_STATE_OK = 0;
/**
@@ -465,6 +475,10 @@
/**
* The data channel state of the voicemail source. This the channel through which the source
* pulls voicemail data from a remote server.
+ *
+ * <P>Negative values are reserved to the source for source-specific states, see
+ * {@link #SOURCE_TYPE}
+ *
* <P> Possible values:
* {@link #DATA_CHANNEL_STATE_OK},
* {@link #DATA_CHANNEL_STATE_NO_CONNECTION}
@@ -472,14 +486,7 @@
* <P>Type: INTEGER</P>
*/
public static final String DATA_CHANNEL_STATE = "data_channel_state";
- /**
- * Value of {@link #DATA_CHANNEL_STATE} passed into
- * {@link #setStatus(Context, PhoneAccountHandle, int, int, int)} to indicate that the
- * {@link #DATA_CHANNEL_STATE} field is not to be changed
- *
- * @hide
- */
- public static final int DATA_CHANNEL_STATE_IGNORE = -1;
+
/**
* Value of {@link #DATA_CHANNEL_STATE} to indicate that data channel is working fine.
*/
@@ -519,6 +526,10 @@
/**
* The notification channel state of the voicemail source. This is the channel through which
* the source gets notified of new voicemails on the remote server.
+ *
+ * <P>Negative values are reserved to the source for source-specific states, see
+ * {@link #SOURCE_TYPE}
+ *
* <P> Possible values:
* {@link #NOTIFICATION_CHANNEL_STATE_OK},
* {@link #NOTIFICATION_CHANNEL_STATE_NO_CONNECTION},
@@ -527,14 +538,7 @@
* <P>Type: INTEGER</P>
*/
public static final String NOTIFICATION_CHANNEL_STATE = "notification_channel_state";
- /**
- * Value of {@link #NOTIFICATION_CHANNEL_STATE} passed into
- * {@link #setStatus(Context, PhoneAccountHandle, int, int, int)} to indicate that the
- * {@link #NOTIFICATION_CHANNEL_STATE} field is not to be changed
- *
- * @hide
- */
- public static final int NOTIFICATION_CHANNEL_STATE_IGNORE = -1;
+
/**
* Value of {@link #NOTIFICATION_CHANNEL_STATE} to indicate that the notification channel is
* working fine.
@@ -584,67 +588,5 @@
return Status.CONTENT_URI.buildUpon()
.appendQueryParameter(PARAM_KEY_SOURCE_PACKAGE, packageName).build();
}
-
- /**
- * A helper method to set the status of a voicemail source.
- *
- * @param context The context from the package calling the method. This will be the source.
- * @param accountHandle The handle for the account the source is associated with.
- * @param configurationState See {@link Status#CONFIGURATION_STATE}
- * @param dataChannelState See {@link Status#DATA_CHANNEL_STATE}
- * @param notificationChannelState See {@link Status#NOTIFICATION_CHANNEL_STATE}
- *
- * @hide
- */
- public static void setStatus(Context context, PhoneAccountHandle accountHandle,
- int configurationState, int dataChannelState, int notificationChannelState) {
- ContentValues values = new ContentValues();
- values.put(Status.PHONE_ACCOUNT_COMPONENT_NAME,
- accountHandle.getComponentName().flattenToString());
- values.put(Status.PHONE_ACCOUNT_ID, accountHandle.getId());
- if(configurationState != CONFIGURATION_STATE_IGNORE) {
- values.put(Status.CONFIGURATION_STATE, configurationState);
- }
- if(dataChannelState != DATA_CHANNEL_STATE_IGNORE) {
- values.put(Status.DATA_CHANNEL_STATE, dataChannelState);
- }
- if(notificationChannelState != NOTIFICATION_CHANNEL_STATE_IGNORE) {
- values.put(Status.NOTIFICATION_CHANNEL_STATE, notificationChannelState);
- }
- ContentResolver contentResolver = context.getContentResolver();
- Uri statusUri = buildSourceUri(context.getPackageName());
- contentResolver.insert(statusUri, values);
- }
-
- /**
- * A helper method to set the quota of a voicemail source. Unit is unspecified.
- *
- * @param context The context from the package calling the method. This will be the source.
- * @param accountHandle The handle for the account the source is associated with.
- * @param occupied See {@link Status#QUOTA_OCCUPIED}
- * @param total See {@link Status#QUOTA_TOTAL}
- *
- * @hide
- */
- public static void setQuota(Context context, PhoneAccountHandle accountHandle, int occupied,
- int total) {
- if (occupied == QUOTA_UNAVAILABLE && total == QUOTA_UNAVAILABLE) {
- return;
- }
- ContentValues values = new ContentValues();
- values.put(Status.PHONE_ACCOUNT_COMPONENT_NAME,
- accountHandle.getComponentName().flattenToString());
- values.put(Status.PHONE_ACCOUNT_ID, accountHandle.getId());
- if (occupied != QUOTA_UNAVAILABLE) {
- values.put(Status.QUOTA_OCCUPIED,occupied);
- }
- if (total != QUOTA_UNAVAILABLE) {
- values.put(Status.QUOTA_TOTAL,total);
- }
-
- ContentResolver contentResolver = context.getContentResolver();
- Uri statusUri = buildSourceUri(context.getPackageName());
- contentResolver.insert(statusUri, values);
- }
}
}
diff --git a/core/java/android/service/voice/VoiceInteractionServiceInfo.java b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
index a9db32b..e1a9a05 100644
--- a/core/java/android/service/voice/VoiceInteractionServiceInfo.java
+++ b/core/java/android/service/voice/VoiceInteractionServiceInfo.java
@@ -61,7 +61,11 @@
throws PackageManager.NameNotFoundException {
try {
ServiceInfo si = AppGlobals.getPackageManager().getServiceInfo(comp,
- PackageManager.GET_META_DATA, userHandle);
+ PackageManager.GET_META_DATA
+ | PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_DEBUG_TRIAGED_MISSING,
+ userHandle);
if (si != null) {
return si;
}
diff --git a/core/java/android/util/KeyValueListParser.java b/core/java/android/util/KeyValueListParser.java
index 4abdde0..e4c025d 100644
--- a/core/java/android/util/KeyValueListParser.java
+++ b/core/java/android/util/KeyValueListParser.java
@@ -63,6 +63,24 @@
}
/**
+ * Get the value for key as an int.
+ * @param key The key to lookup.
+ * @param def The value to return if the key was not found, or the value was not a long.
+ * @return the int value associated with the key.
+ */
+ public int getInt(String key, int def) {
+ String value = mValues.get(key);
+ if (value != null) {
+ try {
+ return Integer.parseInt(value);
+ } catch (NumberFormatException e) {
+ // fallthrough
+ }
+ }
+ return def;
+ }
+
+ /**
* Get the value for key as a long.
* @param key The key to lookup.
* @param def The value to return if the key was not found, or the value was not a long.
diff --git a/core/java/android/util/jar/StrictJarVerifier.java b/core/java/android/util/jar/StrictJarVerifier.java
index 6da50ba..cb71ecc 100644
--- a/core/java/android/util/jar/StrictJarVerifier.java
+++ b/core/java/android/util/jar/StrictJarVerifier.java
@@ -30,6 +30,7 @@
import java.util.HashMap;
import java.util.Hashtable;
import java.util.Iterator;
+import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
@@ -41,6 +42,7 @@
import libcore.io.Base64;
import sun.security.jca.Providers;
import sun.security.pkcs.PKCS7;
+import sun.security.pkcs.SignerInfo;
/**
* Non-public class used by {@link JarFile} and {@link JarInputStream} to manage
@@ -308,18 +310,29 @@
obj = Providers.startJarVerification();
PKCS7 block = new PKCS7(blockBytes);
- if (block.verify(sfBytes) == null) {
- throw new GeneralSecurityException("Failed to verify signature");
+ SignerInfo[] verifiedSignerInfos = block.verify(sfBytes);
+ if ((verifiedSignerInfos == null) || (verifiedSignerInfos.length == 0)) {
+ throw new GeneralSecurityException(
+ "Failed to verify signature: no verified SignerInfos");
}
- X509Certificate[] blockCerts = block.getCertificates();
- Certificate[] signerCertChain = null;
- if (blockCerts != null) {
- signerCertChain = new Certificate[blockCerts.length];
- for (int i = 0; i < blockCerts.length; ++i) {
- signerCertChain[i] = blockCerts[i];
- }
+ // Ignore any SignerInfo other than the first one, to be compatible with older Android
+ // platforms which have been doing this for years. See
+ // libcore/luni/src/main/java/org/apache/harmony/security/utils/JarUtils.java
+ // verifySignature method of older platforms.
+ SignerInfo verifiedSignerInfo = verifiedSignerInfos[0];
+ List<X509Certificate> verifiedSignerCertChain =
+ verifiedSignerInfo.getCertificateChain(block);
+ if (verifiedSignerCertChain == null) {
+ // Should never happen
+ throw new GeneralSecurityException(
+ "Failed to find verified SignerInfo certificate chain");
+ } else if (verifiedSignerCertChain.isEmpty()) {
+ // Should never happen
+ throw new GeneralSecurityException(
+ "Verified SignerInfo certificate chain is emtpy");
}
- return signerCertChain;
+ return verifiedSignerCertChain.toArray(
+ new X509Certificate[verifiedSignerCertChain.size()]);
} catch (IOException e) {
throw new GeneralSecurityException("IO exception verifying jar cert", e);
} finally {
diff --git a/core/java/android/view/ViewRootImpl.java b/core/java/android/view/ViewRootImpl.java
index 0d648c1..4742818 100644
--- a/core/java/android/view/ViewRootImpl.java
+++ b/core/java/android/view/ViewRootImpl.java
@@ -3078,16 +3078,22 @@
// best is probably just to leave things as-is.
if (DEBUG_INPUT_RESIZE) Log.v(mTag,
"Too tall; leaving scrollY=" + scrollY);
- } else if ((mTempRect.top-scrollY) < vi.top) {
- scrollY -= vi.top - (mTempRect.top-scrollY);
+ }
+ // Next, check whether top or bottom is covered based on the non-scrolled
+ // position, and calculate new scrollY (or set it to 0).
+ // We can't keep using mScrollY here. For example mScrollY is non-zero
+ // due to IME, then IME goes away. The current value of mScrollY leaves top
+ // and bottom both visible, but we still need to scroll it back to 0.
+ else if (mTempRect.top < vi.top) {
+ scrollY = mTempRect.top - vi.top;
if (DEBUG_INPUT_RESIZE) Log.v(mTag,
"Top covered; scrollY=" + scrollY);
- } else if ((mTempRect.bottom-scrollY)
- > (mView.getHeight()-vi.bottom)) {
- scrollY += (mTempRect.bottom-scrollY)
- - (mView.getHeight()-vi.bottom);
+ } else if (mTempRect.bottom > (mView.getHeight()-vi.bottom)) {
+ scrollY = mTempRect.bottom - (mView.getHeight()-vi.bottom);
if (DEBUG_INPUT_RESIZE) Log.v(mTag,
"Bottom covered; scrollY=" + scrollY);
+ } else {
+ scrollY = 0;
}
handled = true;
}
diff --git a/core/java/com/android/internal/app/WindowDecorActionBar.java b/core/java/com/android/internal/app/WindowDecorActionBar.java
index a09dbe5..1376d0a 100644
--- a/core/java/com/android/internal/app/WindowDecorActionBar.java
+++ b/core/java/com/android/internal/app/WindowDecorActionBar.java
@@ -873,24 +873,40 @@
hideForActionMode();
}
- Animator fadeIn, fadeOut;
- if (toActionMode) {
- fadeOut = mDecorToolbar.setupAnimatorToVisibility(View.GONE,
- FADE_OUT_DURATION_MS);
- fadeIn = mContextView.setupAnimatorToVisibility(View.VISIBLE,
- FADE_IN_DURATION_MS);
+ if (shouldAnimateContextView()) {
+ Animator fadeIn, fadeOut;
+ if (toActionMode) {
+ fadeOut = mDecorToolbar.setupAnimatorToVisibility(View.GONE,
+ FADE_OUT_DURATION_MS);
+ fadeIn = mContextView.setupAnimatorToVisibility(View.VISIBLE,
+ FADE_IN_DURATION_MS);
+ } else {
+ fadeIn = mDecorToolbar.setupAnimatorToVisibility(View.VISIBLE,
+ FADE_IN_DURATION_MS);
+ fadeOut = mContextView.setupAnimatorToVisibility(View.GONE,
+ FADE_OUT_DURATION_MS);
+ }
+ AnimatorSet set = new AnimatorSet();
+ set.playSequentially(fadeOut, fadeIn);
+ set.start();
} else {
- fadeIn = mDecorToolbar.setupAnimatorToVisibility(View.VISIBLE,
- FADE_IN_DURATION_MS);
- fadeOut = mContextView.setupAnimatorToVisibility(View.GONE,
- FADE_OUT_DURATION_MS);
+ if (toActionMode) {
+ mDecorToolbar.setVisibility(View.GONE);
+ mContextView.setVisibility(View.VISIBLE);
+ } else {
+ mDecorToolbar.setVisibility(View.VISIBLE);
+ mContextView.setVisibility(View.GONE);
+ }
}
- AnimatorSet set = new AnimatorSet();
- set.playSequentially(fadeOut, fadeIn);
- set.start();
// mTabScrollView's visibility is not affected by action mode.
}
+ private boolean shouldAnimateContextView() {
+ // We only to animate the action mode in if the container view has already been laid out.
+ // If it hasn't been laid out, it hasn't been drawn to screen yet.
+ return mContainerView.isLaidOut();
+ }
+
public Context getThemedContext() {
if (mThemedContext == null) {
TypedValue outValue = new TypedValue();
diff --git a/core/java/com/android/internal/os/InstallerConnection.java b/core/java/com/android/internal/os/InstallerConnection.java
index a7a3cb5..419c3d8 100644
--- a/core/java/com/android/internal/os/InstallerConnection.java
+++ b/core/java/com/android/internal/os/InstallerConnection.java
@@ -157,9 +157,7 @@
sharedLibraries);
}
- public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
- final String[] res = execute("merge_profiles", uid, pkgName);
-
+ private boolean safeParseBooleanResult(String[] res) throws InstallerException {
if ((res == null) || (res.length != 2)) {
throw new InstallerException("Invalid size result: " + Arrays.toString(res));
}
@@ -172,6 +170,19 @@
return Boolean.parseBoolean(res[1]);
}
+ public boolean mergeProfiles(int uid, String pkgName) throws InstallerException {
+ final String[] res = execute("merge_profiles", uid, pkgName);
+
+ return safeParseBooleanResult(res);
+ }
+
+ public boolean dumpProfiles(String gid, String packageName, String codePaths)
+ throws InstallerException {
+ final String[] res = execute("dump_profiles", gid, packageName, codePaths);
+
+ return safeParseBooleanResult(res);
+ }
+
private boolean connect() {
if (mSocket != null) {
return true;
diff --git a/core/java/com/android/internal/policy/DecorView.java b/core/java/com/android/internal/policy/DecorView.java
index a065219..7e38d9b 100644
--- a/core/java/com/android/internal/policy/DecorView.java
+++ b/core/java/com/android/internal/policy/DecorView.java
@@ -32,6 +32,7 @@
import java.util.List;
import android.animation.Animator;
+import android.animation.AnimatorListenerAdapter;
import android.animation.ObjectAnimator;
import android.app.ActivityManager;
import android.content.Context;
@@ -1588,31 +1589,27 @@
mPrimaryActionModeView.getApplicationWindowToken(),
Gravity.TOP | Gravity.FILL_HORIZONTAL, 0, 0);
endOnGoingFadeAnimation();
- mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA,
- 0f, 1f);
- mFadeAnim.addListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- mPrimaryActionModeView.setVisibility(VISIBLE);
- }
- @Override
- public void onAnimationEnd(Animator animation) {
- mPrimaryActionModeView.setAlpha(1f);
- mFadeAnim = null;
- }
+ if (shouldAnimatePrimaryActionModeView()) {
+ mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA,
+ 0f, 1f);
+ mFadeAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mPrimaryActionModeView.setVisibility(VISIBLE);
+ }
- @Override
- public void onAnimationCancel(Animator animation) {
-
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
-
- }
- });
- mFadeAnim.start();
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPrimaryActionModeView.setAlpha(1f);
+ mFadeAnim = null;
+ }
+ });
+ mFadeAnim.start();
+ } else {
+ mPrimaryActionModeView.setAlpha(1f);
+ mPrimaryActionModeView.setVisibility(VISIBLE);
+ }
}
};
} else {
@@ -1646,35 +1643,36 @@
if (mPrimaryActionModePopup != null) {
post(mShowPrimaryActionModePopup);
} else {
- mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA, 0f, 1f);
- mFadeAnim.addListener(new Animator.AnimatorListener() {
- @Override
- public void onAnimationStart(Animator animation) {
- mPrimaryActionModeView.setVisibility(View.VISIBLE);
- }
+ if (shouldAnimatePrimaryActionModeView()) {
+ mFadeAnim = ObjectAnimator.ofFloat(mPrimaryActionModeView, View.ALPHA, 0f, 1f);
+ mFadeAnim.addListener(new AnimatorListenerAdapter() {
+ @Override
+ public void onAnimationStart(Animator animation) {
+ mPrimaryActionModeView.setVisibility(View.VISIBLE);
+ }
- @Override
- public void onAnimationEnd(Animator animation) {
- mPrimaryActionModeView.setAlpha(1f);
- mFadeAnim = null;
- }
-
- @Override
- public void onAnimationCancel(Animator animation) {
-
- }
-
- @Override
- public void onAnimationRepeat(Animator animation) {
-
- }
- });
- mFadeAnim.start();
+ @Override
+ public void onAnimationEnd(Animator animation) {
+ mPrimaryActionModeView.setAlpha(1f);
+ mFadeAnim = null;
+ }
+ });
+ mFadeAnim.start();
+ } else {
+ mPrimaryActionModeView.setAlpha(1f);
+ mPrimaryActionModeView.setVisibility(View.VISIBLE);
+ }
}
mPrimaryActionModeView.sendAccessibilityEvent(
AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED);
}
+ boolean shouldAnimatePrimaryActionModeView() {
+ // We only to animate the action mode in if the decor has already been laid out.
+ // If it hasn't been laid out, it hasn't been drawn to screen yet.
+ return isLaidOut();
+ }
+
private ActionMode createFloatingActionMode(
View originatingView, ActionMode.Callback2 callback) {
if (mFloatingActionMode != null) {
diff --git a/core/java/com/android/internal/util/FastPrintWriter.java b/core/java/com/android/internal/util/FastPrintWriter.java
index c74fea0..e46e6b0 100644
--- a/core/java/com/android/internal/util/FastPrintWriter.java
+++ b/core/java/com/android/internal/util/FastPrintWriter.java
@@ -1,5 +1,6 @@
package com.android.internal.util;
+import android.util.Log;
import android.util.Printer;
import java.io.IOException;
@@ -328,11 +329,13 @@
}
private void flushBytesLocked() throws IOException {
- int position;
- if ((position = mBytes.position()) > 0) {
- mBytes.flip();
- mOutputStream.write(mBytes.array(), 0, position);
- mBytes.clear();
+ if (!mIoError) {
+ int position;
+ if ((position = mBytes.position()) > 0) {
+ mBytes.flip();
+ mOutputStream.write(mBytes.array(), 0, position);
+ mBytes.clear();
+ }
}
}
@@ -352,11 +355,15 @@
}
break;
}
- flushBytesLocked();
- mOutputStream.flush();
+ if (!mIoError) {
+ flushBytesLocked();
+ mOutputStream.flush();
+ }
} else if (mWriter != null) {
- mWriter.write(mText, 0, mPos);
- mWriter.flush();
+ if (!mIoError) {
+ mWriter.write(mText, 0, mPos);
+ mWriter.flush();
+ }
} else {
int nonEolOff = 0;
final int sepLen = mSeparator.length();
@@ -385,12 +392,15 @@
synchronized (lock) {
try {
flushLocked();
- if (mOutputStream != null) {
- mOutputStream.flush();
- } else if (mWriter != null) {
- mWriter.flush();
+ if (!mIoError) {
+ if (mOutputStream != null) {
+ mOutputStream.flush();
+ } else if (mWriter != null) {
+ mWriter.flush();
+ }
}
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
setError();
}
}
@@ -407,6 +417,7 @@
mWriter.close();
}
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
setError();
}
}
@@ -425,6 +436,8 @@
try {
appendLocked(charArray, 0, charArray.length);
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
+ setError();
}
}
}
@@ -442,6 +455,8 @@
try {
appendLocked(ch);
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
+ setError();
}
}
}
@@ -465,6 +480,7 @@
try {
appendLocked(str, 0, str.length());
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
setError();
}
}
@@ -500,6 +516,7 @@
flushLocked();
}
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
setError();
}
}
@@ -564,6 +581,8 @@
try {
appendLocked(buf, offset, count);
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
+ setError();
}
}
}
@@ -584,6 +603,8 @@
try {
appendLocked((char) oneChar);
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
+ setError();
}
}
}
@@ -600,6 +621,8 @@
try {
appendLocked(str, 0, str.length());
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
+ setError();
}
}
}
@@ -624,6 +647,8 @@
try {
appendLocked(str, offset, count);
} catch (IOException e) {
+ Log.w("FastPrintWriter", "Write failure", e);
+ setError();
}
}
}
diff --git a/core/res/res/layout/app_error_dialog.xml b/core/res/res/layout/app_error_dialog.xml
index 9a5bbd4..d78ce59 100644
--- a/core/res/res/layout/app_error_dialog.xml
+++ b/core/res/res/layout/app_error_dialog.xml
@@ -38,7 +38,7 @@
android:id="@+id/aerr_close"
android:layout_width="match_parent"
android:layout_height="wrap_content"
- android:text="@string/aerr_close"
+ android:text="@string/aerr_close_app"
android:drawableStart="@drawable/ic_close"
style="@style/aerr_list_item"
/>
diff --git a/core/res/res/values-af/strings.xml b/core/res/res/values-af/strings.xml
index 9fbba38..f8d6aee 100644
--- a/core/res/res/values-af/strings.xml
+++ b/core/res/res/values-af/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">oor <xliff:g id="COUNT_1">%d</xliff:g> j.</item>
<item quantity="one">oor <xliff:g id="COUNT_0">%d</xliff:g> j.</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minute gelede</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minuut gelede</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> uur gelede</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> uur gelede</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dae gelede</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> dag gelede</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> jaar gelede</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> jaar gelede</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">oor <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="one">oor <xliff:g id="COUNT_0">%d</xliff:g> minuut</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">oor <xliff:g id="COUNT_1">%d</xliff:g> uur</item>
+ <item quantity="one">oor <xliff:g id="COUNT_0">%d</xliff:g> uur</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">oor <xliff:g id="COUNT_1">%d</xliff:g> dae</item>
+ <item quantity="one">oor <xliff:g id="COUNT_0">%d</xliff:g> dag</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">oor <xliff:g id="COUNT_1">%d</xliff:g> jaar</item>
+ <item quantity="one">oor <xliff:g id="COUNT_0">%d</xliff:g> jaar</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Videoprobleem"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Hierdie video is nie geldig vir stroming na hierdie toestel nie."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Kan nie hierdie video speel nie."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> het gestop"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> stop aanhoudend"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> stop aanhoudend"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Herbegin program"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Stel terug en herbegin program"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Maak program weer oop"</string>
<string name="aerr_report" msgid="5371800241488400617">"Stuur terugvoer"</string>
<string name="aerr_close" msgid="2991640326563991340">"Maak toe"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Demp totdat toestel herbegin"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> uitgevee"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Werk-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Raak en hou Terug om hierdie skerm te ontspeld."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Raak en hou Oorsig om hierdie skerm te ontspeld."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Program is vasgespeld: Dit mag nie op hierdie toestel ontspeld word nie."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skerm vasgespeld"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Skerm ontspeld"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-versoek is gewysig tot USSD-versoek."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-versoek is gewysig tot nuwe SS-versoek."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Werkprofiel"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Uitvou-knoppie"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android-USB-randpoort"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB-randpoort"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Ontspeld"</string>
<string name="app_info" msgid="6856026610594615344">"Programinligting"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Herbegin sessie"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Tik om \'n nuwe demonstrasiesessie te begin"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Doen \'n fabriekterugstelling om hierdie toestel sonder beperkinge te gebruik"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Raak om meer te wete te kom."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Het <xliff:g id="LABEL">%1$s</xliff:g> gedeaktiveer"</string>
</resources>
diff --git a/core/res/res/values-am/strings.xml b/core/res/res/values-am/strings.xml
index 4bab99e..389ce59 100644
--- a/core/res/res/values-am/strings.xml
+++ b/core/res/res/values-am/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one">በ<xliff:g id="COUNT_1">%d</xliff:g> ዓ ውስጥ</item>
<item quantity="other">በ<xliff:g id="COUNT_1">%d</xliff:g> ዓ ውስጥ</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">ከ<xliff:g id="COUNT_1">%d</xliff:g> ደቂቃዎች በፊት</item>
+ <item quantity="other">ከ<xliff:g id="COUNT_1">%d</xliff:g> ደቂቃዎች በፊት</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">ከ<xliff:g id="COUNT_1">%d</xliff:g> ሰዓቶች በፊት</item>
+ <item quantity="other">ከ<xliff:g id="COUNT_1">%d</xliff:g> ሰዓቶች በፊት</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">ከ<xliff:g id="COUNT_1">%d</xliff:g> ቀኖች በፊት</item>
+ <item quantity="other">ከ<xliff:g id="COUNT_1">%d</xliff:g> ቀኖች በፊት</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">ከ<xliff:g id="COUNT_1">%d</xliff:g> ዓመቶች በፊት</item>
+ <item quantity="other">ከ<xliff:g id="COUNT_1">%d</xliff:g> ዓመቶች በፊት</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">በ<xliff:g id="COUNT_1">%d</xliff:g> ደቂቃዎች ውስጥ</item>
+ <item quantity="other">በ<xliff:g id="COUNT_1">%d</xliff:g> ደቂቃዎች ውስጥ</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">በ<xliff:g id="COUNT_1">%d</xliff:g> ሰዓቶች ውስጥ</item>
+ <item quantity="other">በ<xliff:g id="COUNT_1">%d</xliff:g> ሰዓቶች ውስጥ</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">በ<xliff:g id="COUNT_1">%d</xliff:g> ቀኖች ውስጥ</item>
+ <item quantity="other">በ<xliff:g id="COUNT_1">%d</xliff:g> ቀኖች ውስጥ</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">በ<xliff:g id="COUNT_1">%d</xliff:g> ዓመቶች ውስጥ</item>
+ <item quantity="other">በ<xliff:g id="COUNT_1">%d</xliff:g> ዓመቶች ውስጥ</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"የቪዲዮ ችግር"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ይቅርታ፣ ይህ ቪዲዮ በዚህ መሣሪያ ለመልቀቅ ትክክል አይደለም።"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ይሄን ቪዲዮ ማጫወት አልተቻለም።"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> ቆሟል"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> አሁንም እያቆመ ነው"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> አሁንም እያቆመ ነው"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"መተግበሪያውን ዳግም አስጀምር"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"ዳግም ያቀናብሩ እና መተግበሪያ ዳግም ያስጀምሩት"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"መተግበሪያውን እንደገና ክፈት"</string>
<string name="aerr_report" msgid="5371800241488400617">"ግብረመልስ ይላኩ"</string>
<string name="aerr_close" msgid="2991640326563991340">"ዝጋ"</string>
<string name="aerr_mute" msgid="1974781923723235953">"መሣሪያ ዳግም እስኪጀመር ድረስ ድምጽ ያጥፉ"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ተሰርዟል"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ስራ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ይህን ማያ ገጽ ለመንቀል ተመለስን ይንኩትና ያዙት።"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ይህን ማያ ገጽ ለመንቀል አጠቃላይ እይታን ይንኩትና ይያዙት።"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"መተግበሪያ ተሰክቷል፦ በዚህ መሣሪያ ላይ ማላቀቅ አይፈቀድም።"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ማያ ገጽ ተሰክቷል"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"ማያ ገጽ ተነቅሏል"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ጥያቄ ወደ USSD ጥያቄ ተሻሽሎዋል።"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ጥያቄ ወደ አዲስ SS ጥያቄ ተሻሽሎዋል።"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"የስራ መገለጫ"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"የዘርጋ አዝራር"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"የAndroid USB Peripheral ወደብ"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral ወደብ"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"ንቀል"</string>
<string name="app_info" msgid="6856026610594615344">"የመተግበሪያ መረጃ"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"ክፍለ-ጊዜን ዳግም ያስጀምሩ"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"አዲስ የማሳያ ክፍለ-ጊዜን ለመጀመር መታ ያድርጉ"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"ይህን መሣሪያ ያለምንም ገደብ ለመጠቀም የፋብሪካ ዳግም ያስጀምሩ"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"የበለጠ ለመረዳት ይንኩ።"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ተሰናክሏል"</string>
</resources>
diff --git a/core/res/res/values-ar/strings.xml b/core/res/res/values-ar/strings.xml
index b797006..cabb6a2 100644
--- a/core/res/res/values-ar/strings.xml
+++ b/core/res/res/values-ar/strings.xml
@@ -951,6 +951,70 @@
<item quantity="other">في <xliff:g id="COUNT_1">%d</xliff:g> عام</item>
<item quantity="one">في <xliff:g id="COUNT_0">%d</xliff:g> عام</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="zero">قبل <xliff:g id="COUNT_1">%d</xliff:g> دقيقة</item>
+ <item quantity="two">قبل دقيقتين (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="few">قبل <xliff:g id="COUNT_1">%d</xliff:g> دقائق</item>
+ <item quantity="many">قبل <xliff:g id="COUNT_1">%d</xliff:g> دقيقة</item>
+ <item quantity="other">قبل <xliff:g id="COUNT_1">%d</xliff:g> دقيقة</item>
+ <item quantity="one">قبل <xliff:g id="COUNT_0">%d</xliff:g> دقيقة</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="zero">قبل <xliff:g id="COUNT_1">%d</xliff:g> ساعة</item>
+ <item quantity="two">قبل ساعتين (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="few">قبل <xliff:g id="COUNT_1">%d</xliff:g> ساعات</item>
+ <item quantity="many">قبل <xliff:g id="COUNT_1">%d</xliff:g> ساعة</item>
+ <item quantity="other">قبل <xliff:g id="COUNT_1">%d</xliff:g> ساعة</item>
+ <item quantity="one">قبل <xliff:g id="COUNT_0">%d</xliff:g> ساعة</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="zero">قبل <xliff:g id="COUNT_1">%d</xliff:g> يوم</item>
+ <item quantity="two">قبل يومين (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="few">قبل <xliff:g id="COUNT_1">%d</xliff:g> أيام</item>
+ <item quantity="many">قبل <xliff:g id="COUNT_1">%d</xliff:g> يومًا</item>
+ <item quantity="other">قبل <xliff:g id="COUNT_1">%d</xliff:g> يوم</item>
+ <item quantity="one">قبل <xliff:g id="COUNT_0">%d</xliff:g> يوم</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="zero">قبل <xliff:g id="COUNT_1">%d</xliff:g> سنة</item>
+ <item quantity="two">قبل سنتين (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="few">قبل <xliff:g id="COUNT_1">%d</xliff:g> سنوات</item>
+ <item quantity="many">قبل <xliff:g id="COUNT_1">%d</xliff:g> سنة</item>
+ <item quantity="other">قبل <xliff:g id="COUNT_1">%d</xliff:g> سنة</item>
+ <item quantity="one">قبل <xliff:g id="COUNT_0">%d</xliff:g> سنة</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="zero">خلال <xliff:g id="COUNT_1">%d</xliff:g> دقيقة</item>
+ <item quantity="two">خلال دقيقتين (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="few">خلال <xliff:g id="COUNT_1">%d</xliff:g> دقائق</item>
+ <item quantity="many">خلال <xliff:g id="COUNT_1">%d</xliff:g> دقيقة</item>
+ <item quantity="other">خلال <xliff:g id="COUNT_1">%d</xliff:g> دقيقة</item>
+ <item quantity="one">خلال <xliff:g id="COUNT_0">%d</xliff:g> دقيقة</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="zero">خلال <xliff:g id="COUNT_1">%d</xliff:g> ساعة</item>
+ <item quantity="two">خلال ساعتين (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="few">خلال <xliff:g id="COUNT_1">%d</xliff:g> ساعات</item>
+ <item quantity="many">خلال <xliff:g id="COUNT_1">%d</xliff:g> ساعة</item>
+ <item quantity="other">خلال <xliff:g id="COUNT_1">%d</xliff:g> ساعة</item>
+ <item quantity="one">خلال <xliff:g id="COUNT_0">%d</xliff:g> ساعة</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="zero">خلال <xliff:g id="COUNT_1">%d</xliff:g> يوم</item>
+ <item quantity="two">خلال يومين (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="few">خلال <xliff:g id="COUNT_1">%d</xliff:g> أيام</item>
+ <item quantity="many">خلال <xliff:g id="COUNT_1">%d</xliff:g> يومًا</item>
+ <item quantity="other">خلال <xliff:g id="COUNT_1">%d</xliff:g> يوم</item>
+ <item quantity="one">خلال <xliff:g id="COUNT_0">%d</xliff:g> يوم</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="zero">خلال <xliff:g id="COUNT_1">%d</xliff:g> سنة</item>
+ <item quantity="two">خلال سنتين (<xliff:g id="COUNT_1">%d</xliff:g>)</item>
+ <item quantity="few">خلال <xliff:g id="COUNT_1">%d</xliff:g> سنوات</item>
+ <item quantity="many">خلال <xliff:g id="COUNT_1">%d</xliff:g> سنة</item>
+ <item quantity="other">خلال <xliff:g id="COUNT_1">%d</xliff:g> سنة</item>
+ <item quantity="one">خلال <xliff:g id="COUNT_0">%d</xliff:g> سنة</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"مشكلة في الفيديو"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"عذرًا، هذا الفيديو غير صالح للبث على هذا الجهاز."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"لا يمكنك تشغيل هذا الفيديو."</string>
@@ -1022,8 +1086,7 @@
<string name="aerr_process" msgid="6201597323218674729">"توقفت <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"يستمر التطبيق <xliff:g id="APPLICATION">%1$s</xliff:g> في التوقف."</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"تستمر عملية <xliff:g id="PROCESS">%1$s</xliff:g> في التوقف."</string>
- <string name="aerr_restart" msgid="9001379185665886595">"إعادة تشغيل التطبيق"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"إعادة ضبط التطبيق وإعادة تشغيله"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"فتح التطبيق مرة أخرى"</string>
<string name="aerr_report" msgid="5371800241488400617">"إرسال تعليقات"</string>
<string name="aerr_close" msgid="2991640326563991340">"إغلاق"</string>
<string name="aerr_mute" msgid="1974781923723235953">"التعطيل حتى إعادة تشغيل الجهاز"</string>
@@ -1588,7 +1651,6 @@
<string name="deleted_key" msgid="7659477886625566590">"تم حذف <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> المخصص للعمل"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"لإزالة تثبيت هذه الشاشة، يمكنك لمس زر الرجوع مع الاستمرار."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"لإزالة تثبيت هذه الشاشة، يمكنك لمس زر \"نظرة عامة\" مع الاستمرار."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"التطبيق مقيد: ولا يسمح بإلغاء التقييد على هذا الجهاز."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"تم تثبيت الشاشة"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"تم إلغاء تثبيت الشاشة"</string>
@@ -1687,6 +1749,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"يتم تعديل طلب SS إلى طلب USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"يتم تعديل طلب SS إلى طلب SS الجديد."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"الملف الشخصي للعمل"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"زر \"توسيع\""</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"منفذ الأجهزة الطرفية المزودة بكابل USB ونظام التشغيل Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"منفذ الأجهزة الطرفية المزودة بكابل USB"</string>
@@ -1728,8 +1793,9 @@
<string name="unpin_target" msgid="3556545602439143442">"إزالة تثبيت"</string>
<string name="app_info" msgid="6856026610594615344">"معلومات عن التطبيق"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"إعادة تشغيل الجلسة"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"انقر لبدء جلسة عرض توضيحي جديدة"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"يمكنك إعادة تعيين بيانات المصنع لاستخدام هذا الجهاز بدون قيود"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"المس للتعرف على مزيد من المعلومات."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"تم تعطيل <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-az-rAZ/strings.xml b/core/res/res/values-az-rAZ/strings.xml
index 61f4bf4..a41713d 100644
--- a/core/res/res/values-az-rAZ/strings.xml
+++ b/core/res/res/values-az-rAZ/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>ildə</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>ildə</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dəqiqə əvvəl</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> dəqiqə əvvəl</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> saat əvvəl</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> saat əvvəl</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> gün əvvəl</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> gün əvvəl</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> il əvvəl</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> il əvvəl</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dəqiqəyə</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> dəqiqəyə</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> saata</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> saata</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> günə</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> günə</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ilə</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ilə</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Video problemi"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Bu video bu cihaza strim olunmaq üçün uyğun deyil."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Bu video oxumur"</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> dayandı"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> dayandırılması davam edir"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> dayandırılması davam edir"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Tətbiqi yenidən başladın"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Tətbiqi sıfırlayın və yenidən başladın"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Geri əlaqə göndərin"</string>
<string name="aerr_close" msgid="2991640326563991340">"Bağla"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Cihaz yeniden başladılana kimi səssiz edin"</string>
@@ -1512,7 +1544,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> silindi"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"İş <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Sancağı götürmək üçün Geri düyməsinə toxunun və saxlayın."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Sancağı götürmək üçün İcmala toxunun və saxlayın."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Tətbiq sancılıb: Açmağa bu cihazda icazə verilmir."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Screen unpinned"</string>
@@ -1579,6 +1610,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS sorğusu USSD sorğusuna dəyişdirildi."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS sorğusu yeni SS sorğusuna dəyişdirildi."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"İş profili"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
@@ -1616,8 +1651,11 @@
<string name="unpin_target" msgid="3556545602439143442">"Çıxarın"</string>
<string name="app_info" msgid="6856026610594615344">"Tətbiq məlumatı"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Bu cihazı məhdudiyyətsiz istifadə etmək üçün zavod sıfırlaması edin"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Daha çox məlumat üçün toxunun."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> deaktiv edildi"</string>
</resources>
diff --git a/core/res/res/values-bg/strings.xml b/core/res/res/values-bg/strings.xml
index 06329bc..cb5a89d 100644
--- a/core/res/res/values-bg/strings.xml
+++ b/core/res/res/values-bg/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">след <xliff:g id="COUNT_1">%d</xliff:g> г</item>
<item quantity="one">след <xliff:g id="COUNT_0">%d</xliff:g> г</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">преди <xliff:g id="COUNT_1">%d</xliff:g> минути</item>
+ <item quantity="one">преди <xliff:g id="COUNT_0">%d</xliff:g> минута</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">преди <xliff:g id="COUNT_1">%d</xliff:g> часа</item>
+ <item quantity="one">преди <xliff:g id="COUNT_0">%d</xliff:g> час</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">преди <xliff:g id="COUNT_1">%d</xliff:g> дни</item>
+ <item quantity="one">преди <xliff:g id="COUNT_0">%d</xliff:g> ден</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">преди <xliff:g id="COUNT_1">%d</xliff:g> години</item>
+ <item quantity="one">преди <xliff:g id="COUNT_0">%d</xliff:g> година</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">след <xliff:g id="COUNT_1">%d</xliff:g> минути</item>
+ <item quantity="one">след <xliff:g id="COUNT_0">%d</xliff:g> минута</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">след <xliff:g id="COUNT_1">%d</xliff:g> часа</item>
+ <item quantity="one">след <xliff:g id="COUNT_0">%d</xliff:g> час</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">след <xliff:g id="COUNT_1">%d</xliff:g> дни</item>
+ <item quantity="one">след <xliff:g id="COUNT_0">%d</xliff:g> ден</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">след <xliff:g id="COUNT_1">%d</xliff:g> години</item>
+ <item quantity="one">след <xliff:g id="COUNT_0">%d</xliff:g> година</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Проблем с видеоклипа"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Този видеоклип не е валиден за поточно предаване към това устройство."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Този видеоклип не може да се пусне."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> спря"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> спира многократно"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> спира многократно"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Рестартиране на приложението"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Нулиране и рестартиране на приложението"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Повторно отваряне на приложението"</string>
<string name="aerr_report" msgid="5371800241488400617">"Изпращане на отзиви"</string>
<string name="aerr_close" msgid="2991640326563991340">"Затваряне"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Спиране, докато устройството се рестартира"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Изтрихте <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> за работа"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"За да освободите този екран, докоснете и задръжте бутона за връщане назад."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"За да освободите този екран, докоснете и задръжте бутона за общ преглед."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Приложението е фиксирано. Освобождаването му не е разрешено на това устройство."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Екранът е фиксиран"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Екранът е освободен"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS заявката е променена на USSD заявка."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS заявката е променена на нова SS заявка."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Служебен потребителски профил"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Бутон за разгъване"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Периферен USB порт под Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Периферен USB порт"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Освобождаване"</string>
<string name="app_info" msgid="6856026610594615344">"Информация за приложението"</string>
<string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Рестартиране на сесията"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Докоснете, за да стартирате нова демонстрационна сесия"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Възстановете фабричните настройки на това устройство, за да го използвате без ограничения"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Докоснете, за да научите повече."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g>: Деактивирано"</string>
</resources>
diff --git a/core/res/res/values-bn-rBD/strings.xml b/core/res/res/values-bn-rBD/strings.xml
index 2916d95..0ebea16 100644
--- a/core/res/res/values-bn-rBD/strings.xml
+++ b/core/res/res/values-bn-rBD/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>বছরের মধ্যে</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>বছরের মধ্যে</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>মিনিট আগে</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>মিনিট আগে</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ঘণ্টা আগে</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ঘণ্টা আগে</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> দিন আগে</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> দিন আগে</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> বছর আগে</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> বছর আগে</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one"> <xliff:g id="COUNT_1">%d</xliff:g> মিনিটের মধ্যে</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%d</xliff:g> মিনিটের মধ্যে</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ঘন্টার মধ্যে</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ঘন্টার মধ্যে</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> দিনের মধ্যে</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> দিনের মধ্যে</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one"> <xliff:g id="COUNT_1">%d</xliff:g> বছরের মধ্যে</item>
+ <item quantity="other"> <xliff:g id="COUNT_1">%d</xliff:g> বছরের মধ্যে</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"ভিডিও সমস্যা"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"এই ভিডিওটি এই ডিভাইসে স্ট্রিমিং করার জন্য বৈধ নয়৷"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"এই ভিডিওটি চালানো যাবে না৷"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> বন্ধ হয়েছে"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> বারবার বন্ধ হচ্ছে"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> বারবার বন্ধ হচ্ছে"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"অ্যাপ্লিকেশান পুনরায় আরম্ভ করুন"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"পুনরায় সেট করুন এবং অ্যাপ্লিকেশান পুনরায় আরম্ভ করুন"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"অ্যাপ্লিকেশানটিকে আবার খুলুন"</string>
<string name="aerr_report" msgid="5371800241488400617">"প্রতিক্রিয়া পাঠান"</string>
<string name="aerr_close" msgid="2991640326563991340">"বন্ধ করুন"</string>
<string name="aerr_mute" msgid="1974781923723235953">"ডিভাইসটি পুনরায় আরম্ভ না হওয়া পর্যন্ত নিঃশব্দ করুন"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> মুছে ফেলা হয়েছে"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"কর্মক্ষেত্র <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"এই স্ক্রীনটিকে আনপিন করতে, \'ফিরুন\' স্পর্শ করুন এবং ধরে রাখুন৷"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"এই স্ক্রীনটিকে আনপিন করতে, \'ওভারভিউ\' স্পর্শ করুন এবং ধরে রাখুন৷"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"অ্যাপ্লিকেশান পিন করা আছে: এই ডিভাইস এটিকে পিনমুক্ত করা মঞ্জুরিপ্রাপ্ত নয়৷"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"স্ক্রীন পিন করা হয়েছে"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"পিন না করা স্ক্রীন"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS অনুরোধটিকে নতুন USSD অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS অনুরোধটিকে নতুন SS অনুরোধে রুপান্তরিত করা হয়েছে৷"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"কর্মস্থলের প্রোফাইল"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"প্রসারিত করার বোতাম"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB পেরিফেরাল পোর্ট"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB পেরিফেরাল পোর্ট"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"আনপিন করুন"</string>
<string name="app_info" msgid="6856026610594615344">"অ্যাপ্লিকেশানের তথ্য"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"সেশন পুনঃসূচনা করুন"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"একটি নতুন ডেমো সেশন শুরু করতে আলতো চাপ দিন"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"কোনো বিধিনিষেধ ছাড়াই এই ডিভাইসটিকে ব্যবহার করতে ফ্যাক্টরি রিসেট করুন"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"আরো জানতে স্পর্শ করুন৷"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"অক্ষম করা <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ca/strings.xml b/core/res/res/values-ca/strings.xml
index 59bf3e9..3eb14a9 100644
--- a/core/res/res/values-ca/strings.xml
+++ b/core/res/res/values-ca/strings.xml
@@ -405,7 +405,7 @@
<string name="permlab_changeNetworkState" msgid="958884291454327309">"canviar la connectivitat de xarxa"</string>
<string name="permdesc_changeNetworkState" msgid="6789123912476416214">"Permet que l\'aplicació pugui canviar l\'estat de connectivitat de la xarxa."</string>
<string name="permlab_changeTetherState" msgid="5952584964373017960">"Canvia la connectivitat de compartició de xarxa"</string>
- <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Permet que l\'aplicació canviï l\'estat de la connectivitat de la xarxa d\'ancoratge."</string>
+ <string name="permdesc_changeTetherState" msgid="1524441344412319780">"Permet que l\'aplicació canviï l\'estat de la connectivitat de la xarxa compartida."</string>
<string name="permlab_accessWifiState" msgid="5202012949247040011">"veure connexions Wi-Fi"</string>
<string name="permdesc_accessWifiState" msgid="5002798077387803726">"Permet que l\'aplicació visualitzi informació sobre les xarxes Wi-Fi, com ara si la Wi-Fi està activada i el nom dels dispositius Wi-Fi connectats."</string>
<string name="permlab_changeWifiState" msgid="6550641188749128035">"connectar-se a xarxes Wi-Fi i desconnectar-se"</string>
@@ -645,7 +645,7 @@
<string name="relationTypeDomesticPartner" msgid="6904807112121122133">"Parella"</string>
<string name="relationTypeFather" msgid="5228034687082050725">"Pare"</string>
<string name="relationTypeFriend" msgid="7313106762483391262">"Amic"</string>
- <string name="relationTypeManager" msgid="6365677861610137895">"Gerent"</string>
+ <string name="relationTypeManager" msgid="6365677861610137895">"Gestor"</string>
<string name="relationTypeMother" msgid="4578571352962758304">"Mare"</string>
<string name="relationTypeParent" msgid="4755635567562925226">"Pare/mare"</string>
<string name="relationTypePartner" msgid="7266490285120262781">"Partner"</string>
@@ -891,6 +891,38 @@
<item quantity="other">d\'aquí a <xliff:g id="COUNT_1">%d</xliff:g> a</item>
<item quantity="one">d\'aquí a <xliff:g id="COUNT_0">%d</xliff:g> a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">fa <xliff:g id="COUNT_1">%d</xliff:g> minuts</item>
+ <item quantity="one">fa <xliff:g id="COUNT_0">%d</xliff:g> minut</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">fa <xliff:g id="COUNT_1">%d</xliff:g> hores</item>
+ <item quantity="one">fa <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">fa <xliff:g id="COUNT_1">%d</xliff:g> dies</item>
+ <item quantity="one">fa <xliff:g id="COUNT_0">%d</xliff:g> dia</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">fa <xliff:g id="COUNT_1">%d</xliff:g> anys</item>
+ <item quantity="one">fa <xliff:g id="COUNT_0">%d</xliff:g> any</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">d\'aquí a <xliff:g id="COUNT_1">%d</xliff:g> minuts</item>
+ <item quantity="one">d\'aquí a <xliff:g id="COUNT_0">%d</xliff:g> minut</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">d\'aquí a <xliff:g id="COUNT_1">%d</xliff:g> hores</item>
+ <item quantity="one">d\'aquí a <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">d\'aquí a <xliff:g id="COUNT_1">%d</xliff:g> dies</item>
+ <item quantity="one">d\'aquí a <xliff:g id="COUNT_0">%d</xliff:g> dia</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">d\'aquí a <xliff:g id="COUNT_1">%d</xliff:g> anys</item>
+ <item quantity="one">d\'aquí a <xliff:g id="COUNT_0">%d</xliff:g> any</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problema amb el vídeo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Aquest vídeo no és vàlid per a la reproducció en aquest dispositiu."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"No es pot reproduir aquest vídeo."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> s\'ha aturat"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"L\'aplicació <xliff:g id="APPLICATION">%1$s</xliff:g> s\'atura contínuament"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"El procés <xliff:g id="PROCESS">%1$s</xliff:g> s\'atura contínuament"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Reinicia l\'aplicació"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Restableix i reinicia l\'aplicació"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Torna a obrir l\'aplicació"</string>
<string name="aerr_report" msgid="5371800241488400617">"Envia suggeriments"</string>
<string name="aerr_close" msgid="2991640326563991340">"Tanca"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Silencia fins que es reiniciï el dispositiu"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> suprimit"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de la feina"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Toca i mantén premuda l\'opció Enrere per deixar de fixar aquesta pantalla."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Toca i mantén premuda l\'opció Visió general per deixar de fixar aquesta pantalla."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"S\'ha fixat l\'aplicació. En aquest dispositiu no es permet anul·lar-ne la fixació."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Fixació de la pantalla anul·lada"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La sol·licitud SS s\'ha transformat en una sol·licitud USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La sol·licitud SS s\'ha transformat en una sol·licitud SS nova."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil professional"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Botó Desplega"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port perifèric USB d\'Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port perifèric USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"No fixis"</string>
<string name="app_info" msgid="6856026610594615344">"Informació de l\'aplicació"</string>
<string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Torna a iniciar la sessió"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Toca per iniciar una nova sessió de demostració"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Restableix les dades de fàbrica del dispositiu per utilitzar-lo sense restriccions"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toca per obtenir més informació."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> s\'ha desactivat"</string>
</resources>
diff --git a/core/res/res/values-cs/strings.xml b/core/res/res/values-cs/strings.xml
index 7d66b17..ec945fa 100644
--- a/core/res/res/values-cs/strings.xml
+++ b/core/res/res/values-cs/strings.xml
@@ -921,6 +921,54 @@
<item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> let</item>
<item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> rok</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="few">před <xliff:g id="COUNT_1">%d</xliff:g> minutami</item>
+ <item quantity="many">před <xliff:g id="COUNT_1">%d</xliff:g> minuty</item>
+ <item quantity="other">před <xliff:g id="COUNT_1">%d</xliff:g> minutami</item>
+ <item quantity="one">před <xliff:g id="COUNT_0">%d</xliff:g> minutou</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="few">před <xliff:g id="COUNT_1">%d</xliff:g> hodinami</item>
+ <item quantity="many">před <xliff:g id="COUNT_1">%d</xliff:g> hodiny</item>
+ <item quantity="other">před <xliff:g id="COUNT_1">%d</xliff:g> hodinami</item>
+ <item quantity="one">před <xliff:g id="COUNT_0">%d</xliff:g> hodinou</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="few">před <xliff:g id="COUNT_1">%d</xliff:g> dny</item>
+ <item quantity="many">před <xliff:g id="COUNT_1">%d</xliff:g> dne</item>
+ <item quantity="other">před <xliff:g id="COUNT_1">%d</xliff:g> dny</item>
+ <item quantity="one">před <xliff:g id="COUNT_0">%d</xliff:g> dnem</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="few">před <xliff:g id="COUNT_1">%d</xliff:g> lety</item>
+ <item quantity="many">před <xliff:g id="COUNT_1">%d</xliff:g> roku</item>
+ <item quantity="other">před <xliff:g id="COUNT_1">%d</xliff:g> lety</item>
+ <item quantity="one">před <xliff:g id="COUNT_0">%d</xliff:g> rokem</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> minuty</item>
+ <item quantity="many">za <xliff:g id="COUNT_1">%d</xliff:g> minuty</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> minut</item>
+ <item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> minutu</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> hodiny</item>
+ <item quantity="many">za <xliff:g id="COUNT_1">%d</xliff:g> hodiny</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> hodin</item>
+ <item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> hodinu</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> dny</item>
+ <item quantity="many">za <xliff:g id="COUNT_1">%d</xliff:g> dne</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> dnů</item>
+ <item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> den</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> roky</item>
+ <item quantity="many">za <xliff:g id="COUNT_1">%d</xliff:g> roku</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> let</item>
+ <item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> rok</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Potíže s videem"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Toto video nelze přenášet datovým proudem do tohoto zařízení."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Toto video nelze přehrát."</string>
@@ -992,8 +1040,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> přestal fungovat"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"Aplikace <xliff:g id="APPLICATION">%1$s</xliff:g> pravidelně přestává fungovat"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Aplikace <xliff:g id="PROCESS">%1$s</xliff:g> pravidelně přestává fungovat"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Restartovat aplikaci"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Obnovit a restartovat aplikaci"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Znovu spustit aplikaci"</string>
<string name="aerr_report" msgid="5371800241488400617">"Odeslat zpětnou vazbu"</string>
<string name="aerr_close" msgid="2991640326563991340">"Zavřít"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ignorovat do restartu zařízení"</string>
@@ -1550,7 +1597,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Číslice <xliff:g id="KEY">%1$s</xliff:g> byla smazána"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Pracovní <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Chcete-li tuto obrazovku uvolnit, klepněte na tlačítko Zpět a podržte jej."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Chcete-li tuto obrazovku uvolnit, klepněte na tlačítko Přehled a podržte jej."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikace je připnutá: Odepnutí v tomto zařízení není povoleno."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Obrazovka připnuta"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Obrazovka uvolněna"</string>
@@ -1633,6 +1679,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Požadavek SS byl změněn na požadavek USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Požadavek SS byl změněn na nový požadavek SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Pracovní profil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Tlačítko rozbalení"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port USB pro periferní zařízení – Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port USB pro periferní zařízení"</string>
@@ -1672,8 +1721,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Odepnout"</string>
<string name="app_info" msgid="6856026610594615344">"Informace o aplikaci"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Restartujte relaci"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Klepnutím zahájíte novou demonstrační relaci"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Chcete-li toto zařízení používat bez omezení, obnovte jej do továrního nastavení"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Klepnutím zobrazíte další informace."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – zakázáno"</string>
</resources>
diff --git a/core/res/res/values-da/strings.xml b/core/res/res/values-da/strings.xml
index eafad45..52f0ec3 100644
--- a/core/res/res/values-da/strings.xml
+++ b/core/res/res/values-da/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one">om <xliff:g id="COUNT_1">%d</xliff:g> år</item>
<item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> år</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">for <xliff:g id="COUNT_1">%d</xliff:g> minut siden</item>
+ <item quantity="other">for <xliff:g id="COUNT_1">%d</xliff:g> minutter siden</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">for <xliff:g id="COUNT_1">%d</xliff:g> time siden</item>
+ <item quantity="other">for <xliff:g id="COUNT_1">%d</xliff:g> timer siden</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">for <xliff:g id="COUNT_1">%d</xliff:g> dag siden</item>
+ <item quantity="other">for <xliff:g id="COUNT_1">%d</xliff:g> dage siden</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">for <xliff:g id="COUNT_1">%d</xliff:g> år siden</item>
+ <item quantity="other">for <xliff:g id="COUNT_1">%d</xliff:g> år siden</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">om <xliff:g id="COUNT_1">%d</xliff:g> minut</item>
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> minutter</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">om <xliff:g id="COUNT_1">%d</xliff:g> time</item>
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> timer</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">om <xliff:g id="COUNT_1">%d</xliff:g> dag</item>
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> dage</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">om <xliff:g id="COUNT_1">%d</xliff:g> år</item>
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> år</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Videoproblem"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Denne video kan ikke streames på denne enhed."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Videoen kan ikke afspilles."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> er stoppet"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> bliver ved med at stoppe"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> bliver ved med at stoppe"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Genstart appen"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Nulstil og genstart appen"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Åbn appen igen"</string>
<string name="aerr_report" msgid="5371800241488400617">"Send feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Luk"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ignorer, indtil enheden genstarter"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> er slettet"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> – arbejde"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Hvis du vil frigøre dette skærmbillede, skal du trykke på Tilbage og holde fingeren nede."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Hvis du vil frigøre dette skærmbillede, skal du trykke på Oversigt og holde fingeren nede."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Appen er fastgjort: Det er ikke tilladt at frigøre den på denne enhed."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skærmen blev fastgjort"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Skærmen blev frigjort"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-anmodningen er ændret til en USSD-anmodning."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-anmodningen er ændret til en ny SS-anmodning."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Arbejdsprofil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Udvid-knap"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"USB-port til eksterne Android-enheder"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB-port til eksterne enheder"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Frigør"</string>
<string name="app_info" msgid="6856026610594615344">"Oplysninger om appen"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Genstart sessionen"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Tryk for at starte en ny demosession"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Gendan fabriksdataene på enheden for at bruge den uden begrænsninger"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Tryk for at få flere oplysninger."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – deaktiveret"</string>
</resources>
diff --git a/core/res/res/values-de/strings.xml b/core/res/res/values-de/strings.xml
index 5510238..5a9b58e 100644
--- a/core/res/res/values-de/strings.xml
+++ b/core/res/res/values-de/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> a</item>
<item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">vor <xliff:g id="COUNT_1">%d</xliff:g> Minuten</item>
+ <item quantity="one">vor <xliff:g id="COUNT_0">%d</xliff:g> Minute</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">vor <xliff:g id="COUNT_1">%d</xliff:g> Stunden</item>
+ <item quantity="one">vor <xliff:g id="COUNT_0">%d</xliff:g> Stunde</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">vor <xliff:g id="COUNT_1">%d</xliff:g> Tagen</item>
+ <item quantity="one">vor <xliff:g id="COUNT_0">%d</xliff:g> Tag</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">vor <xliff:g id="COUNT_1">%d</xliff:g> Jahren</item>
+ <item quantity="one">vor <xliff:g id="COUNT_0">%d</xliff:g> Jahr</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> Minuten</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> Minute</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> Stunden</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> Stunde</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> Tagen</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> Tag</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> Jahren</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> Jahr</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Videoprobleme"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Dieses Video ist nicht für Streaming auf diesem Gerät gültig."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Video kann nicht wiedergegeben werden."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> wurde beendet"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> wird wiederholt beendet"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> wird wiederholt beendet"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"App neu starten"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"App zurücksetzen und neu starten"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"App wieder öffnen"</string>
<string name="aerr_report" msgid="5371800241488400617">"Feedback geben"</string>
<string name="aerr_close" msgid="2991640326563991340">"Schließen"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Bis zum Neustart des Geräts ausblenden"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> gelöscht"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (geschäftlich)"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Um die Fixierung dieses Bildschirms aufzuheben, \"Zurück\" berühren und halten."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Um die Fixierung dieses Bildschirms aufzuheben, \"Übersicht\" berühren und halten."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Die App ist fixiert. Das Aufheben der Fixierung ist auf diesem Gerät nicht zulässig."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Bildschirm fixiert"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Bildschirm gelöst"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-Anfrage wird in USSD-Anfrage geändert."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-Anfrage wird in neue SS-Anfrage geändert."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Arbeitsprofil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Schaltfläche \"Maximieren\""</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"USB-Port für Android-Peripheriegeräte"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB-Port für Peripheriegeräte"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Markierung entfernen"</string>
<string name="app_info" msgid="6856026610594615344">"App-Informationen"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Sitzung neu starten"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Zum Starten einer neuen Demositzung tippen"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Gerät auf Werkseinstellungen zurücksetzen, um es ohne Einschränkungen zu nutzen"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Für weitere Informationen tippen."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> deaktiviert"</string>
</resources>
diff --git a/core/res/res/values-el/strings.xml b/core/res/res/values-el/strings.xml
index bfb52e3..f27dc15 100644
--- a/core/res/res/values-el/strings.xml
+++ b/core/res/res/values-el/strings.xml
@@ -600,7 +600,7 @@
<string name="phoneTypeCompanyMain" msgid="540434356461478916">"Κύρια εταιρική"</string>
<string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
<string name="phoneTypeMain" msgid="6766137010628326916">"Κύριος"</string>
- <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Άλλο fax"</string>
+ <string name="phoneTypeOtherFax" msgid="8587657145072446565">"Άλλο φαξ"</string>
<string name="phoneTypeRadio" msgid="4093738079908667513">"Πομπός"</string>
<string name="phoneTypeTelex" msgid="3367879952476250512">"Τέλεξ"</string>
<string name="phoneTypeTtyTdd" msgid="8606514378585000044">"Τηλέφωνο TTY/TDD"</string>
@@ -891,6 +891,38 @@
<item quantity="other">σε <xliff:g id="COUNT_1">%d</xliff:g> ε.</item>
<item quantity="one">σε <xliff:g id="COUNT_0">%d</xliff:g> ε.</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">πριν από <xliff:g id="COUNT_1">%d</xliff:g> λεπτά</item>
+ <item quantity="one">πριν από <xliff:g id="COUNT_0">%d</xliff:g> λεπτό</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">πριν από <xliff:g id="COUNT_1">%d</xliff:g> ώρες</item>
+ <item quantity="one">πριν από <xliff:g id="COUNT_0">%d</xliff:g> ώρα</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">πριν από <xliff:g id="COUNT_1">%d</xliff:g> ημέρες</item>
+ <item quantity="one">πριν από <xliff:g id="COUNT_0">%d</xliff:g> ημέρα</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">πριν από <xliff:g id="COUNT_1">%d</xliff:g> έτη</item>
+ <item quantity="one">πριν από <xliff:g id="COUNT_0">%d</xliff:g> έτος</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">σε <xliff:g id="COUNT_1">%d</xliff:g> λεπτά</item>
+ <item quantity="one">σε <xliff:g id="COUNT_0">%d</xliff:g> λεπτό</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">σε <xliff:g id="COUNT_1">%d</xliff:g> ώρες</item>
+ <item quantity="one">σε <xliff:g id="COUNT_0">%d</xliff:g> ώρα</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">σε <xliff:g id="COUNT_1">%d</xliff:g> ημέρες</item>
+ <item quantity="one">σε <xliff:g id="COUNT_0">%d</xliff:g> ημέρα</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">σε <xliff:g id="COUNT_1">%d</xliff:g> έτη</item>
+ <item quantity="one">σε <xliff:g id="COUNT_0">%d</xliff:g> έτος</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Πρόβλημα με το βίντεο"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Αυτό το βίντεο δεν είναι έγκυρο για ροή σε αυτή τη συσκευή."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Δεν μπορείτε να αναπαράγετε αυτό το βίντεο."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Η διαδικασία <xliff:g id="PROCESS">%1$s</xliff:g> έχει διακοπεί"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"Η εφαρμογή <xliff:g id="APPLICATION">%1$s</xliff:g> διακόπτεται επανειλημμένα"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Η διαδικασία <xliff:g id="PROCESS">%1$s</xliff:g> διακόπτεται επανειλημμένα"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Επανεκκίνηση εφαρμογής"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Επαναφορά και επανεκκίνηση εφαρμογής"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Ανοίξτε ξανά την εφαρμογή"</string>
<string name="aerr_report" msgid="5371800241488400617">"Αποστολή σχολίων"</string>
<string name="aerr_close" msgid="2991640326563991340">"Κλείσιμο"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Σίγαση μέχρι την επανεκκίνηση της συσκευής"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> διαγράφηκε"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Εργασία <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, αγγίξτε παρατεταμένα \"Επιστροφή\"."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Για να ξεκαρφιτσώσετε αυτήν την οθόνη, αγγίξτε παρατεταμένα \"Επισκόπηση\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Η εφαρμογή καρφιτσώθηκε: Το ξεκαρφίτσωμα δεν επιτρέπεται σε αυτήν τη συσκευή."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Η οθόνη καρφιτσώθηκε"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Η οθόνη ξεκαρφιτσώθηκε"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Το αίτημα SS τροποποιήθηκε σε αίτημα USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Το αίτημα SS τροποποιήθηκε σε νέο αίτημα SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Προφίλ εργασίας"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Κουμπί ανάπτυξης"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Περιφερειακή θύρα USB Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Περιφερειακή θύρα USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Ξεκαρφίτσωμα"</string>
<string name="app_info" msgid="6856026610594615344">"Πληροφορίες εφαρμογής"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Επανεκκίνηση περιόδου σύνδεσης"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Πατήστε για να ξεκινήσετε μια νέα περίοδο σύνδεσης επίδειξης"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Επαναφέρετε τις εργοστασιακές ρυθμίσεις για να χρησιμοποιήσετε αυτήν τη συσκευή χωρίς περιορισμούς"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Αγγίξτε για να μάθετε περισσότερα."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Απενεργοποιημένο <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-en-rAU/strings.xml b/core/res/res/values-en-rAU/strings.xml
index 3c399c4..ebaba20 100644
--- a/core/res/res/values-en-rAU/strings.xml
+++ b/core/res/res/values-en-rAU/strings.xml
@@ -239,7 +239,7 @@
<string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string>
<string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
- <string name="android_system_label" msgid="6577375335728551336">"Android system"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string>
<string name="managed_profile_label" msgid="5289992269827577857">"Switch to Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
@@ -891,6 +891,38 @@
<item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g>y</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minute ago</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> hours</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> hour ago</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> day ago</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> year ago</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> minute</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> hour</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> day</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> year</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Video problem"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"This video isn\'t valid for streaming to this device."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Can\'t play this video."</string>
@@ -939,7 +971,7 @@
<string name="whichViewApplicationLabel" msgid="2666774233008808473">"Open"</string>
<string name="whichEditApplication" msgid="144727838241402655">"Edit with"</string>
<string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit with %1$s"</string>
- <string name="whichEditApplicationLabel" msgid="7183524181625290300">"(edit)"</string>
+ <string name="whichEditApplicationLabel" msgid="7183524181625290300">"Edit"</string>
<string name="whichSendApplication" msgid="6902512414057341668">"Share with"</string>
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"Share with %1$s"</string>
<string name="whichSendApplicationLabel" msgid="4579076294675975354">"Shared"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> has stopped"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> keeps stopping"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> keeps stopping"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Restart app"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Reset and restart app"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Open app again"</string>
<string name="aerr_report" msgid="5371800241488400617">"Send feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Close"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Mute until device restarts"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"To unpin this screen, touch & hold Back."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"To unpin this screen, touch & hold Overview."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App is pinned: unpinning isn\'t allowed on this device."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Screen unpinned"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profile"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Expand button"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
<string name="app_info" msgid="6856026610594615344">"App info"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Restart Session"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Tap to start a new demo session"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Factory reset to use this device without restrictions"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Touch to find out more."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-en-rGB/strings.xml b/core/res/res/values-en-rGB/strings.xml
index 3c399c4..ebaba20 100644
--- a/core/res/res/values-en-rGB/strings.xml
+++ b/core/res/res/values-en-rGB/strings.xml
@@ -239,7 +239,7 @@
<string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string>
<string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
- <string name="android_system_label" msgid="6577375335728551336">"Android system"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string>
<string name="managed_profile_label" msgid="5289992269827577857">"Switch to Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
@@ -891,6 +891,38 @@
<item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g>y</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minute ago</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> hours</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> hour ago</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> day ago</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> year ago</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> minute</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> hour</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> day</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> year</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Video problem"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"This video isn\'t valid for streaming to this device."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Can\'t play this video."</string>
@@ -939,7 +971,7 @@
<string name="whichViewApplicationLabel" msgid="2666774233008808473">"Open"</string>
<string name="whichEditApplication" msgid="144727838241402655">"Edit with"</string>
<string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit with %1$s"</string>
- <string name="whichEditApplicationLabel" msgid="7183524181625290300">"(edit)"</string>
+ <string name="whichEditApplicationLabel" msgid="7183524181625290300">"Edit"</string>
<string name="whichSendApplication" msgid="6902512414057341668">"Share with"</string>
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"Share with %1$s"</string>
<string name="whichSendApplicationLabel" msgid="4579076294675975354">"Shared"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> has stopped"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> keeps stopping"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> keeps stopping"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Restart app"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Reset and restart app"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Open app again"</string>
<string name="aerr_report" msgid="5371800241488400617">"Send feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Close"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Mute until device restarts"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"To unpin this screen, touch & hold Back."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"To unpin this screen, touch & hold Overview."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App is pinned: unpinning isn\'t allowed on this device."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Screen unpinned"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profile"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Expand button"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
<string name="app_info" msgid="6856026610594615344">"App info"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Restart Session"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Tap to start a new demo session"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Factory reset to use this device without restrictions"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Touch to find out more."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-en-rIN/strings.xml b/core/res/res/values-en-rIN/strings.xml
index 3c399c4..ebaba20 100644
--- a/core/res/res/values-en-rIN/strings.xml
+++ b/core/res/res/values-en-rIN/strings.xml
@@ -239,7 +239,7 @@
<string name="notification_hidden_text" msgid="1135169301897151909">"Contents hidden"</string>
<string name="notification_hidden_by_policy_text" msgid="9004631276932584600">"Contents hidden by policy"</string>
<string name="safeMode" msgid="2788228061547930246">"Safe mode"</string>
- <string name="android_system_label" msgid="6577375335728551336">"Android system"</string>
+ <string name="android_system_label" msgid="6577375335728551336">"Android System"</string>
<string name="user_owner_label" msgid="1119010402169916617">"Switch to Personal"</string>
<string name="managed_profile_label" msgid="5289992269827577857">"Switch to Work"</string>
<string name="permgrouplab_contacts" msgid="3657758145679177612">"Contacts"</string>
@@ -891,6 +891,38 @@
<item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g>y</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minute ago</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> hours</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> hour ago</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> day ago</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> years ago</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> year ago</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> minute</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> hours</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> hour</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> days</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> day</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> years</item>
+ <item quantity="one">in <xliff:g id="COUNT_0">%d</xliff:g> year</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Video problem"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"This video isn\'t valid for streaming to this device."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Can\'t play this video."</string>
@@ -939,7 +971,7 @@
<string name="whichViewApplicationLabel" msgid="2666774233008808473">"Open"</string>
<string name="whichEditApplication" msgid="144727838241402655">"Edit with"</string>
<string name="whichEditApplicationNamed" msgid="1775815530156447790">"Edit with %1$s"</string>
- <string name="whichEditApplicationLabel" msgid="7183524181625290300">"(edit)"</string>
+ <string name="whichEditApplicationLabel" msgid="7183524181625290300">"Edit"</string>
<string name="whichSendApplication" msgid="6902512414057341668">"Share with"</string>
<string name="whichSendApplicationNamed" msgid="2799370240005424391">"Share with %1$s"</string>
<string name="whichSendApplicationLabel" msgid="4579076294675975354">"Shared"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> has stopped"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> keeps stopping"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> keeps stopping"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Restart app"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Reset and restart app"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Open app again"</string>
<string name="aerr_report" msgid="5371800241488400617">"Send feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Close"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Mute until device restarts"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> deleted"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Work <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"To unpin this screen, touch & hold Back."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"To unpin this screen, touch & hold Overview."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App is pinned: unpinning isn\'t allowed on this device."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Screen pinned"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Screen unpinned"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS request is modified to USSD request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS request is modified to new SS request."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profile"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Expand button"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
<string name="app_info" msgid="6856026610594615344">"App info"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Restart Session"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Tap to start a new demo session"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Factory reset to use this device without restrictions"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Touch to find out more."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Disabled <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-es-rUS/strings.xml b/core/res/res/values-es-rUS/strings.xml
index 773dd11..fa7ec78 100644
--- a/core/res/res/values-es-rUS/strings.xml
+++ b/core/res/res/values-es-rUS/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> años</item>
<item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> año</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">hace <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="one">hace <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">hace <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="one">hace <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">hace <xliff:g id="COUNT_1">%d</xliff:g> días</item>
+ <item quantity="one">hace <xliff:g id="COUNT_0">%d</xliff:g> día</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">hace <xliff:g id="COUNT_1">%d</xliff:g> años</item>
+ <item quantity="one">hace <xliff:g id="COUNT_0">%d</xliff:g> año</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> días</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> día</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> años</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> año</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problemas de video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"No es posible transmitir este video al dispositivo."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"No se puede reproducir el video."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> se detuvo"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> continúa fallando"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> continúa fallando"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Reiniciar app"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Restablecer y reiniciar la app"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Volver a abrir la app"</string>
<string name="aerr_report" msgid="5371800241488400617">"Enviar comentarios"</string>
<string name="aerr_close" msgid="2991640326563991340">"Cerrar"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Silenciar hasta que se reinicie el dispositivo"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> borrado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para dejar de fijar esta pantalla, mantén presionado Atrás."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Para dejar de fijar esta pantalla, mantén presionado Recientes."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"La aplicación está fijada, no se puede anular la fijación en este dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fija"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Pantalla no fija"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La solicitud SS cambió por una solicitud USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La solicitud SS cambió por una nueva solicitud SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabajo"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Botón Expandir"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Puerto USB de periféricos Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Puerto USB de periféricos"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"No fijar"</string>
<string name="app_info" msgid="6856026610594615344">"Información de la app"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Reiniciar sesión"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Presiona para iniciar una nueva sesión de demostración"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Restablece la configuración de fábrica para usar este dispositivo sin restricciones"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toca para obtener más información."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Se inhabilitó <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-es/strings.xml b/core/res/res/values-es/strings.xml
index 93f128c..f47b4e7 100644
--- a/core/res/res/values-es/strings.xml
+++ b/core/res/res/values-es/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> a</item>
<item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">hace <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="one">hace <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">hace <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="one">hace <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">hace <xliff:g id="COUNT_1">%d</xliff:g> días</item>
+ <item quantity="one">hace <xliff:g id="COUNT_0">%d</xliff:g> día</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">hace <xliff:g id="COUNT_1">%d</xliff:g> años</item>
+ <item quantity="one">hace <xliff:g id="COUNT_0">%d</xliff:g> año</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> días</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> día</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> años</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> año</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Incidencias con el vídeo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Este vídeo no se puede transmitir al dispositivo."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"No se puede reproducir el vídeo."</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"El proceso <xliff:g id="PROCESS">%1$s</xliff:g> ha dejado de funcionar"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> sigue sin funcionar"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> sigue sin funcionar"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Reiniciar aplicación"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Restablecer y reiniciar aplicación"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Enviar sugerencias"</string>
<string name="aerr_close" msgid="2991640326563991340">"Cerrar"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Silenciar hasta que se reinicie el dispositivo"</string>
@@ -1512,7 +1544,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabajo"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Mantén pulsado el botón Atrás para dejar de fijar esta pantalla."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Mantén pulsado el botón Visión general para dejar de fijar esta pantalla."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"La aplicación está fijada: no se puede deshacer la fijación en este dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fijada"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"La pantalla ya no está fija"</string>
@@ -1579,6 +1610,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La solicitud SS se ha modificado para la solicitud USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La solicitud SS se ha modificado para la nueva solicitud SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabajo"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Puerto periférico USB (Android)"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Puerto periférico USB"</string>
@@ -1616,8 +1651,11 @@
<string name="unpin_target" msgid="3556545602439143442">"No fijar"</string>
<string name="app_info" msgid="6856026610594615344">"Información de la aplicación"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Restablece los datos de fábrica para usar este dispositivo sin restricciones"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toca para obtener más información."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> inhabilitado"</string>
</resources>
diff --git a/core/res/res/values-et-rEE/strings.xml b/core/res/res/values-et-rEE/strings.xml
index 329150e..8dcc2757 100644
--- a/core/res/res/values-et-rEE/strings.xml
+++ b/core/res/res/values-et-rEE/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> a pärast</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> a pärast</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minutit tagasi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minut tagasi</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> tundi tagasi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> tund tagasi</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> päeva tagasi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> päev tagasi</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> aastat tagasi</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> aasta tagasi</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minuti pärast</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minuti pärast</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> tunni pärast</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> tunni pärast</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> päeva pärast</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> päeva pärast</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> aasta pärast</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> aasta pärast</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Probleem videoga"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"See video ei sobi voogesituseks selles seadmes."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Videot ei saa esitada."</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"Rakendus <xliff:g id="PROCESS">%1$s</xliff:g> on seiskunud"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"Rakendus <xliff:g id="APPLICATION">%1$s</xliff:g> lõpetab pidevalt töö"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Rakendus <xliff:g id="PROCESS">%1$s</xliff:g> lõpetab pidevalt töö"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Taaskäivita rakendus"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Lähtesta ja taaskäivita rakendus"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Saada tagasiside"</string>
<string name="aerr_close" msgid="2991640326563991340">"Sule"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Vaigista, kuni seade taaskäivitatakse"</string>
@@ -1512,7 +1544,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> on kustutatud"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Töö <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Ekraani vabastamiseks puudutage pikalt nuppu Tagasi."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Ekraani vabastamiseks puudutage pikalt nuppu Ülevaade."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Rakendus on kinnitatud: vabastamine pole selles seadmes lubatud."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekraan on kinnitatud"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekraan on vabastatud"</string>
@@ -1579,6 +1610,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-päring muudeti USSD-päringuks."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-päring muudeti uueks SS-päringuks."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Tööprofiil"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Androidi väline USB-port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Väline USB-port"</string>
@@ -1616,8 +1651,11 @@
<string name="unpin_target" msgid="3556545602439143442">"Vabasta"</string>
<string name="app_info" msgid="6856026610594615344">"Rakenduse teave"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Seadme piiranguteta kasutamiseks lähtestage see tehaseandmetele"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Lisateabe saamiseks puudutage."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Keelatud <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-eu-rES/strings.xml b/core/res/res/values-eu-rES/strings.xml
index 2e813b4..d326f8a 100644
--- a/core/res/res/values-eu-rES/strings.xml
+++ b/core/res/res/values-eu-rES/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> urte barru</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> urte barru</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">Duela <xliff:g id="COUNT_1">%d</xliff:g> minutu</item>
+ <item quantity="one">Duela minutu <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">Duela <xliff:g id="COUNT_1">%d</xliff:g> ordu</item>
+ <item quantity="one">Duela ordu <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">Duela <xliff:g id="COUNT_1">%d</xliff:g> egun</item>
+ <item quantity="one">Duela egun <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">Duela <xliff:g id="COUNT_1">%d</xliff:g> urte</item>
+ <item quantity="one">Duela urte <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minutu barru</item>
+ <item quantity="one">Minutu <xliff:g id="COUNT_0">%d</xliff:g> barru</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ordu barru</item>
+ <item quantity="one">Ordu <xliff:g id="COUNT_0">%d</xliff:g> barru</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> egun barru</item>
+ <item quantity="one">Egun <xliff:g id="COUNT_0">%d</xliff:g> barru</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> urte barru</item>
+ <item quantity="one">Urte <xliff:g id="COUNT_0">%d</xliff:g> barru</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Bideoak arazoren bat du"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Bideo hau ezin da gailuan zuzenean erreproduzitu."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Ezin da bideoa erreproduzitu."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Gelditu egin da <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"Behin eta berriz gelditzen ari da <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Behin eta berriz gelditzen ari da <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Berrabiarazi aplikazioa"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Berrezarri eta berrabiarazi aplikazioa"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Ireki aplikazioa berriro"</string>
<string name="aerr_report" msgid="5371800241488400617">"Bidali iritzia"</string>
<string name="aerr_close" msgid="2991640326563991340">"Itxi"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ezkutatu gailua berrabiarazi arte"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ezabatu da"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Laneko <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Pantailari aingura kentzeko, eduki sakatuta Atzera botoia."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Pantailari aingura kentzeko, eduki sakatuta Ikuspegi orokorra botoia."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikazioa ainguratuta dago. Gailu honetan ezin da aingura kendu."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantaila ainguratu da"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Aingura kendu zaio pantailari"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS eskaera USSD eskaerara aldatu da."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS eskaera SS eskaera berrira aldatu da."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work profila"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Zabaltzeko botoia"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB ataka periferikoa"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB ataka periferikoa"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Kendu aingura"</string>
<string name="app_info" msgid="6856026610594615344">"Aplikazioari buruzko informazioa"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Berrabiarazi saioa"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Demo-saio berria hasteko, sakatu hau"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Berrezarri jatorrizko ezarpenak gailua murriztapenik gabe erabili ahal izateko"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Sakatu informazio gehiago lortzeko."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> desgaituta dago"</string>
</resources>
diff --git a/core/res/res/values-fa/strings.xml b/core/res/res/values-fa/strings.xml
index 97264065..b34286d 100644
--- a/core/res/res/values-fa/strings.xml
+++ b/core/res/res/values-fa/strings.xml
@@ -148,7 +148,7 @@
<string name="httpError" msgid="7956392511146698522">"خطایی در شبکه وجود داشت."</string>
<string name="httpErrorLookup" msgid="4711687456111963163">"URL پیدا نشد."</string>
<string name="httpErrorUnsupportedAuthScheme" msgid="6299980280442076799">"طرح کلی احراز هویت سایت پشتیبانی نمیشود."</string>
- <string name="httpErrorAuth" msgid="1435065629438044534">"تأیید اعتبار ناموفق بود."</string>
+ <string name="httpErrorAuth" msgid="1435065629438044534">"راستیآزمایی ناموفق بود."</string>
<string name="httpErrorProxyAuth" msgid="1788207010559081331">"احراز هویت از طریق سرور پروکسی انجام نشد."</string>
<string name="httpErrorConnect" msgid="8714273236364640549">"اتصال به سرور انجام نشد."</string>
<string name="httpErrorIO" msgid="2340558197489302188">"برقراری ارتباط با سرور ممکن نبود. بعداً دوباره امتحان کنید."</string>
@@ -216,7 +216,7 @@
<string name="global_action_power_off" msgid="4471879440839879722">"خاموش کردن"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"گزارش اشکال"</string>
<string name="bugreport_title" msgid="2667494803742548533">"گرفتن گزارش اشکال"</string>
- <string name="bugreport_message" msgid="398447048750350456">"این گزارش اطلاعات مربوط به وضعیت دستگاه کنونی شما را جمعآوری میکند تا به صورت یک پیام ایمیل ارسال شود. از زمان شروع گزارش اشکال تا آماده شدن برای ارسال اندکی زمان میبرد؛ لطفاً شکیبا باشید."</string>
+ <string name="bugreport_message" msgid="398447048750350456">"این گزارش اطلاعات مربوط به وضعیت دستگاه کنونی شما را جمعآوری میکند تا به صورت یک پیام رایانامه ارسال شود. از زمان شروع گزارش اشکال تا آماده شدن برای ارسال اندکی زمان میبرد؛ لطفاً شکیبا باشید."</string>
<string name="bugreport_option_interactive_title" msgid="8635056131768862479">"گزارش تعاملی"</string>
<string name="bugreport_option_interactive_summary" msgid="229299488536107968">"در بیشتر شرایط از این گزینه استفاده کنید. به شما امکان ردیابی پیشرفت گزارش و وارد کردن جزئیات بیشتری درباره مشکل را میدهد. ممکن است برخی از بخشهایی را که کمتر استفاده شده و باعث افزایش طول زمان گزارش میشود حذف کند."</string>
<string name="bugreport_option_full_title" msgid="6354382025840076439">"گزارش کامل"</string>
@@ -350,7 +350,7 @@
<string name="permdesc_readCalendar" product="tablet" msgid="4216462049057658723">"به برنامه امکان میدهد همه رویدادهای تقویم ذخیره شده در رایانهٔ لوحی شما را بخواند، از جمله رویدادهای دوستان یا همکاران. این ممکن است به برنامه امکان دهد دادههای تقویم شما را صرفنظر از محرمانه یا حساس بودن آنها به اشتراک گذاشته یا ذخیره کند."</string>
<string name="permdesc_readCalendar" product="tv" msgid="3191352452242394196">"به برنامه اجازه میدهد تا همه رویدادهای تقویم ذخیرهشده روی تلویزیون از جمله رویدادهای دوستان یا همکاران را بخواند. شاید به برنامه اجازه دهد تا اطلاعات تقویم را صرفنظر از محرمانه بودن یا حساسیت، به اشتراک بگذارد یا ذخیره کند."</string>
<string name="permdesc_readCalendar" product="default" msgid="7434548682470851583">"به برنامه امکان میدهد همه رویدادهای تقویم ذخیره شده در تلفن شما را بخواند، از جمله رویدادهای دوستان یا همکاران. این ممکن است به برنامه امکان دهد دادههای تقویم شما را صرفنظر از محرمانه یا حساس بودن آنها به اشتراک گذاشته یا ذخیره کند."</string>
- <string name="permlab_writeCalendar" msgid="8438874755193825647">"افزودن یا تغییر رویدادهای تقویم و ارسال ایمیل به مهمانان بدون دخالت مالک"</string>
+ <string name="permlab_writeCalendar" msgid="8438874755193825647">"افزودن یا تغییر رویدادهای تقویم و ارسال رایانامه به مهمانان بدون دخالت مالک"</string>
<string name="permdesc_writeCalendar" product="tablet" msgid="6679035520113668528">"به برنامه اجازه میدهد رویدادهایی را که میتوانید در رایانهٔ لوحی خود اصلاح نمایید، از جمله رویدادهای دوستان یا همکاران خود را، اضافه یا حذف کرده یا تغییر دهد. این ویژگی ممکن است به برنامه اجازه دهد پیامهایی را که به نظر میرسد از مالکین تقویم رسیده است ارسال نموده یا رویدادها را بدون اطلاع مالک اصلاح کنند."</string>
<string name="permdesc_writeCalendar" product="tv" msgid="1273290605500902507">"به برنامه اجازه میدهد به افزودن، حذف یا تغییر رویدادهایی بپردازد که میتوانید در تلویزیونتان تغییر دهید، از جمله رویدادهای دوستان یا همکاران خود. این ویژگی شاید به برنامه اجازه دهد پیامهایی را ارسال کند که به نظر میرسد از جانب مالکین تقویم است یا رویدادها را بدون اطلاع مالک تغییر دهد."</string>
<string name="permdesc_writeCalendar" product="default" msgid="2324469496327249376">"به برنامه اجازه میدهد رویدادهایی را که میتوانید در تلفن خود اصلاح نمایید، از جمله رویدادهای دوستان یا همکاران خود را، اضافه یا حذف کرده یا تغییر دهد. این ویژگی ممکن است به برنامه اجازه دهد پیامهایی را که به نظر میرسد از مالکین تقویم رسیده است ارسال نموده یا رویدادها را بدون اطلاع مالک اصلاح کنند."</string>
@@ -717,7 +717,7 @@
<string name="lockscreen_glogin_forgot_pattern" msgid="2588521501166032747">"بازگشایی قفل حساب"</string>
<string name="lockscreen_glogin_too_many_attempts" msgid="2751368605287288808">"تلاشهای زیادی برای کشیدن الگو صورت گرفته است"</string>
<string name="lockscreen_glogin_instructions" msgid="3931816256100707784">"برای بازگشایی قفل، با حساب Google خود وارد سیستم شوید."</string>
- <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"نام کاربری (ایمیل)"</string>
+ <string name="lockscreen_glogin_username_hint" msgid="8846881424106484447">"نام کاربری (رایانامه)"</string>
<string name="lockscreen_glogin_password_hint" msgid="5958028383954738528">"گذرواژه"</string>
<string name="lockscreen_glogin_submit_button" msgid="7130893694795786300">"ورود به سیستم"</string>
<string name="lockscreen_glogin_invalid_input" msgid="1364051473347485908">"نام کاربر یا گذرواژه نامعتبر است."</string>
@@ -891,6 +891,38 @@
<item quantity="one">در <xliff:g id="COUNT_1">%d</xliff:g> سال</item>
<item quantity="other">در <xliff:g id="COUNT_1">%d</xliff:g> سال</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> دقیقه پیش</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> دقیقه پیش</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ساعت پیش</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ساعت پیش</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> روز پیش</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> روز پیش</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> سال پیش</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> سال پیش</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">در <xliff:g id="COUNT_1">%d</xliff:g> دقیقه</item>
+ <item quantity="other">در <xliff:g id="COUNT_1">%d</xliff:g> دقیقه</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">در <xliff:g id="COUNT_1">%d</xliff:g> ساعت</item>
+ <item quantity="other">در <xliff:g id="COUNT_1">%d</xliff:g> ساعت</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">در <xliff:g id="COUNT_1">%d</xliff:g> روز</item>
+ <item quantity="other">در <xliff:g id="COUNT_1">%d</xliff:g> روز</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">در <xliff:g id="COUNT_1">%d</xliff:g> سال</item>
+ <item quantity="other">در <xliff:g id="COUNT_1">%d</xliff:g> سال</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"مشکل در ویدیو"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"متأسفیم، این ویدیو برای پخش جریانی با این دستگاه معتبر نیست."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"پخش این ویدیو ممکن نیست."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> متوقف شده است"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> مرتب متوقف میشود"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> مرتب متوقف میشود"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"راهاندازی مجدد برنامه"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"بازنشانی و راهاندازی مجدد برنامه"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"باز کردن دوباره برنامه"</string>
<string name="aerr_report" msgid="5371800241488400617">"ارسال بازخورد"</string>
<string name="aerr_close" msgid="2991640326563991340">"بستن"</string>
<string name="aerr_mute" msgid="1974781923723235953">"صامت کردن تا وقتی دستگاه راهاندازی مجدد شود"</string>
@@ -1364,7 +1395,7 @@
<string name="kg_invalid_confirm_pin_hint" product="default" msgid="7003469261464593516">"پین کدها منطبق نیستند"</string>
<string name="kg_login_too_many_attempts" msgid="6486842094005698475">"تلاشهای زیادی برای کشیدن الگو صورت گرفته است"</string>
<string name="kg_login_instructions" msgid="1100551261265506448">"برای بازگشایی قفل، با حساب Google خود وارد سیستم شوید."</string>
- <string name="kg_login_username_hint" msgid="5718534272070920364">"نام کاربری (ایمیل)"</string>
+ <string name="kg_login_username_hint" msgid="5718534272070920364">"نام کاربری (رایانامه)"</string>
<string name="kg_login_password_hint" msgid="9057289103827298549">"گذرواژه"</string>
<string name="kg_login_submit_button" msgid="5355904582674054702">"ورود به سیستم"</string>
<string name="kg_login_invalid_input" msgid="5754664119319872197">"نام کاربری یا گذرواژه نامعتبر."</string>
@@ -1379,9 +1410,9 @@
<string name="kg_failed_attempts_now_wiping" product="tablet" msgid="2072996269148483637">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل رایانه لوحی کردهاید. رایانه لوحی اکنون به پیشفرض کارخانه بازنشانی میشود."</string>
<string name="kg_failed_attempts_now_wiping" product="tv" msgid="4987878286750741463">"<xliff:g id="NUMBER">%d</xliff:g> دفعه به صورت نادرست سعی کردهاید قفل تلویزیون را باز کنید. اکنون تلویزیون به تنظیمات پیشفرض کارخانه بازنشانی خواهد شد."</string>
<string name="kg_failed_attempts_now_wiping" product="default" msgid="4817627474419471518">"شما به اشتباه <xliff:g id="NUMBER">%d</xliff:g> بار اقدام به باز کردن قفل تلفن کردهاید. این تلفن اکنون به پیشفرض کارخانه بازنشانی میشود."</string>
- <string name="kg_failed_attempts_almost_at_login" product="tablet" msgid="3253575572118914370">"شما الگوی بازگشایی قفل خود را <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="tv" msgid="4224651132862313471">"الگوی بازگشاییتان را <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="1437638152015574839">"شما الگوی بازگشایی قفل خود را <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="tablet" msgid="3253575572118914370">"شما الگوی بازگشایی قفل خود را <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="tv" msgid="4224651132862313471">"الگوی بازگشاییتان را <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="1437638152015574839">"شما الگوی بازگشایی قفل خود را <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_text_message_separator" product="default" msgid="4160700433287233771">" — "</string>
<string name="kg_reordering_delete_drop_target_text" msgid="7899202978204438708">"حذف"</string>
<string name="safe_media_volume_warning" product="default" msgid="2276318909314492312">"میزان صدا را به بالاتر از حد توصیه شده افزایش میدهید؟\n\nگوش دادن به صداهای بلند برای مدت طولانی میتواند به شنواییتان آسیب وارد کند."</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> حذف شد"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> محل کار"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"برای برداشتن پین این صفحه، «برگشت» را لمس کنید و نگه دارید."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"برای برداشتن پین این صفحه، «نمای کلی» را لمس کنید و نگه دارید."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"برنامه پین شده است: برداشتن پین در این دستگاه مجاز نیست."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"صفحه پین شد"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"پین صفحه برداشته شد"</string>
@@ -1522,7 +1552,7 @@
<string name="package_installed_device_owner" msgid="8420696545959087545">"توسط سرپرستتان نصب شد"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"توسط سرپرست شما بهروزرسانی شد"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"توسط سرپرستتان حذف شد"</string>
- <string name="battery_saver_description" msgid="1960431123816253034">"برای کمک به بهبود عمر باتری، بهینهسازی باتری عملکرد دستگاهتان را کاهش میدهد و لرزش، سرویسهای مبتنی بر مکان، و دسترسی به اکثر دادهها در پسزمینه را محدود میکند. ایمیل، پیامرسانی و برنامههای دیگری که به همگامسازی وابستهاند، تا زمانیکه آنها را باز نکنید نمیتوانند بهروز شوند.\n\nبهینهسازی باتری بهصورت خودکار در هنگام شارژ شدن دستگاه خاموش میشود."</string>
+ <string name="battery_saver_description" msgid="1960431123816253034">"برای کمک به بهبود عمر باتری، بهینهسازی باتری عملکرد دستگاهتان را کاهش میدهد و لرزش، سرویسهای مبتنی بر مکان، و دسترسی به اکثر دادهها در پسزمینه را محدود میکند. رایانامه، پیامرسانی و برنامههای دیگری که به همگامسازی وابستهاند، تا زمانیکه آنها را باز نکنید نمیتوانند بهروز شوند.\n\nبهینهسازی باتری بهصورت خودکار در هنگام شارژ شدن دستگاه خاموش میشود."</string>
<string name="data_saver_description" msgid="6015391409098303235">"برای کمک به کاهش مصرف داده، «صرفهجویی داده» از ارسال و دریافت داده در پسزمینه از طرف بعضی برنامهها جلوگیری میکند. برنامهای که درحالحاضر استفاده میکنید میتواند به دادهها دسترسی داشته باشد اما دفعات دسترسی آن محدود است.این یعنی، برای مثال، تصاویر تا زمانی که روی آنها ضربه نزنید نشان داده نمیشوند."</string>
<string name="data_saver_enable_title" msgid="4674073932722787417">"صرفهجویی داده روشن شود؟"</string>
<string name="data_saver_enable_button" msgid="7147735965247211818">"روشن کردن"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"درخواست SS به درخواست USSD اصلاح میشود."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"درخواست SS به درخواست SS جدید اصلاح میشود."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"نمایه کاری"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"دکمه بزرگ کردن"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"درگاه جانبی Android USB"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"درگاه جانبی USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"برداشتن پین"</string>
<string name="app_info" msgid="6856026610594615344">"اطلاعات برنامه"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"راهاندازی مجدد جلسه"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"برای شروع جلسه آزمایشی جدید ضربه بزنید"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"برای استفاده بدون محدودیت از این دستگاه، بازنشانی کارخانهای انجام دهید"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"برای یادگیری بیشتر لمس کنید."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> غیرفعال شد"</string>
</resources>
diff --git a/core/res/res/values-fi/strings.xml b/core/res/res/values-fi/strings.xml
index 81fd542..7d67655 100644
--- a/core/res/res/values-fi/strings.xml
+++ b/core/res/res/values-fi/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> v:n päästä</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> v:n päästä</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minuuttia sitten</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minuutti sitten</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> tuntia sitten</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> tunti sitten</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> päivää sitten</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> päivä sitten</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> vuotta sitten</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> vuosi sitten</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minuutin kuluttua</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minuutin kuluttua</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> tunnin kuluttua</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> tunnin kuluttua</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> päivän kuluttua</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> päivän kuluttua</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> vuoden kuluttua</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> vuoden kuluttua</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Video-ongelma"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Tätä videota ei voi suoratoistaa tällä laitteella."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Videota ei voida toistaa."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> pysähtyi."</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> pysähtyy toistuvasti."</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> pysähtyy toistuvasti."</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Käynnistä sovellus uudelleen"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Nollaa sovellus ja käynnistä uudelleen"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Avaa sovellus uudelleen"</string>
<string name="aerr_report" msgid="5371800241488400617">"Lähetä palautetta"</string>
<string name="aerr_close" msgid="2991640326563991340">"Sulje"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Mykistä laitteen uudelleenkäynnistykseen asti"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> poistettiin"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (työ)"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Irrota näyttö koskettamalla Takaisin-painiketta pitkään."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Poista näytön kiinnitys koskettamalla Yleistä-kohtaa pitkään."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Sovellus on kiinnitetty. Irrottaminen ei ole sallittua tällä laitteella."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Näyttö kiinnitetty"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Näyttö irrotettu"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-pyyntö muutettiin USSD-pyynnöksi."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-pyyntö muutettiin uudeksi SS-pyynnöksi."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Työprofiili"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Laajennuspainike"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Androidin USB-oheislaiteportti"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB-oheislaiteportti"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Irrota"</string>
<string name="app_info" msgid="6856026610594615344">"Sovelluksen tiedot"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Istunnon uudelleenaloitus"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Aloita uusi esittely napauttamalla."</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Palauta tehdasasetukset, jotta voit käyttää tätä laitetta rajoituksitta"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Lue lisätietoja koskettamalla."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ei ole käytössä."</string>
</resources>
diff --git a/core/res/res/values-fr-rCA/strings.xml b/core/res/res/values-fr-rCA/strings.xml
index bb3ae67..7220451 100644
--- a/core/res/res/values-fr-rCA/strings.xml
+++ b/core/res/res/values-fr-rCA/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">il y a<xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="other">il y a<xliff:g id="COUNT_1">%d</xliff:g> heures</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> an</item>
+ <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
+ <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problème vidéo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Impossible de lire cette vidéo en continu sur cet appareil."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Impossible de lire la vidéo."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> a cessé de fonctionner"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> plante continuellement"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> plante continuellement"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Redémarrer l\'application"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Réinitialiser et redémarrer l\'application"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Rouvrir l\'application"</string>
<string name="aerr_report" msgid="5371800241488400617">"Envoyer des commentaires"</string>
<string name="aerr_close" msgid="2991640326563991340">"Fermer"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Désactiver jusqu\'au redémarrage de l\'appareil"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"« <xliff:g id="KEY">%1$s</xliff:g> » a été supprimé"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (travail)"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Pour annuler l\'épinglage de cet écran, maintenez enfoncée la touche Retour."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Pour annuler l\'épinglage de cet écran, maintenez enfoncée la touche Aperçu."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"L\'application est épinglée : l\'annulation de l\'épinglage n\'est pas autorisée sur cet appareil."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Écran épinglé"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Épinglage d\'écran annulé"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La demande SS a été modifiée et est maintenant une demande USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La demande SS a été modifiée et est maintenant une nouvelle demande SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil professionnel"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Bouton Développer"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port USB de l\'appareil Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Annuler l\'épinglage"</string>
<string name="app_info" msgid="6856026610594615344">"Détails de l\'application"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Redémarrer la séance"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Touchez ici pour démarrer une nouvelle séance de démonstration"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Rétablissez la configuration d\'usine de cet appareil pour l\'utiliser sans restrictions"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Touchez ici pour en savoir plus."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Désactivé : <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-fr/strings.xml b/core/res/res/values-fr/strings.xml
index 64d5899..0a6a230 100644
--- a/core/res/res/values-fr/strings.xml
+++ b/core/res/res/values-fr/strings.xml
@@ -597,14 +597,14 @@
<string name="phoneTypeOther" msgid="1544425847868765990">"Autre"</string>
<string name="phoneTypeCallback" msgid="2712175203065678206">"Rappel"</string>
<string name="phoneTypeCar" msgid="8738360689616716982">"Voiture"</string>
- <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Accueil entreprise"</string>
+ <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Entreprise (principal)"</string>
<string name="phoneTypeIsdn" msgid="8022453193171370337">"RNIS"</string>
<string name="phoneTypeMain" msgid="6766137010628326916">"Principal"</string>
<string name="phoneTypeOtherFax" msgid="8587657145072446565">"Autre télécopie"</string>
<string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
<string name="phoneTypeTelex" msgid="3367879952476250512">"Télex"</string>
<string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY/TTD"</string>
- <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobile prof."</string>
+ <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobile pro"</string>
<string name="phoneTypeWorkPager" msgid="649938731231157056">"Bipeur prof."</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Assistant"</string>
<string name="phoneTypeMms" msgid="7254492275502768992">"MMS"</string>
@@ -891,6 +891,38 @@
<item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
<item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">il y a <xliff:g id="COUNT_1">%d</xliff:g> an</item>
+ <item quantity="other">il y a <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> heure</item>
+ <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> heures</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> jour</item>
+ <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> jours</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">dans <xliff:g id="COUNT_1">%d</xliff:g> an</item>
+ <item quantity="other">dans <xliff:g id="COUNT_1">%d</xliff:g> ans</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problème vidéo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Impossible de lire cette vidéo en streaming sur cet appareil."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Impossible de lire la vidéo."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Le processus <xliff:g id="PROCESS">%1$s</xliff:g> a cessé de fonctionner."</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> ne cesse de s\'arrêter."</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Le processus \"<xliff:g id="PROCESS">%1$s</xliff:g>\" ne cesse de s\'arrêter."</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Redémarrer l\'application"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Réinitialiser et redémarrer l\'application"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Rouvrir l\'application"</string>
<string name="aerr_report" msgid="5371800241488400617">"Envoyer des commentaires"</string>
<string name="aerr_close" msgid="2991640326563991340">"Fermer"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ignorer jusqu\'au redémarrage de l\'appareil"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"\"<xliff:g id="KEY">%1$s</xliff:g>\" supprimé"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (travail)"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Pour annuler l\'épinglage, appuyez de manière prolongée sur \"Retour\"."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Pour annuler l\'épinglage, appuyez de manière prolongée sur \"Vue d\'ensemble\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"L\'application est épinglée. L\'annulation de l\'épinglage n\'est pas autorisée sur cet appareil."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Écran épinglé."</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Épinglage d\'écran annulé."</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La requête SS a été remplacée par une requête USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La requête SS a été remplacée par une autre requête SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil professionnel"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Bouton \"Développer\""</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port du périphérique USB Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port du périphérique USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Retirer"</string>
<string name="app_info" msgid="6856026610594615344">"Infos sur l\'appli"</string>
<string name="negative_duration" msgid="5688706061127375131">"− <xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Redémarrer la session"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Appuyer pour lancer une nouvelle session de démonstration"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Rétablir la configuration d\'usine pour utiliser cet appareil sans restrictions"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Appuyez ici pour en savoir plus."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Élément \"<xliff:g id="LABEL">%1$s</xliff:g>\" désactivé"</string>
</resources>
diff --git a/core/res/res/values-gl-rES/strings.xml b/core/res/res/values-gl-rES/strings.xml
index f57e7bb..2f5ebf24 100644
--- a/core/res/res/values-gl-rES/strings.xml
+++ b/core/res/res/values-gl-rES/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> a</item>
<item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">hai <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="one">hai <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">hai <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="one">hai <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">hai <xliff:g id="COUNT_1">%d</xliff:g> días</item>
+ <item quantity="one">hai <xliff:g id="COUNT_0">%d</xliff:g> día</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">hai <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
+ <item quantity="one">hai <xliff:g id="COUNT_0">%d</xliff:g> ano</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> días</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> día</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">en <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
+ <item quantity="one">en <xliff:g id="COUNT_0">%d</xliff:g> ano</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Hai un problema co vídeo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Este vídeo non se pode transmitir no dispositivo."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Non se pode reproducir este vídeo."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Detívose <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> segue deténdose"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> segue deténdose"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Reiniciar aplicación"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Restablecer e reiniciar aplicación"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Abrir aplicación de novo"</string>
<string name="aerr_report" msgid="5371800241488400617">"Dános a túa opinión"</string>
<string name="aerr_close" msgid="2991640326563991340">"Pechar"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ignorar fallos ata que o dispositivo se reinicie"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> do traballo"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para soltar a pantalla, mantén premido Volver."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Para soltar a pantalla, mantén premido Visión xeral."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"A aplicación está fixada: non se permite soltala neste dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Pantalla fixada"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Pantalla desactivada"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"A solicitude SS transformouse nunha solicitude USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"A solicitude SS transformouse nunha nova solicitude SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de traballo"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Botón Despregar"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Porto periférico USB de Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Porto periférico USB"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Soltar"</string>
<string name="app_info" msgid="6856026610594615344">"Información da aplicación"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Reiniciar sesión"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Toca para iniciar unha nova sesión de demostración"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Restablecemento dos valores de fábrica para usar este dispositivo sen restricións"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toca para acceder a máis información"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Desactivouse <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-gu-rIN/strings.xml b/core/res/res/values-gu-rIN/strings.xml
index 289582b..816f8d6 100644
--- a/core/res/res/values-gu-rIN/strings.xml
+++ b/core/res/res/values-gu-rIN/strings.xml
@@ -257,7 +257,7 @@
<string name="permgrouplab_camera" msgid="4820372495894586615">"કૅમેરો"</string>
<string name="permgroupdesc_camera" msgid="3250611594678347720">"ચિત્રો લેવાની અને વિડિઓ રેકોર્ડ કરવાની"</string>
<string name="permgrouplab_phone" msgid="5229115638567440675">"ફોન"</string>
- <string name="permgroupdesc_phone" msgid="6234224354060641055">"ફોન કૉલ કરો તથા સંચાલિત કરો"</string>
+ <string name="permgroupdesc_phone" msgid="6234224354060641055">"ફોન કૉલ કરો અને સંચાલિત કરો"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"બોડી સેન્સર્સ"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"તમારા મહત્વપૂર્ણ ચિહ્નો વિશે સેન્સર ડેટા ઍક્સેસ કરો"</string>
<string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"વિંડો સામગ્રી પુનર્પ્રાપ્ત કરો"</string>
@@ -537,7 +537,7 @@
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ઉપકરણ વૈશ્વિક પ્રોક્સી સેટ કરો"</string>
<string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"નીતિ સક્ષમ હોય તે વખતે ઉપયોગ કરવા માટેના ઉપકરણ વૈશ્વિક પ્રોક્સીને સેટ કરો. ફક્ત ઉપકરણના માલિક વૈશ્વિક પ્રોક્સી સેટ કરી શકે છે."</string>
<string name="policylab_expirePassword" msgid="5610055012328825874">"સ્ક્રીન લૉક પાસવર્ડ સમાપ્તિ સેટ કરો"</string>
- <string name="policydesc_expirePassword" msgid="5367525762204416046">"કેટલીવાર સ્ક્રીન લૉક પાસવર્ડ, PIN અથવા નમૂનો બદલવો આવશ્યક છે તેને બદલો."</string>
+ <string name="policydesc_expirePassword" msgid="5367525762204416046">"કેટલીવાર સ્ક્રીન લૉક પાસવર્ડ, PIN અથવા પેટર્ન બદલવો આવશ્યક છે તેને બદલો."</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"સંગ્રહ એન્ક્રિપ્શન સેટ કરો"</string>
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"જરૂરી છે કે સંગ્રહિત ઍપ્લિકેશન એન્ક્રિપ્ટ થાય."</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"કૅમેરા અક્ષમ કરો"</string>
@@ -891,6 +891,38 @@
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>વ. માં</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>વ. માં</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> મિનિટ પહેલાં</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> મિનિટ પહેલાં</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> કલાક પહેલાં</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> કલાક પહેલાં</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> દિવસ પહેલાં</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> દિવસ પહેલાં</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> વર્ષ પહેલાં</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> વર્ષ પહેલાં</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> મિનિટમાં</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> મિનિટમાં</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> કલાકમાં</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> કલાકમાં</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> દિવસમાં</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> દિવસમાં</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> વર્ષમાં</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> વર્ષમાં</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"વિડિઓમાં સમસ્યા"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"આ ઉપકરણ પર સ્ટ્રીમ કરવા માટે આ વિડિઓ માન્ય નથી."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"આ વિડિઓ ચલાવી શકતાં નથી."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> બંધ થઈ ગઈ છે"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> રોકાઈ રહી છે"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> રોકાઈ રહી છે"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"ઍપ્લિકેશનને ફરીથી પ્રારંભ કરો"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"ફરીથી સેટ કરો અને ઍપ્લિકેશનને ફરીથી પ્રારંભ કરો"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"ઍપ્લિકેશન ફરીથી ખોલો"</string>
<string name="aerr_report" msgid="5371800241488400617">"પ્રતિસાદ મોકલો"</string>
<string name="aerr_close" msgid="2991640326563991340">"બંધ કરો"</string>
<string name="aerr_mute" msgid="1974781923723235953">"ઉપકરણ પુનઃપ્રારંભ ન થાય ત્યાં સુધી મ્યૂટ કરો"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> કાઢી નાખી"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"કાર્યાલય <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"આ સ્ક્રીનને અનપિન કરવા માટે, પાછળને ટચ કરીને પકડી રાખો."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"આ સ્ક્રીનને અનપિન કરવા માટે, વિહંગાવલોકન કરોને ટચ કરો અને પકડો."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ઍપ્લિકેશન પિન કરેલ છે. આ ઉપકરણ પર અનપિન કરવાની મંજૂરી નથી."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"સ્ક્રીન પિન કરી"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"સ્ક્રીન અનપિન કરી"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS વિનંતીને USSD વિનંતી પર સંશોધિત કરી."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS વિનંતીને નવી SS વિનંતી પર સંશોધિત કરી."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"કાર્ય પ્રોફાઇલ"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"વિસ્તૃત કરો બટન"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB પેરિફેરલ પોર્ટ"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB પેરિફેરલ પોર્ટ"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"અનપિન કરો"</string>
<string name="app_info" msgid="6856026610594615344">"ઍપ્લિકેશન માહિતી"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"સત્ર પુનઃપ્રારંભ કરો"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"નવું ડેમો સત્ર પ્રારંભ કરવા માટે ટૅપ કરો"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"આ ઉપકરણનો પ્રતિબંધો વિના ઉપયોગ કરવા માટે ફેક્ટરી રીસેટ કરો"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"વધુ જાણવા માટે ટચ કરો."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> અક્ષમ કર્યું"</string>
</resources>
diff --git a/core/res/res/values-hi/strings.xml b/core/res/res/values-hi/strings.xml
index 6bf9268..68c4526 100644
--- a/core/res/res/values-hi/strings.xml
+++ b/core/res/res/values-hi/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> वर्ष में</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> वर्ष में</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> मिनट पहले</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> मिनट पहले</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> घंटे पहले</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> घंटे पहले</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> दिन पहले</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> दिन पहले</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> वर्ष पहले</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> वर्ष पहले</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> मिनट में</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> मिनट में</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> घंटे में</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> घंटे में</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> दिनों में</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> दिनों में</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> वर्षों में</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> वर्षों में</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"वीडियो समस्याएं"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"यह वीडियो इस डिवाइस पर स्ट्रीमिंग के लिए मान्य नहीं है."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"यह वीडियो नहीं चलाया जा सकता."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> रुक गई है"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> रुक रहा है"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> रुक रही है"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"ऐप पुनः प्रारंभ करें"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"ऐप रीसेट करें और पुन: प्रारंभ करें"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"ऐप्लिकेशन फिर से खोलें"</string>
<string name="aerr_report" msgid="5371800241488400617">"फ़ीडबैक भेजें"</string>
<string name="aerr_close" msgid="2991640326563991340">"बंद करें"</string>
<string name="aerr_mute" msgid="1974781923723235953">"डिवाइस पुन: प्रारंभ होने तक म्यूट करें"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> को हटा दिया गया"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्यस्थल का <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"इस स्क्रीन को अनपिन करने के लिए, वापस जाएं को स्पर्श करके रखें."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"इस स्क्रीन को अनपिन करने के लिए, अवलोकन को स्पर्श करके रखें."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ऐप पिन किया गया है: इस डिवाइस पर अनपिन करने की अनुमति नहीं है."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रीन पिन की गई"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"स्क्रीन अनपिन की गई"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS अनुरोध को USSD अनुरोध में बदल दिया गया है."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS अनुरोध को नए SS अनुरोध में बदल दिया गया है."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"कार्य प्रोफ़ाइल"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"विस्तृत करें बटन"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB पेरिफ़ेरल पोर्ट"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB पेरिफ़ेरल पोर्ट"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"अनपिन करें"</string>
<string name="app_info" msgid="6856026610594615344">"ऐप की जानकारी"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"सत्र पुन: प्रारंभ करें"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"एक नया डेमो सत्र प्रारंभ करने के लिए टैप करें"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"इस डिवाइस को प्रतिबंधों के बिना उपयोग करने के लिए फ़ैक्टरी रीसेट करें"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"अधिक जानने के लिए स्पर्श करें."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"अक्षम <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-hr/strings.xml b/core/res/res/values-hr/strings.xml
index d1e06a6..186ba7c 100644
--- a/core/res/res/values-hr/strings.xml
+++ b/core/res/res/values-hr/strings.xml
@@ -906,6 +906,46 @@
<item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> g</item>
<item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> g</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">prije <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="few">prije <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">prije <xliff:g id="COUNT_1">%d</xliff:g> minuta</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">prije <xliff:g id="COUNT_1">%d</xliff:g> sata</item>
+ <item quantity="few">prije <xliff:g id="COUNT_1">%d</xliff:g> sata</item>
+ <item quantity="other">prije <xliff:g id="COUNT_1">%d</xliff:g> sati</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">prije <xliff:g id="COUNT_1">%d</xliff:g> dana</item>
+ <item quantity="few">prije <xliff:g id="COUNT_1">%d</xliff:g> dana</item>
+ <item quantity="other">prije <xliff:g id="COUNT_1">%d</xliff:g> dana</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">prije <xliff:g id="COUNT_1">%d</xliff:g> godine</item>
+ <item quantity="few">prije <xliff:g id="COUNT_1">%d</xliff:g> godine</item>
+ <item quantity="other">prije <xliff:g id="COUNT_1">%d</xliff:g> godina</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">za <xliff:g id="COUNT_1">%d</xliff:g> minutu</item>
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> minuta</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">za <xliff:g id="COUNT_1">%d</xliff:g> sat</item>
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> sata</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> sati</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">za <xliff:g id="COUNT_1">%d</xliff:g> dan</item>
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> dana</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> dana</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">za <xliff:g id="COUNT_1">%d</xliff:g> godinu</item>
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> godine</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> godina</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problem s videozapisom"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Ovaj videozapis nije valjan za streaming na ovaj uređaj."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Ovaj videozapis nije moguće reproducirati."</string>
@@ -977,8 +1017,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Postupak <xliff:g id="PROCESS">%1$s</xliff:g> je zaustavljen"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> neprekidno se ruši"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Postupak <xliff:g id="PROCESS">%1$s</xliff:g> neprekidno se ruši"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Ponovo pokreni aplikaciju"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Vrati aplikaciju na zadano i pokreni ponovo"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Ponovo otvori aplikaciju"</string>
<string name="aerr_report" msgid="5371800241488400617">"Pošalji povratne informacije"</string>
<string name="aerr_close" msgid="2991640326563991340">"Zatvori"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Zanemari do ponovnog pokretanja uređaja"</string>
@@ -1531,7 +1570,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Izbrisan je broj <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> za posao"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Da biste otkvačili ovaj zaslon, dodirnite i zadržite Natrag."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Da biste otkvačili ovaj zaslon, dodirnite i zadržite Pregled."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je prikvačena: otkvačivanje nije dopušteno na tom uređaju."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Zaslon je pričvršćen"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Zaslon je otkvačen"</string>
@@ -1606,6 +1644,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS zahtjev izmijenjen je u USSD zahtjev."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS zahtjev izmijenjen je u novi SS zahtjev."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Radni profil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Gumb za proširivanje"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Androidov USB priključak za periferne uređaje"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB priključak za periferne uređaje"</string>
@@ -1644,8 +1685,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Otkvači"</string>
<string name="app_info" msgid="6856026610594615344">"Informacije o aplikaciji"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Ponovno pokretanje sesije"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Dodirnite za pokretanje nove demo-sesije"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Uređaj je vraćen na tvorničke postavke da biste ga mogli upotrebljavati bez ograničenja"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Dodirnite da biste saznali više."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – onemogućeno"</string>
</resources>
diff --git a/core/res/res/values-hu/strings.xml b/core/res/res/values-hu/strings.xml
index 77c920f..29beca5 100644
--- a/core/res/res/values-hu/strings.xml
+++ b/core/res/res/values-hu/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> éven belül</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> éven belül</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> perccel ezelőtt</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> perccel ezelőtt</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> órával ezelőtt</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> órával ezelőtt</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> nappal ezelőtt</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> nappal ezelőtt</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> évvel ezelőtt</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> évvel ezelőtt</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> percen belül</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> percen belül</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> órán belül</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> órán belül</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> napon belül</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> napon belül</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> éven belül</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> éven belül</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Videoprobléma"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Ezt a videót nem lehet megjeleníteni ezen az eszközön."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Nem lehet lejátszani ezt a videót."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> – az alkalmazás leállt"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"A(z) <xliff:g id="APPLICATION">%1$s</xliff:g> alkalmazás állandóan leáll"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"A(z) <xliff:g id="PROCESS">%1$s</xliff:g> folyamat állandóan leáll"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Alkalmazás újraindítása"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Alkalmazás alaphelyzetbe állítása és újraindítása"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Alkalmazás ismételt megnyitása"</string>
<string name="aerr_report" msgid="5371800241488400617">"Visszajelzés küldése"</string>
<string name="aerr_close" msgid="2991640326563991340">"Bezárás"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Némítás az eszköz újraindulásáig"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"A(z) <xliff:g id="KEY">%1$s</xliff:g> érték törölve"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Munkahelyi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"A képernyő rögzítésének feloldásához tartsa lenyomva a Vissza lehetőséget."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"A képernyő rögzítésének feloldásához tartsa lenyomva az Áttekintés lehetőséget."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Az alkalmazás rögzítve van: a rögzítés feloldása nem engedélyezett ezen az eszközön."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Képernyő rögzítve"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Képernyő rögzítése feloldva"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Az SS-kérés módosítva USSD-kérésre."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Az SS-kérés módosítva új SS-kérésre."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Munkaprofil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Kibontás gomb"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB-perifériaport"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB-perifériaport"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Feloldás"</string>
<string name="app_info" msgid="6856026610594615344">"Alkalmazásinformáció"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Munkamenet újraindítása"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Koppintson az új, bemutató munkamenet indításához"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Állítsa vissza a gyári beállításokat az eszköz korlátozások nélküli használata érdekében"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Érintse meg a további információkért."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"A(z) <xliff:g id="LABEL">%1$s</xliff:g> letiltva"</string>
</resources>
diff --git a/core/res/res/values-hy-rAM/strings.xml b/core/res/res/values-hy-rAM/strings.xml
index 31d9cc1..9b1cc96 100644
--- a/core/res/res/values-hy-rAM/strings.xml
+++ b/core/res/res/values-hy-rAM/strings.xml
@@ -24,7 +24,7 @@
<string name="kilobyteShort" msgid="5973789783504771878">"ԿԲ"</string>
<string name="megabyteShort" msgid="6355851576770428922">"ՄԲ"</string>
<string name="gigabyteShort" msgid="3259882455212193214">"ԳԲ"</string>
- <string name="terabyteShort" msgid="231613018159186962">"Տբ"</string>
+ <string name="terabyteShort" msgid="231613018159186962">"ՏԲ"</string>
<string name="petabyteShort" msgid="5637816680144990219">"Պբ"</string>
<string name="fileSizeSuffix" msgid="8897567456150907538">"<xliff:g id="NUMBER">%1$s</xliff:g> <xliff:g id="UNIT">%2$s</xliff:g>"</string>
<string name="durationDays" msgid="6652371460511178259">"<xliff:g id="DAYS">%1$d</xliff:g> օր"</string>
@@ -891,6 +891,38 @@
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> տարուց</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> տարուց</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> րոպե առաջ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> րոպե առաջ</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ժամ առաջ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ժամ առաջ</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> օր առաջ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> օր առաջ</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> տարի առաջ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> տարի առաջ</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> րոպեից</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> րոպեից</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ժամից</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ժամից</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> օրից</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> օրից</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> տարուց</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> տարուց</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Տեսանյութի խնդիր"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Այս տեսանյութը հեռարձակման ենթակա չէ այս սարքով:"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Այս տեսանյութը հնարավոր չէ նվագարկել:"</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացն ընդհատվել է"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> հավելվածի աշխատանքը շարունակաբար ընդհատվում է"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> գործընթացը շարունակաբար ընդհատվում է"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Վերագործարկել հավելվածը"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Վերակայել և վերագործարկել հավելվածը"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Ուղարկել կարծիք"</string>
<string name="aerr_close" msgid="2991640326563991340">"Փակել"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Անջատել ձայնը մինչև սարքի վերագործարկումը"</string>
@@ -1512,7 +1544,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> թիվը ջնջված է"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Աշխատանքային <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Այս էկրանն ապամրացնելու համար հպեք և պահեք Հետ կոճակը:"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Այս էկրանն ապամրացնելու համար հպեք և պահեք Համատեսքի կոճակը:"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Հավելվածն ամրացված է: Ապամրացումն այս սարքում չի թույլատրվում:"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Էկրանն ամրացված է"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Էկրանն ապամրացված է"</string>
@@ -1579,6 +1610,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS հարցումը փոխվել է USSD հարցման:"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS հարցումը փոխվել է նոր SS հարցման:"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Աշխատանքային պրոֆիլ"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB արտաքին միացք"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB արտաքին միացք"</string>
@@ -1616,8 +1651,11 @@
<string name="unpin_target" msgid="3556545602439143442">"Ապամրացնել"</string>
<string name="app_info" msgid="6856026610594615344">"Հավելվածի տվյալներ"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Սարքն առանց սահմանափակումների օգտագործելու համար կատարեք գործարանային վերակայում"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Հպեք՝ ավելին իմանալու համար:"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Անջատած <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-in/strings.xml b/core/res/res/values-in/strings.xml
index 1128338..9aa74fd 100644
--- a/core/res/res/values-in/strings.xml
+++ b/core/res/res/values-in/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g>t</item>
<item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g>t</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> menit lalu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> menit lalu</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> jam lalu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> jam lalu</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> hari lalu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> hari lalu</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> tahun lalu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> tahun lalu</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g> menit</item>
+ <item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g> menit</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g> jam</item>
+ <item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g> jam</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g> hari</item>
+ <item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g> hari</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g> tahun</item>
+ <item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g> tahun</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Masalah video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Video ini tidak valid untuk pengaliran ke perangkat ini."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Tidak dapat memutar video ini."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> telah berhenti"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> terus berhenti"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> terus berhenti"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Mulai ulang aplikasi"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Setel ulang dan mulai ulang aplikasi"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Buka aplikasi lagi"</string>
<string name="aerr_report" msgid="5371800241488400617">"Kirim masukan"</string>
<string name="aerr_close" msgid="2991640326563991340">"Tutup"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Bisukan hingga perangkat dimulai ulang"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dihapus"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Kantor <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Untuk melepas pin layar ini, sentuh & tahan tombol Kembali."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Untuk melepas pin layar ini, sentuh & tahan tombol Ringkasan."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Pin dipasang ke aplikasi. Melepas pin tidak diizinkan di perangkat ini."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Layar disematkan"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Layar dicopot sematannya"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Permintaan SS diubah menjadi permintaan USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Permintaan SS diubah menjadi permintaan SS baru."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil kerja"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Tombol luaskan"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port Periferal USB Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port Periferal USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Lepas pin"</string>
<string name="app_info" msgid="6856026610594615344">"Info aplikasi"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Mulai Ulang Sesi"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Ketuk untuk memulai sesi demo baru"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Dikembalikan ke setelan pabrik agar perangkat ini dapat digunakan tanpa batasan"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Sentuh untuk mempelajari lebih lanjut."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> dinonaktifkan"</string>
</resources>
diff --git a/core/res/res/values-is-rIS/strings.xml b/core/res/res/values-is-rIS/strings.xml
index a65e8d9..4f1a9d3 100644
--- a/core/res/res/values-is-rIS/strings.xml
+++ b/core/res/res/values-is-rIS/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one">eftir <xliff:g id="COUNT_1">%d</xliff:g> ár</item>
<item quantity="other">eftir <xliff:g id="COUNT_1">%d</xliff:g> ár</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">fyrir <xliff:g id="COUNT_1">%d</xliff:g> mínútu</item>
+ <item quantity="other">fyrir <xliff:g id="COUNT_1">%d</xliff:g> mínútum</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">fyrir <xliff:g id="COUNT_1">%d</xliff:g> klukkustund</item>
+ <item quantity="other">fyrir <xliff:g id="COUNT_1">%d</xliff:g> klukkustundum</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">fyrir <xliff:g id="COUNT_1">%d</xliff:g> degi</item>
+ <item quantity="other">fyrir <xliff:g id="COUNT_1">%d</xliff:g> dögum</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">fyrir <xliff:g id="COUNT_1">%d</xliff:g> ári</item>
+ <item quantity="other">fyrir <xliff:g id="COUNT_1">%d</xliff:g> árum</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">eftir <xliff:g id="COUNT_1">%d</xliff:g> mínútu</item>
+ <item quantity="other">eftir <xliff:g id="COUNT_1">%d</xliff:g> mínútur</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">eftir <xliff:g id="COUNT_1">%d</xliff:g> klukkustund</item>
+ <item quantity="other">eftir <xliff:g id="COUNT_1">%d</xliff:g> klukkustundir</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">eftir <xliff:g id="COUNT_1">%d</xliff:g> dag</item>
+ <item quantity="other">eftir <xliff:g id="COUNT_1">%d</xliff:g> daga</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">eftir <xliff:g id="COUNT_1">%d</xliff:g> ár</item>
+ <item quantity="other">eftir <xliff:g id="COUNT_1">%d</xliff:g> ár</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Vandamál með myndskeið"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Þetta myndskeið er ekki gjaldgengt fyrir straumspilun í þessu tæki."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Ekki er hægt að spila þetta myndskeið."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> stöðvaðist"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> stöðvast ítrekað"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> stöðvast ítrekað"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Endurræsa forritið"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Endurstilla og endurræsa forritið"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Opna forrit aftur"</string>
<string name="aerr_report" msgid="5371800241488400617">"Senda ábendingu"</string>
<string name="aerr_close" msgid="2991640326563991340">"Loka"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Þagga þangað til tæki er endurræst"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eytt"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> í vinnu"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Til að taka lásinn af þessari skjámynd skaltu halda inni bakkhnappinum."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Til að taka lásinn af þessari skjámynd skaltu halda Yfirlit inni."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Forritið er fest: Ekki er hægt að losa forrit í þessu tæki."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skjár festur"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Skjár opnaður"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-beiðni er breytt í USSD-beiðni."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-beiðni er breytt í nýja SS-beiðni."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Vinnusnið"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Stækka hnapp"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB-tengi fyrir jaðartæki"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB-tengi fyrir jaðartæki"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Losa"</string>
<string name="app_info" msgid="6856026610594615344">"Forritsupplýsingar"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Endurræsa lotu"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Ýttu til að hefja nýja tilraunalotu"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Núllstilltu til að nota þetta tæki án takmarkana"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Snertu til að fá frekari upplýsingar."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Slökkt <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-it/strings.xml b/core/res/res/values-it/strings.xml
index 7eed840..8d99a73 100644
--- a/core/res/res/values-it/strings.xml
+++ b/core/res/res/values-it/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">tra <xliff:g id="COUNT_1">%d</xliff:g> a</item>
<item quantity="one">tra <xliff:g id="COUNT_0">%d</xliff:g> a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minuti fa</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minuto fa</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ore fa</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ora fa</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> giorni fa</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> giorno fa</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> anni fa</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> anno fa</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">tra <xliff:g id="COUNT_1">%d</xliff:g> minuti</item>
+ <item quantity="one">tra <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">tra <xliff:g id="COUNT_1">%d</xliff:g> ore</item>
+ <item quantity="one">tra <xliff:g id="COUNT_0">%d</xliff:g> ora</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">tra <xliff:g id="COUNT_1">%d</xliff:g> giorni</item>
+ <item quantity="one">tra <xliff:g id="COUNT_0">%d</xliff:g> giorno</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">tra <xliff:g id="COUNT_1">%d</xliff:g> anni</item>
+ <item quantity="one">tra <xliff:g id="COUNT_0">%d</xliff:g> anno</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problemi video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Questo video non è valido per lo streaming su questo dispositivo."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Impossibile riprodurre il video."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> si è interrotto"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"L\'app <xliff:g id="APPLICATION">%1$s</xliff:g> continua a interrompersi"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Il processo <xliff:g id="PROCESS">%1$s</xliff:g> continua a interrompersi"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Riavvia app"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Reimposta e riavvia app"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Riapri l\'app"</string>
<string name="aerr_report" msgid="5371800241488400617">"Invia feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Chiudi"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Disattiva fino al riavvio del dispositivo"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminato"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> lavoro"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Per sbloccare questa schermata tieni premuta l\'opzione Indietro."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Per sbloccare questa schermata tieni premuta l\'opzione Panoramica."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"L\'app è bloccata. Su questo dispositivo non è consentito lo sblocco."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Schermata bloccata"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Schermata sbloccata"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"La richiesta SS è stata modificata in richiesta USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"La richiesta SS è stata modificata in nuova richiesta SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profilo di lavoro"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Pulsante Espandi"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Porta periferica USB Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Porta periferica USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Sblocca"</string>
<string name="app_info" msgid="6856026610594615344">"Informazioni app"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Riavvia la sessione"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Tocca per iniziare una nuova sessione demo"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Esegui il ripristino dei dati di fabbrica per utilizzare il dispositivo senza limitazioni"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Tocca per ulteriori informazioni."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Widget <xliff:g id="LABEL">%1$s</xliff:g> disattivato"</string>
</resources>
diff --git a/core/res/res/values-iw/strings.xml b/core/res/res/values-iw/strings.xml
index dd75ff3..b5a4bc6 100644
--- a/core/res/res/values-iw/strings.xml
+++ b/core/res/res/values-iw/strings.xml
@@ -921,6 +921,54 @@
<item quantity="other">בעוד <xliff:g id="COUNT_1">%d</xliff:g> שנים</item>
<item quantity="one">בעוד שנה <xliff:g id="COUNT_0">%d</xliff:g></item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="two">לפני <xliff:g id="COUNT_1">%d</xliff:g> דקות</item>
+ <item quantity="many">לפני <xliff:g id="COUNT_1">%d</xliff:g> דקות</item>
+ <item quantity="other">לפני <xliff:g id="COUNT_1">%d</xliff:g> דקות</item>
+ <item quantity="one">לפני <xliff:g id="COUNT_0">%d</xliff:g> דקה</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="two">לפני <xliff:g id="COUNT_1">%d</xliff:g> שעות</item>
+ <item quantity="many">לפני <xliff:g id="COUNT_1">%d</xliff:g> שעות</item>
+ <item quantity="other">לפני <xliff:g id="COUNT_1">%d</xliff:g> שעות</item>
+ <item quantity="one">לפני שעה <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="two">לפני <xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
+ <item quantity="many">לפני <xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
+ <item quantity="other">לפני <xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
+ <item quantity="one">לפני יום <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="two">לפני <xliff:g id="COUNT_1">%d</xliff:g> שנים</item>
+ <item quantity="many">לפני <xliff:g id="COUNT_1">%d</xliff:g> שנים</item>
+ <item quantity="other">לפני <xliff:g id="COUNT_1">%d</xliff:g> שנים</item>
+ <item quantity="one">לפני <xliff:g id="COUNT_0">%d</xliff:g> שנה</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="two">בעוד <xliff:g id="COUNT_1">%d</xliff:g> דקות</item>
+ <item quantity="many">בעוד <xliff:g id="COUNT_1">%d</xliff:g> דקות</item>
+ <item quantity="other">בעוד <xliff:g id="COUNT_1">%d</xliff:g> דקות</item>
+ <item quantity="one">בעוד <xliff:g id="COUNT_0">%d</xliff:g> דקה</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="two">בעוד <xliff:g id="COUNT_1">%d</xliff:g> שעות</item>
+ <item quantity="many">בעוד <xliff:g id="COUNT_1">%d</xliff:g> שעות</item>
+ <item quantity="other">בעוד <xliff:g id="COUNT_1">%d</xliff:g> שעות</item>
+ <item quantity="one">בעוד <xliff:g id="COUNT_0">%d</xliff:g> שעה</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="two">בעוד <xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
+ <item quantity="many">בעוד <xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
+ <item quantity="other">בעוד <xliff:g id="COUNT_1">%d</xliff:g> ימים</item>
+ <item quantity="one">בעוד <xliff:g id="COUNT_0">%d</xliff:g> יום</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="two">בעוד <xliff:g id="COUNT_1">%d</xliff:g> שנים</item>
+ <item quantity="many">בעוד <xliff:g id="COUNT_1">%d</xliff:g> שנים</item>
+ <item quantity="other">בעוד <xliff:g id="COUNT_1">%d</xliff:g> שנים</item>
+ <item quantity="one">בעוד שנה <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"בעיה בווידאו"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"סרטון זה אינו חוקי להעברה כמדיה זורמת למכשיר זה."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"לא ניתן להפעיל סרטון זה."</string>
@@ -992,8 +1040,7 @@
<string name="aerr_process" msgid="6201597323218674729">"התהליך <xliff:g id="PROCESS">%1$s</xliff:g> הפסיק"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"האפליקציה <xliff:g id="APPLICATION">%1$s</xliff:g> נעצרת שוב ושוב"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"האפליקציה <xliff:g id="PROCESS">%1$s</xliff:g> נעצרת שוב ושוב"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"הפעל מחדש את האפליקציה"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"אפס והפעל מחדש את האפליקציה"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"פתח שוב את האפליקציה"</string>
<string name="aerr_report" msgid="5371800241488400617">"שלח משוב"</string>
<string name="aerr_close" msgid="2991640326563991340">"סגור"</string>
<string name="aerr_mute" msgid="1974781923723235953">"השתק עד הפעלה מחדש של המכשיר"</string>
@@ -1550,7 +1597,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> נמחק"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"עבודה <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"כדי לבטל את הצמדת המסך הזה, לחץ לחיצה ממושכת על הלחצן \'הקודם\'."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"כדי לבטל את הצמדת המסך הזה, לחץ לחיצה ממושכת על הלחצן \'סקירה\'."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"האפליקציה מוצמדת: ביטול ההצמדה אסור במכשיר הזה."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"המסך מוצמד"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"הצמדת המסך בוטלה"</string>
@@ -1633,6 +1679,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"בקשת SS שונתה לבקשת USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"בקשת SS שונתה לבקשת SS חדשה."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"פרופיל עבודה"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"לחצן הרחבה"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"יציאת USB בציוד היקפי של Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"יציאת USB בציוד היקפי"</string>
@@ -1672,8 +1721,9 @@
<string name="unpin_target" msgid="3556545602439143442">"בטל הצמדה"</string>
<string name="app_info" msgid="6856026610594615344">"פרטי אפליקציה"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"הפעלה מחדש"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"הקש כדי להפעיל הדגמה חדשה"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"איפוס להגדרות היצרן כדי לאפשר שימוש במכשיר ללא מגבלות"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"גע לקבלת מידע נוסף."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> הושבת"</string>
</resources>
diff --git a/core/res/res/values-ja/strings.xml b/core/res/res/values-ja/strings.xml
index 2bd2504..5e010d2 100644
--- a/core/res/res/values-ja/strings.xml
+++ b/core/res/res/values-ja/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>年</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>年</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 分前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 分前</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 時間前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 時間前</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 日前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 日前</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年前</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 分後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 分後</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 時間後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 時間後</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 日後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 日後</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年後</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"動画の問題"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"この動画はこの端末にストリーミングできません。"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"この動画を再生できません。"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> が停止しました"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"「<xliff:g id="APPLICATION">%1$s</xliff:g>」が繰り返し停止しています"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"「<xliff:g id="PROCESS">%1$s</xliff:g>」が繰り返し停止しています"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"アプリを再起動"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"アプリをリセットして再起動"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"アプリを再起動"</string>
<string name="aerr_report" msgid="5371800241488400617">"フィードバックを送信"</string>
<string name="aerr_close" msgid="2991640326563991340">"閉じる"</string>
<string name="aerr_mute" msgid="1974781923723235953">"端末が再起動するまでミュート"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g>を削除しました"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"仕事の<xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"この画面の固定を解除するには [戻る] を押し続けます。"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"この画面の固定を解除するには [概要] を押し続けます。"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"アプリは固定されています。この端末では固定を解除できません。"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"画面を固定しました"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"画面固定を解除しました"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SSリクエストはUSSDリクエストに変更されました。"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SSリクエストは新しいSSリクエストに変更されました。"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"仕事用プロファイル"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"展開ボタン"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB周辺機器ポート"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB周辺機器ポート"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"固定を解除"</string>
<string name="app_info" msgid="6856026610594615344">"アプリ情報"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"新しいセッションの開始"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"新しいデモセッションを開始するにはタップ"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"制限なしでこの端末を使用するには初期状態にリセットしてください"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"タップして詳細をご確認ください。"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"停止済みの「<xliff:g id="LABEL">%1$s</xliff:g>」"</string>
</resources>
diff --git a/core/res/res/values-ka-rGE/strings.xml b/core/res/res/values-ka-rGE/strings.xml
index 3354465..70c3d44 100644
--- a/core/res/res/values-ka-rGE/strings.xml
+++ b/core/res/res/values-ka-rGE/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> წელში</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> წელში</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> წუთის წინ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> წუთის წინ</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> საათის წინ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> საათის წინ</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> დღის წინ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> დღის წინ</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> წლის წინ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> წლის წინ</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> წუთში</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> წუთში</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> საათში</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> საათში</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> დღეში</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> დღეში</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> წელში</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> წელში</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"პრობლემები ვიდეოსთან"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ეს ვიდეო არ გამოდგება ამ მოწყობილობაზე სტრიმინგისთვის."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ვიდეოს დაკვრა არ არის შესაძლებელი."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> შეწყდა"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> განუწყვეტლივ ჩერდება"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> განუწყვეტლივ წყდება"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"აპის გადატვირთვა"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"გადაყენება და აპის გადატვირთვა"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"აპის ხელახლა გახსნა"</string>
<string name="aerr_report" msgid="5371800241488400617">"გამოხმაურება"</string>
<string name="aerr_close" msgid="2991640326563991340">"დახურვა"</string>
<string name="aerr_mute" msgid="1974781923723235953">"დადუმება მოწყობილობის გადატვირთვამდე"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> წაიშალა"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"სამსახური <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ამ ეკრანის ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ ღილაკს „უკან“."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ამ ეკრანის ჩამაგრების მოსახსნელად, ხანგრძლივად შეეხეთ ღილაკს „მიმოხილვა“."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"აპი მიმაგრებულია: მიმაგრების მოხსნა არ არის ნებადართული ამ მოწყობილობაზე."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ეკრანი დაფიქსირდა"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"ეკრანს ფიქსაცია მოეხსნა"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS მოთხოვნა შეიცვალა USSD მოთხოვნით."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS მოთხოვნა შეიცვალა ახალი SS მოთხოვნით."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"სამსახურის პროფილი"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"გაშლის ღილაკი"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android-ის პერიფერიული USB პორტი"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"პერიფერიული USB პორტი"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"ჩამაგრების მოხსნა"</string>
<string name="app_info" msgid="6856026610594615344">"აპის შესახებ"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"სესიის ხელახლა დაწყება"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"შეეხეთ ახალი სადემონსტრაციო სესიის დასაწყებად"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"ამ მოწყობილობის შეზღუდვების გარეშე გამოსაყენებლად, დააბრუნეთ ქარხნული პარამეტრები"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"შეეხეთ მეტის გასაგებად."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"გათიშული <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-kk-rKZ/strings.xml b/core/res/res/values-kk-rKZ/strings.xml
index 29a62f3..e705003 100644
--- a/core/res/res/values-kk-rKZ/strings.xml
+++ b/core/res/res/values-kk-rKZ/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ж.</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ж.</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> минут бұрын</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> минут бұрын</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> сағат бұрын</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> сағат бұрын</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> күн бұрын</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> күн бұрын</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> жыл бұрын</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> жыл бұрын</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> минутта</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> минутта</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> сағатта</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> сағатта</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> күнде</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> күнде</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> жылда</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> жылда</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Бейне ақаулығы"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Бұл бейне осы құрылғыға ағынын жіберуге жарамсыз."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Бұл бейне таспаны ойната алмайды."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> тоқтады"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> тоқтай береді"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> тоқтай береді"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Қолданбаны қайта іске қосу"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Ысырып, қолданбаны қайта іске қосу"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Қолданбаны қайта ашу"</string>
<string name="aerr_report" msgid="5371800241488400617">"Пікір жіберу"</string>
<string name="aerr_close" msgid="2991640326563991340">"Жабу"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Құрылғы қайта іске қосылғанша дыбысын өшіру"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> жойылды"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Жұмыс <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Осы экранды босату үшін \"Артқа\" түймесін басып тұрыңыз."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Осы экранды босату үшін \"Шолу\" түймесін басып тұрыңыз."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Бағдарлама белгіленді: Бұл құрылғыда белгіні алуға рұқсат берілмейді."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Экран түйрелді"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Экран босатылды"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS сұрауы USSD сұрауына өзгертілді."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS сұрауы жаңа SS сұрауына өзгертілді."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Жұмыс профилі"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Жаю түймесі"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB перифериялық порты"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB перифериялық порты"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Босату"</string>
<string name="app_info" msgid="6856026610594615344">"Қолданба ақпараты"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Сеансты қайта бастау"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Жаңа демо сеансты бастау үшін түртіңіз"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Осы құрылғыны шектеусіз пайдалану үшін зауыттық параметрлерді қалпына келтіріңіз"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Қосымша мәліметтер алу үшін түртіңіз."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> өшірулі"</string>
</resources>
diff --git a/core/res/res/values-km-rKH/strings.xml b/core/res/res/values-km-rKH/strings.xml
index 31d87de..c190806 100644
--- a/core/res/res/values-km-rKH/strings.xml
+++ b/core/res/res/values-km-rKH/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">ក្នុងពេល <xliff:g id="COUNT_1">%d</xliff:g>ឆ</item>
<item quantity="one">ក្នុងពេល <xliff:g id="COUNT_0">%d</xliff:g>ឆ</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> នាទីមុន</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> នាទីមុន</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ម៉ោងមុន</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ម៉ោងមុន</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ថ្ងៃមុន</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ថ្ងៃមុន</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ឆ្នាំមុន</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ឆ្នាំមុន</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">ក្នុងរយៈពេល <xliff:g id="COUNT_1">%d</xliff:g> នាទីទៀត</item>
+ <item quantity="one">ក្នុងរយៈពេល <xliff:g id="COUNT_0">%d</xliff:g> នាទីទៀត</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">ក្នុងរយៈពេល <xliff:g id="COUNT_1">%d</xliff:g> ម៉ោងទៀត</item>
+ <item quantity="one">ក្នុងរយៈពេល <xliff:g id="COUNT_0">%d</xliff:g> ម៉ោងទៀត</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">ក្នុងរយៈពេល <xliff:g id="COUNT_1">%d</xliff:g> ថ្ងៃទៀត</item>
+ <item quantity="one">ក្នុងរយៈពេល <xliff:g id="COUNT_0">%d</xliff:g> ថ្ងៃទៀត</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">ក្នុងរយៈពេល <xliff:g id="COUNT_1">%d</xliff:g> ឆ្នាំទៀត</item>
+ <item quantity="one">ក្នុងរយៈពេល <xliff:g id="COUNT_0">%d</xliff:g> ឆ្នាំទៀត</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"បញ្ហាវីដេអូ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"វីដេអូនេះមិនត្រឹមត្រូវសម្រាប់ចរន្តចូលឧបករណ៍នេះ។"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"មិនអាចចាក់វីដេអូនេះ។"</string>
@@ -964,8 +996,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> បានឈប់"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> ឈប់ដំណើរការម្តងហើយម្តងទៀត"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> ឈប់ដំណើរការម្តងហើយម្តងទៀត"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"ចាប់ផ្តើមកម្មវិធីឡើងវិញ"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"កំណត់ និងចាប់ផ្តើមកម្មវិធីឡើងវិញ"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"បើកកម្មវិធីម្តងទៀត"</string>
<string name="aerr_report" msgid="5371800241488400617">"ផ្ញើមតិ"</string>
<string name="aerr_close" msgid="2991640326563991340">"បិទ"</string>
<string name="aerr_mute" msgid="1974781923723235953">"បិទរហូតដល់ឧបករណ៍ចាប់ផ្តើមឡើងវិញ"</string>
@@ -1514,7 +1545,6 @@
<string name="deleted_key" msgid="7659477886625566590">"បានលុប <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"កន្លែងធ្វើការ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ដើម្បីផ្តាច់អេក្រង់នេះ សូមប៉ះ និងសង្កត់ប៊ូតុងថយក្រោយឲ្យជាប់។"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ដើម្បីផ្តាច់អេក្រង់នេះ សូមប៉ះ និងសង្កត់ប៊ូតុងទិដ្ឋភាពឲ្យជាប់។"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"កម្មវិធីនេះត្រូវបានខ្ទាស់។ មិនអនុញ្ញាតឲ្យដោះការខ្ទាស់នៅលើឧបករណ៍នេះទេ។"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"បានភ្ជាប់អេក្រង់"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"មិនបានភ្ជាប់អេក្រង់"</string>
@@ -1581,6 +1611,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"សំណើរ SS ត្រូវបានកែសម្រួលទៅតាមសំណើរ USSD។"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"សំណើរ SS ត្រូវបានកែសម្រួលទៅតាមសំណើរ SS ថ្មី។"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ប្រវត្តិរូបការងារ"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"ប៊ូតុងពង្រីក"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"ឧបករណ៍រន្ធ USB Android បន្ថែម"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"ឧបករណ៍រន្ធ USB បន្ថែម"</string>
@@ -1618,8 +1651,9 @@
<string name="unpin_target" msgid="3556545602439143442">"មិនខ្ទាស់"</string>
<string name="app_info" msgid="6856026610594615344">"ព័ត៌មានកម្មវិធី"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"ចាប់ផ្តើមវេនម្តងទៀត"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"ប៉ះដើម្បីចាប់ផ្តើមវេនបង្ហាញសាកល្បងថ្មី"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"កំណត់ដូចចេញពីរោងចក្រឡើងវិញដើម្បីប្រើឧបករណ៍នេះដោយគ្មានការរឹតបន្តឹង"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"ប៉ះ ដើម្បីស្វែងយល់បន្ថែម។"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ដែលបានបិទដំណើរការ"</string>
</resources>
diff --git a/core/res/res/values-kn-rIN/strings.xml b/core/res/res/values-kn-rIN/strings.xml
index c1bac96..b5d27a8 100644
--- a/core/res/res/values-kn-rIN/strings.xml
+++ b/core/res/res/values-kn-rIN/strings.xml
@@ -51,7 +51,7 @@
<string name="serviceDisabled" msgid="1937553226592516411">"ಸೇವೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ."</string>
<string name="serviceRegistered" msgid="6275019082598102493">"ನೋಂದಣಿ ಯಶಸ್ವಿಯಾಗಿದೆ."</string>
<string name="serviceErased" msgid="1288584695297200972">"ಅಳಿಸುವಿಕೆ ಯಶಸ್ವಿಯಾಗಿದೆ."</string>
- <string name="passwordIncorrect" msgid="7612208839450128715">"ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್."</string>
+ <string name="passwordIncorrect" msgid="7612208839450128715">"ತಪ್ಪು ಪಾಸ್ವರ್ಡ್."</string>
<string name="mmiComplete" msgid="8232527495411698359">"MMI ಪೂರ್ಣಗೊಂಡಿದೆ."</string>
<string name="badPin" msgid="9015277645546710014">"ನೀವು ಟೈಪ್ ಮಾಡಿದ ಹಳೆಯ ಪಿನ್ ಸರಿಯಾಗಿಲ್ಲ."</string>
<string name="badPuk" msgid="5487257647081132201">"ನೀವು ಟೈಪ್ ಮಾಡಿದ PUK ಸರಿಯಾಗಿಲ್ಲ."</string>
@@ -122,21 +122,21 @@
<string name="roamingText11" msgid="4154476854426920970">"ರೋಮಿಂಗ್ ಬ್ಯಾನರ್ ಆನ್ ಆಗಿದೆ"</string>
<string name="roamingText12" msgid="1189071119992726320">"ರೋಮಿಂಗ್ ಬ್ಯಾನರ್ ಆಫ್ ಆಗಿದೆ"</string>
<string name="roamingTextSearching" msgid="8360141885972279963">"ಸೇವೆ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
- <string name="wfcRegErrorTitle" msgid="2301376280632110664">"Wi-Fi ಕರೆ ಮಾಡುವಿಕೆ"</string>
+ <string name="wfcRegErrorTitle" msgid="2301376280632110664">"ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</string>
<string-array name="wfcOperatorErrorAlertMessages">
- <item msgid="2254967670088539682">"Wi-Fi ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಮತ್ತೆ Wi-Fi ಆನ್ ಮಾಡಿ."</item>
+ <item msgid="2254967670088539682">"ವೈ-ಫೈ ಬಳಸಿಕೊಂಡು ಕರೆ ಮಾಡಲು ಮತ್ತು ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲು, ಮೊದಲು ಈ ಸಾಧನವನ್ನು ಹೊಂದಿಸಲು ನಿಮ್ಮ ವಾಹಕವನ್ನು ಕೇಳಿ. ತದನಂತರ ಸೆಟ್ಟಿಂಗ್ಗಳಲ್ಲಿ ಮತ್ತೆ ವೈ-ಫೈ ಆನ್ ಮಾಡಿ."</item>
</string-array>
<string-array name="wfcOperatorErrorNotificationMessages">
<item msgid="6177300162212449033">"ನಿಮ್ಮ ವಾಹಕದಲ್ಲಿ ನೋಂದಾಯಿಸಿಕೊಳ್ಳಿ"</item>
</string-array>
<string-array name="wfcSpnFormats">
<item msgid="6830082633573257149">"%s"</item>
- <item msgid="4397097370387921767">"%s Wi-Fi ಕರೆ ಮಾಡುವಿಕೆ"</item>
+ <item msgid="4397097370387921767">"%s ವೈ-ಫೈ ಕರೆ ಮಾಡುವಿಕೆ"</item>
</string-array>
<string name="wifi_calling_off_summary" msgid="8720659586041656098">"ಆಫ್"</string>
<string name="wfc_mode_wifi_preferred_summary" msgid="1994113411286935263">"ವೈ-ಫೈಗೆ ಆದ್ಯತೆ ನೀಡಲಾಗಿದೆ"</string>
<string name="wfc_mode_cellular_preferred_summary" msgid="5920549484600758786">"ಸೆಲ್ಯುಲಾರ್ಗೆ ಆದ್ಯತೆ ನೀಡಲಾಗಿದೆ"</string>
- <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"Wi-Fi ಮಾತ್ರ"</string>
+ <string name="wfc_mode_wifi_only_summary" msgid="2379919155237869320">"ವೈ-ಫೈ ಮಾತ್ರ"</string>
<string name="cfTemplateNotForwarded" msgid="1683685883841272560">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: ಫಾರ್ವರ್ಡ್ ಮಾಡಲಾಗಿಲ್ಲ"</string>
<string name="cfTemplateForwarded" msgid="1302922117498590521">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
<string name="cfTemplateForwardedTime" msgid="9206251736527085256">"<xliff:g id="BEARER_SERVICE_CODE">{0}</xliff:g>: <xliff:g id="TIME_DELAY">{2}</xliff:g> ಸೆಕೆಂಡುಗಳ ನಂತರ <xliff:g id="DIALING_NUMBER">{1}</xliff:g>"</string>
@@ -188,7 +188,7 @@
<string name="silent_mode" msgid="7167703389802618663">"ಶಾಂತ ಮೋಡ್"</string>
<string name="turn_on_radio" msgid="3912793092339962371">"ವೈರ್ಲೆಸ್ ಆನ್ ಮಾಡು"</string>
<string name="turn_off_radio" msgid="8198784949987062346">"ವೈರ್ಲೆಸ್ ಆಫ್ ಮಾಡು"</string>
- <string name="screen_lock" msgid="799094655496098153">"ಪರದೆ ಲಾಕ್"</string>
+ <string name="screen_lock" msgid="799094655496098153">"ಸ್ಕ್ರೀನ್ ಲಾಕ್"</string>
<string name="power_off" msgid="4266614107412865048">"ಪವರ್ ಆಫ್ ಮಾಡು"</string>
<string name="silent_mode_silent" msgid="319298163018473078">"ರಿಂಗರ್ ಆಫ್"</string>
<string name="silent_mode_vibrate" msgid="7072043388581551395">"ರಿಂಗರ್ ವೈಬ್ರೇಷನ್"</string>
@@ -212,7 +212,7 @@
<string name="global_actions" product="tablet" msgid="408477140088053665">"ಟ್ಯಾಬ್ಲೆಟ್ ಆಯ್ಕೆಗಳು"</string>
<string name="global_actions" product="tv" msgid="7240386462508182976">"ಟಿವಿ ಆಯ್ಕೆಗಳು"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"ಫೋನ್ ಆಯ್ಕೆಗಳು"</string>
- <string name="global_action_lock" msgid="2844945191792119712">"ಪರದೆ ಲಾಕ್"</string>
+ <string name="global_action_lock" msgid="2844945191792119712">"ಸ್ಕ್ರೀನ್ ಲಾಕ್"</string>
<string name="global_action_power_off" msgid="4471879440839879722">"ಪವರ್ ಆಫ್ ಮಾಡು"</string>
<string name="global_action_bug_report" msgid="7934010578922304799">"ದೋಷದ ವರದಿ"</string>
<string name="bugreport_title" msgid="2667494803742548533">"ದೋಷ ವರದಿ ರಚಿಸಿ"</string>
@@ -357,9 +357,9 @@
<string name="permlab_accessLocationExtraCommands" msgid="2836308076720553837">"ಹೆಚ್ಚುವರಿ ಸ್ಥಾನ ಪೂರೈಕೆದಾರರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permdesc_accessLocationExtraCommands" msgid="6078307221056649927">"ಹೆಚ್ಚಿನ ಸ್ಥಾನ ಪೂರೈಕೆದಾರ ಆದೇಶಗಳನ್ನು ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು GPS ಅಥವಾ ಇತರ ಸ್ಥಾನ ಮೂಲಗಳ ಕಾರ್ಯಾಚರಣೆಯಲ್ಲಿ ಮಧ್ಯ ಪ್ರವೇಶಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಬಹುದು."</string>
<string name="permlab_accessFineLocation" msgid="251034415460950944">"ನಿಖರ ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ (GPS ಮತ್ತು ನೆಟ್ವರ್ಕ್-ಆಧಾರಿತ)"</string>
- <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"ಗ್ಲೊಬಲ್ ಪೊಸಿಷನಿಂಗ್ ಸಿಸ್ಟಮ್ (GPS) ಅಥವಾ ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು Wi-Fi ನಂತಹ ನೆಟ್ವರ್ಕ್ ಸ್ಥಾನ ಮೂಲಗಳನ್ನು ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ನಿಖರವಾದ ಸ್ಥಾನವನ್ನು ಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಅಪ್ಲಿಕೇಶನ್ಗಾಗಿ ಅವುಗಳನ್ನು ಬಳಸಲು ಈ ಸ್ಥಾನ ಸೇವೆಗಳು ಆನ್ ಆಗಿರಬೇಕು ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಲಭ್ಯವಿರಬೇಕು. ನೀವೆಲ್ಲಿರುವಿರಿ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ ಇದನ್ನು ಬಳಸಬಹುದು ಮತ್ತು ಹೆಚ್ಚುವರಿ ಬ್ಯಾಟರಿ ಶಕ್ತಿಯನ್ನು ಬಳಸಬಹುದು."</string>
+ <string name="permdesc_accessFineLocation" msgid="5295047563564981250">"ಗ್ಲೊಬಲ್ ಪೊಸಿಷನಿಂಗ್ ಸಿಸ್ಟಮ್ (GPS) ಅಥವಾ ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನಂತಹ ನೆಟ್ವರ್ಕ್ ಸ್ಥಾನ ಮೂಲಗಳನ್ನು ಬಳಸಿಕೊಂಡು ನಿಮ್ಮ ನಿಖರವಾದ ಸ್ಥಾನವನ್ನು ಪಡೆಯಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಅಪ್ಲಿಕೇಶನ್ಗಾಗಿ ಅವುಗಳನ್ನು ಬಳಸಲು ಈ ಸ್ಥಾನ ಸೇವೆಗಳು ಆನ್ ಆಗಿರಬೇಕು ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಲಭ್ಯವಿರಬೇಕು. ನೀವೆಲ್ಲಿರುವಿರಿ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ ಇದನ್ನು ಬಳಸಬಹುದು ಮತ್ತು ಹೆಚ್ಚುವರಿ ಬ್ಯಾಟರಿ ಶಕ್ತಿಯನ್ನು ಬಳಸಬಹುದು."</string>
<string name="permlab_accessCoarseLocation" msgid="7715277613928539434">"ಅಂದಾಜು ಸ್ಥಳವನ್ನು ಪ್ರವೇಶಿಸಿ (ನೆಟ್ವರ್ಕ್-ಆಧಾರಿತ)"</string>
- <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"ನಿಮ್ಮ ಅಂದಾಜು ಸ್ಥಳವನ್ನು ಪಡೆದುಕೊಳ್ಳಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಈ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು Wi-Fi ನಂತಹ ನೆಟ್ವರ್ಕ್ ಸ್ಥಾನದ ಮೂಲಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಸ್ಥಳದ ಸೇವೆಗಳ ಮೂಲಕ ಪಡೆಯಲಾಗಿದೆ. ಅಪ್ಲಿಕೇಶನ್ಗಾಗಿ ಅವುಗಳನ್ನು ಬಳಸಲು ಈ ಸ್ಥಾನ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಲಭ್ಯವಿರಬೇಕು. ನೀವು ನಿಖರವಾಗಿ ಎಲ್ಲಿರುವಿರಿ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗಳು ಇದನ್ನು ಬಳಸಬಹುದು."</string>
+ <string name="permdesc_accessCoarseLocation" msgid="2538200184373302295">"ನಿಮ್ಮ ಅಂದಾಜು ಸ್ಥಳವನ್ನು ಪಡೆದುಕೊಳ್ಳಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಈ ಸ್ಥಳವನ್ನು ಸೆಲ್ ಟವರ್ಗಳು ಮತ್ತು ವೈ-ಫೈ ನಂತಹ ನೆಟ್ವರ್ಕ್ ಸ್ಥಾನದ ಮೂಲಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಸ್ಥಳದ ಸೇವೆಗಳ ಮೂಲಕ ಪಡೆಯಲಾಗಿದೆ. ಅಪ್ಲಿಕೇಶನ್ಗಾಗಿ ಅವುಗಳನ್ನು ಬಳಸಲು ಈ ಸ್ಥಾನ ಸೇವೆಗಳನ್ನು ಆನ್ ಮಾಡಿರಬೇಕು ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಲಭ್ಯವಿರಬೇಕು. ನೀವು ನಿಖರವಾಗಿ ಎಲ್ಲಿರುವಿರಿ ಎಂಬುದನ್ನು ನಿರ್ಧರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗಳು ಇದನ್ನು ಬಳಸಬಹುದು."</string>
<string name="permlab_modifyAudioSettings" msgid="6095859937069146086">"ನಿಮ್ಮ ಆಡಿಯೊ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="permdesc_modifyAudioSettings" msgid="3522565366806248517">"ವಾಲ್ಯೂಮ್ ರೀತಿಯ ಮತ್ತು ಔಟ್ಪುಟ್ಗಾಗಿ ಯಾವ ಸ್ಪೀಕರ್ ಬಳಸಬೇಕು ಎಂಬ ರೀತಿಯ ಜಾಗತಿಕ ಆಡಿಯೊ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಮಾರ್ಪಡಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
<string name="permlab_recordAudio" msgid="3876049771427466323">"ಆಡಿಯೊ ರೆಕಾರ್ಡ್ ಮಾಡಿ"</string>
@@ -406,14 +406,14 @@
<string name="permdesc_changeNetworkState" msgid="6789123912476416214">"ನೆಟ್ವರ್ಕ್ ಸಂಪರ್ಕದ ಸ್ಥಿತಿಯನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permlab_changeTetherState" msgid="5952584964373017960">"ಟೆಥರಡ್ ಸಂಪರ್ಕತೆಯನ್ನು ಬದಲಾಯಿಸಿ"</string>
<string name="permdesc_changeTetherState" msgid="1524441344412319780">"ಟೆಥರ್ ಮಾಡಲಾದ ನೆಟ್ವರ್ಕ್ ಸಂಪರ್ಕದ ಸ್ಥಿತಿಯನ್ನು ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permlab_accessWifiState" msgid="5202012949247040011">"Wi-Fi ಸಂಪರ್ಕಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
- <string name="permdesc_accessWifiState" msgid="5002798077387803726">"Wi-Fi ಸಕ್ರಿಯಗೊಂಡಿದೆಯೇ ಮತ್ತು ಸಂಪರ್ಕಿಸಲಾದ Wi-Fi ಸಾಧನಗಳ ಹೆಸರಿನ ಮಾಹಿತಿ ರೀತಿಯ, Wi-Fi ನೆಟ್ವರ್ಕ್ ಕುರಿತು ಮಾಹಿತಿಯನ್ನು ವೀಕ್ಷಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
- <string name="permlab_changeWifiState" msgid="6550641188749128035">"Wi-Fi ನಿಂದ ಸಂಪರ್ಕಗೊಳಿಸಿ ಮತ್ತು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿ"</string>
- <string name="permdesc_changeWifiState" msgid="7137950297386127533">"Wi-Fi ಪ್ರವೇಶ ಕೇಂದ್ರಗಳಿಂದ ಸಂಪರ್ಕ ಹೊಂದಲು ಮತ್ತು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲು, ಹಾಗೆಯೇ Wi-Fi ನೆಟ್ವರ್ಕ್ಗಳಿಗೆ ಸಾಧನದ ಕನ್ಫಿಗರೇಶನ್ ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
- <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"Wi-Fi ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಸ್ವೀಕಾರಕ್ಕೆ ಅನುಮತಿಸಿ"</string>
- <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಮಾತ್ರವಲ್ಲದೇ, ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ವಿಳಾಸಗಳನ್ನು ಬಳಸಿಕೊಂಡು Wi-Fi ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ಎಲ್ಲಾ ಸಾಧನಗಳಿಗೆ ಕಳುಹಿಸಲಾಗಿರುವ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಅಲ್ಲದ ಮೋಡ್ ಬಳಸುವ ಶಕ್ತಿಗಿಂತಲೂ ಹೆಚ್ಚಿನ ಶಕ್ತಿಯನ್ನು ಬಳಸುತ್ತದೆ."</string>
- <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"Wi-Fi ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ನಿಮ್ಮ ಟಿವಿ ಮಾತ್ರವಲ್ಲದೆ, ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ವಿಳಾಸಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಎಲ್ಲಾ ಸಾಧನಗಳಿಗೆ ಕಳುಹಿಸಲಾದ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಅಲ್ಲದ ಮೋಡ್ಗಿಂತಲೂ ಹೆಚ್ಚು ಪವರ್ ಬಳಸುತ್ತದೆ."</string>
- <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"ನಿಮ್ಮ ಫೋನ್ ಮಾತ್ರವಲ್ಲದೇ, ಮಲ್ಟಿಕಾಸ್ಟ್ ವಿಳಾಸಗಳನ್ನು ಬಳಸಿಕೊಂಡು Wi-Fi ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ಎಲ್ಲಾ ಸಾಧನಗಳಿಗೆ ಕಳುಹಿಸಲಾಗಿರುವ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಅಲ್ಲದ ಮೋಡ್ ಬಳಸುವ ಶಕ್ತಿಗಿಂತಲೂ ಹೆಚ್ಚಿನ ಶಕ್ತಿಯನ್ನು ಬಳಸುತ್ತದೆ."</string>
+ <string name="permlab_accessWifiState" msgid="5202012949247040011">"ವೈ-ಫೈ ಸಂಪರ್ಕಗಳನ್ನು ವೀಕ್ಷಿಸಿ"</string>
+ <string name="permdesc_accessWifiState" msgid="5002798077387803726">"ವೈ-ಫೈ ಸಕ್ರಿಯಗೊಂಡಿದೆಯೇ ಮತ್ತು ಸಂಪರ್ಕಿಸಲಾದ ವೈ-ಫೈ ಸಾಧನಗಳ ಹೆಸರಿನ ಮಾಹಿತಿ ರೀತಿಯ, ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ ಕುರಿತು ಮಾಹಿತಿಯನ್ನು ವೀಕ್ಷಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ."</string>
+ <string name="permlab_changeWifiState" msgid="6550641188749128035">"ವೈ-ಫೈ ನಿಂದ ಸಂಪರ್ಕಗೊಳಿಸಿ ಮತ್ತು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಿ"</string>
+ <string name="permdesc_changeWifiState" msgid="7137950297386127533">"ವೈ-ಫೈ ಪ್ರವೇಶ ಕೇಂದ್ರಗಳಿಂದ ಸಂಪರ್ಕ ಹೊಂದಲು ಮತ್ತು ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲು, ಹಾಗೆಯೇ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳಿಗೆ ಸಾಧನದ ಕನ್ಫಿಗರೇಶನ್ ಬದಲಾಯಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
+ <string name="permlab_changeWifiMulticastState" msgid="1368253871483254784">"ವೈ-ಫೈ ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಸ್ವೀಕಾರಕ್ಕೆ ಅನುಮತಿಸಿ"</string>
+ <string name="permdesc_changeWifiMulticastState" product="tablet" msgid="7969774021256336548">"ನಿಮ್ಮ ಟ್ಯಾಬ್ಲೆಟ್ ಮಾತ್ರವಲ್ಲದೇ, ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ವಿಳಾಸಗಳನ್ನು ಬಳಸಿಕೊಂಡು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ಎಲ್ಲಾ ಸಾಧನಗಳಿಗೆ ಕಳುಹಿಸಲಾಗಿರುವ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಅಲ್ಲದ ಮೋಡ್ ಬಳಸುವ ಶಕ್ತಿಗಿಂತಲೂ ಹೆಚ್ಚಿನ ಶಕ್ತಿಯನ್ನು ಬಳಸುತ್ತದೆ."</string>
+ <string name="permdesc_changeWifiMulticastState" product="tv" msgid="9031975661145014160">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ನಿಮ್ಮ ಟಿವಿ ಮಾತ್ರವಲ್ಲದೆ, ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ವಿಳಾಸಗಳನ್ನು ಬಳಸಿಕೊಂಡು ಎಲ್ಲಾ ಸಾಧನಗಳಿಗೆ ಕಳುಹಿಸಲಾದ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ. ಇದು ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಅಲ್ಲದ ಮೋಡ್ಗಿಂತಲೂ ಹೆಚ್ಚು ಪವರ್ ಬಳಸುತ್ತದೆ."</string>
+ <string name="permdesc_changeWifiMulticastState" product="default" msgid="6851949706025349926">"ನಿಮ್ಮ ಫೋನ್ ಮಾತ್ರವಲ್ಲದೇ, ಮಲ್ಟಿಕಾಸ್ಟ್ ವಿಳಾಸಗಳನ್ನು ಬಳಸಿಕೊಂಡು ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ನಲ್ಲಿ ಎಲ್ಲಾ ಸಾಧನಗಳಿಗೆ ಕಳುಹಿಸಲಾಗಿರುವ ಪ್ಯಾಕೆಟ್ಗಳನ್ನು ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ನೀಡುತ್ತದೆ. ಇದು ಮಲ್ಟಿಕ್ಯಾಸ್ಟ್ ಅಲ್ಲದ ಮೋಡ್ ಬಳಸುವ ಶಕ್ತಿಗಿಂತಲೂ ಹೆಚ್ಚಿನ ಶಕ್ತಿಯನ್ನು ಬಳಸುತ್ತದೆ."</string>
<string name="permlab_bluetoothAdmin" msgid="6006967373935926659">"ಬ್ಲೂಟೂತ್ ಸೆಟ್ಟಿಂಗ್ಗಳನ್ನು ಪ್ರವೇಶಿಸಿ"</string>
<string name="permdesc_bluetoothAdmin" product="tablet" msgid="6921177471748882137">"ಸ್ಥಳೀಯ ಬ್ಲೂಟೂತ್ ಟ್ಯಾಬ್ಲೆಟ್ ಕಾನ್ಫಿಗರ್ ಮಾಡಲು ಮತ್ತು ಅನ್ವೇಷಿಸಲು ಹಾಗೂ ರಿಮೊಟ್ ಸಾಧನಗಳ ಜೊತೆಗೆ ಜೋಡಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಸುತ್ತದೆ."</string>
<string name="permdesc_bluetoothAdmin" product="tv" msgid="3373125682645601429">"ಸ್ಥಳೀಯ ಬ್ಲೂಟೂತ್ ಟಿವಿಯನ್ನು ಕಾನ್ಫಿಗರ್ ಮಾಡಲು, ಮತ್ತು ಅನ್ವೇಷಿಸಲು ಮತ್ತು ದೂರ ಸಾಧನಗಳೊಂದಿಗೆ ಜೋಡಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
@@ -430,7 +430,7 @@
<string name="permdesc_bluetooth" product="default" msgid="3207106324452312739">"ಫೋನ್ನಲ್ಲಿ ಬ್ಲೂಟೂತ್ ಕಾನ್ಫಿಗರೇಶನ್ ಅನ್ನು ವೀಕ್ಷಿಸಲು ಮತ್ತು ಜೋಡಿ ಮಾಡಿರುವ ಸಾಧನಗಳೊಂದಿಗೆ ಸಂಪರ್ಕಗಳನ್ನು ಕಲ್ಪಿಸಲು ಹಾಗೂ ಸ್ವೀಕರಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅವಕಾಶ ಮಾಡಿಕೊಡುತ್ತದೆ."</string>
<string name="permlab_nfc" msgid="4423351274757876953">"ಸಮೀಪ ಕ್ಷೇತ್ರ ಸಂವಹನವನ್ನು ನಿಯಂತ್ರಿಸಿ"</string>
<string name="permdesc_nfc" msgid="7120611819401789907">"ಸಮೀಪದ ಕ್ಷೇತ್ರ ಸಂವಹನ (NFC) ಟ್ಯಾಗ್ಗಳು, ಕಾರ್ಡ್ಗಳು, ಮತ್ತು ಓದುಗರನ್ನು ಅಪ್ಲಿಕೇಶನ್ ಅನುಮತಿಸುತ್ತದೆ."</string>
- <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ನಿಮ್ಮ ಪರದೆ ಲಾಕ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="permlab_disableKeyguard" msgid="3598496301486439258">"ನಿಮ್ಮ ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಅನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="permdesc_disableKeyguard" msgid="6034203065077122992">"ಕೀಲಾಕ್ ಮತ್ತು ಯಾವುದೇ ಸಂಬಂಧಿತ ಭದ್ರತಾ ಪಾಸ್ವರ್ಡ್ ಭದ್ರತೆಯನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿ ನೀಡುತ್ತದೆ. ಉದಾಹರಣೆಗೆ, ಒಳಬರುವ ಕರೆಯನ್ನು ಸ್ವೀಕರಿಸುವಾಗ ಕೀಲಾಕ್ ಅನ್ನು ಫೋನ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ, ನಂತರ ಕರೆಯು ಅಂತ್ಯಗೊಂಡಾಗ ಕೀಲಾಕ್ ಅನ್ನು ಮರು ಸಕ್ರಿಯಗೊಳಿಸುತ್ತದೆ."</string>
<string name="permlab_manageFingerprint" msgid="5640858826254575638">"ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಹಾರ್ಡ್ವೇರ್ ನಿರ್ವಹಿಸಿ"</string>
<string name="permdesc_manageFingerprint" msgid="178208705828055464">"ಬಳಕೆಗೆ ಫಿಂಗರ್ಪ್ರಿಂಟ್ ಟೆಂಪ್ಲೇಟ್ಗಳನ್ನು ಸೇರಿಸಲು ಮತ್ತು ಅಳಿಸಲು ವಿಧಾನಗಳನ್ನು ಮನವಿ ಮಾಡಲು ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸುತ್ತದೆ."</string>
@@ -522,9 +522,9 @@
<string name="policydesc_watchLogin_secondaryUser" product="tablet" msgid="4280246270601044505">"ಪರದೆಯನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ಟೈಪ್ ಮಾಡಲಾದ ತಪ್ಪಾಗಿರುವ ಪಾಸ್ವರ್ಡ್ಗಳ ಸಂಖ್ಯೆಯನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ಟ್ಯಾಬ್ಲೆಟ್ ಲಾಕ್ ಮಾಡಿ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಟೈಪ್ ಮಾಡಲಾಗಿದ್ದರೆ ಈ ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
<string name="policydesc_watchLogin_secondaryUser" product="TV" msgid="3484832653564483250">"ಪರದೆಯನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ಟೈಪ್ ಮಾಡಲಾದ ತಪ್ಪಾಗಿರುವ ಪಾಸ್ವರ್ಡ್ಗಳ ಸಂಖ್ಯೆಯನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ಟಿವಿಯನ್ನು ಲಾಕ್ ಮಾಡಿ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಟೈಪ್ ಮಾಡಲಾಗಿದ್ದರೆ ಈ ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
<string name="policydesc_watchLogin_secondaryUser" product="default" msgid="2185480427217127147">"ಪರದೆಯನ್ನು ಅನ್ಲಾಕ್ ಮಾಡುವಾಗ ಟೈಪ್ ಮಾಡಲಾದ ತಪ್ಪಾಗಿರುವ ಪಾಸ್ವರ್ಡ್ಗಳ ಸಂಖ್ಯೆಯನ್ನು ವೀಕ್ಷಿಸಿ ಮತ್ತು ಫೋನ್ ಲಾಕ್ ಮಾಡಿ ಅಥವಾ ಹಲವಾರು ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್ಗಳನ್ನು ಟೈಪ್ ಮಾಡಲಾಗಿದ್ದರೆ ಈ ಬಳಕೆದಾರರ ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
- <string name="policylab_resetPassword" msgid="4934707632423915395">"ಪರದೆ ಲಾಕ್ ಬದಲಾಯಿಸಿ"</string>
- <string name="policydesc_resetPassword" msgid="1278323891710619128">"ಪರದೆ ಲಾಕ್ ಬದಲಾಯಿಸಿ."</string>
- <string name="policylab_forceLock" msgid="2274085384704248431">"ಪರದೆ ಲಾಕ್ ಮಾಡಿ"</string>
+ <string name="policylab_resetPassword" msgid="4934707632423915395">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬದಲಾಯಿಸಿ"</string>
+ <string name="policydesc_resetPassword" msgid="1278323891710619128">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಬದಲಾಯಿಸಿ."</string>
+ <string name="policylab_forceLock" msgid="2274085384704248431">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಮಾಡಿ"</string>
<string name="policydesc_forceLock" msgid="1141797588403827138">"ಪರದೆಯು ಯಾವಾಗ ಮತ್ತು ಹೇಗೆ ಲಾಕ್ ಆಗಬೇಕೆಂಬುದನ್ನು ನಿಯಂತ್ರಿಸಿ."</string>
<string name="policylab_wipeData" msgid="3910545446758639713">"ಎಲ್ಲಾ ಡೇಟಾವನ್ನು ಅಳಿಸಿ"</string>
<string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"ಫ್ಯಾಕ್ಟರಿ ಡೇಟಾ ಮರುಹೊಂದಿಕೆಯನ್ನು ನಿರ್ವಹಿಸುವ ಮೂಲಕ ಎಚ್ಚರಿಕೆಯನ್ನು ನೀಡದೆಯೇ ಟ್ಯಾಬ್ಲೆಟ್ ಡೇಟಾವನ್ನು ಅಳಿಸಿಹಾಕಿ."</string>
@@ -536,13 +536,13 @@
<string name="policydesc_wipeData_secondaryUser" product="default" msgid="6787904546711590238">"ಯಾವುದೇ ಸೂಚನೆ ಇಲ್ಲದೆ ಈ ಫೋನ್ನಲ್ಲಿ ಈ ಬಳಕೆದಾರರ ಡೇಟಾವನ್ನು ಅಳಿಸಿ."</string>
<string name="policylab_setGlobalProxy" msgid="2784828293747791446">"ಸಾಧನವನ್ನು ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಗೆ ಹೊಂದಿಸಿ"</string>
<string name="policydesc_setGlobalProxy" msgid="8459859731153370499">"ನೀತಿಯನ್ನು ಸಕ್ರಿಯಗೊಳಿಸಿದಾಗ ಬಳಸಬೇಕಾದ ಸಾಧನದ ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಯನ್ನು ಹೊಂದಿಸಿ. ಸಾಧನದ ಮಾಲೀಕರು ಮಾತ್ರ ಜಾಗತಿಕ ಪ್ರಾಕ್ಸಿಯನ್ನು ಹೊಂದಿಸಬಹುದಾಗಿರುತ್ತದೆ."</string>
- <string name="policylab_expirePassword" msgid="5610055012328825874">"ಪರದೆ ಲಾಕ್ ಪಾಸ್ವರ್ಡ್ ಮುಕ್ತಾಯವನ್ನು ಹೊಂದಿಸಿ"</string>
- <string name="policydesc_expirePassword" msgid="5367525762204416046">"ಪರದೆ ಲಾಕ್ ಪಾಸ್ವರ್ಡ್, ಪಿನ್, ಅಥವಾ ನಮೂನೆಯನ್ನು ಹೆಚ್ಚು ಪದೆ ಪದೇ ಬದಲಾಯಿಸಬೇಕಾಗಿರುತ್ತದೆ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸಿ."</string>
+ <string name="policylab_expirePassword" msgid="5610055012328825874">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಪಾಸ್ವರ್ಡ್ ಮುಕ್ತಾಯವನ್ನು ಹೊಂದಿಸಿ"</string>
+ <string name="policydesc_expirePassword" msgid="5367525762204416046">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಪಾಸ್ವರ್ಡ್, ಪಿನ್, ಅಥವಾ ನಮೂನೆಯನ್ನು ಹೆಚ್ಚು ಪದೆ ಪದೇ ಬದಲಾಯಿಸಬೇಕಾಗಿರುತ್ತದೆ ಎಂಬುದನ್ನು ಬದಲಾಯಿಸಿ."</string>
<string name="policylab_encryptedStorage" msgid="8901326199909132915">"ಸಂಗ್ರಹಣೆ ಎನ್ಕ್ರಿಪ್ಶನ್ ಹೊಂದಿಸಿ"</string>
<string name="policydesc_encryptedStorage" msgid="2637732115325316992">"ಸಂಗ್ರಹಿಸಿರುವ ಅಪ್ಲಿಕೇಶನ್ ಡೇಟಾವನ್ನು ಎನ್ಕ್ರಿಪ್ಟ್ ಮಾಡಬೇಕಾದ ಅಗತ್ಯವಿದೆ."</string>
<string name="policylab_disableCamera" msgid="6395301023152297826">"ಕ್ಯಾಮರಾಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="policydesc_disableCamera" msgid="2306349042834754597">"ಎಲ್ಲಾ ಸಾಧನ ಕ್ಯಾಮರಾಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
- <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"ಕೆಲವು ಪರದೆ ಲಾಕ್ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
+ <string name="policylab_disableKeyguardFeatures" msgid="8552277871075367771">"ಕೆಲವು ಸ್ಕ್ರೀನ್ ಲಾಕ್ ವೈಶಿಷ್ಟ್ಯಗಳನ್ನು ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="policydesc_disableKeyguardFeatures" msgid="2044755691354158439">"ಕೆಲವು ಪರದೆ ಲಾಕ್ನ ವೈಶಿಷ್ಟ್ಯಗಳ ಬಳಕೆಯನ್ನು ತಡೆಯಿರಿ."</string>
<string-array name="phoneTypes">
<item msgid="8901098336658710359">"ನಿವಾಸ"</item>
@@ -669,7 +669,7 @@
<string name="keyguard_label_text" msgid="861796461028298424">"ಅನ್ಲಾಕ್ ಮಾಡಲು, ಮೆನು ನಂತರ 0 ಒತ್ತಿರಿ."</string>
<string name="emergency_call_dialog_number_for_display" msgid="696192103195090970">"ತುರ್ತು ಸಂಖ್ಯೆ"</string>
<string name="lockscreen_carrier_default" msgid="6169005837238288522">"ಯಾವುದೇ ಸೇವೆಯಿಲ್ಲ"</string>
- <string name="lockscreen_screen_locked" msgid="7288443074806832904">"ಪರದೆ ಲಾಕ್ ಆಗಿದೆ."</string>
+ <string name="lockscreen_screen_locked" msgid="7288443074806832904">"ಸ್ಕ್ರೀನ್ ಲಾಕ್ ಆಗಿದೆ."</string>
<string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಮೆನು ಒತ್ತಿರಿ ಇಲ್ಲವೇ ತುರ್ತು ಕರೆಯನ್ನು ಮಾಡಿ."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಮೆನು ಒತ್ತಿರಿ."</string>
<string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"ಅನ್ಲಾಕ್ ಮಾಡಲು ಪ್ಯಾಟರ್ನ್ ಚಿತ್ರಿಸಿ"</string>
@@ -891,6 +891,38 @@
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>ವ ನಲ್ಲಿ</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>ವ ನಲ್ಲಿ</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ನಿಮಿಷಗಳ ಹಿಂದೆ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ನಿಮಿಷಗಳ ಹಿಂದೆ</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ಗಂಟೆಗಳ ಹಿಂದೆ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ಗಂಟೆಗಳ ಹಿಂದೆ</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ದಿನಗಳ ಹಿಂದೆ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ದಿನಗಳ ಹಿಂದೆ</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ವರ್ಷಗಳ ಹಿಂದೆ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ವರ್ಷಗಳ ಹಿಂದೆ</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ನಿಮಿಷಗಳಲ್ಲಿ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ನಿಮಿಷಗಳಲ್ಲಿ </item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ಗಂಟೆಗಳಲ್ಲಿ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ಗಂಟೆಗಳಲ್ಲಿ</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ದಿನಗಳಲ್ಲಿ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ದಿನಗಳಲ್ಲಿ</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ವರ್ಷಗಳಲ್ಲಿ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ವರ್ಷಗಳಲ್ಲಿ</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"ವೀಡಿಯೊ ಸಮಸ್ಯೆ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ಈ ಸಾಧನಲ್ಲಿ ಸ್ಟ್ರೀಮ್ ಮಾಡಲು ಈ ವೀಡಿಯೊ ಮಾನ್ಯವಾಗಿಲ್ಲ."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ಈ ವೀಡಿಯೊ ಪ್ಲೇ ಮಾಡಲು ಸಾಧ್ಯವಿಲ್ಲ."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> ನಿಲ್ಲಿಸಿದೆ"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> ನಿಲ್ಲುತ್ತಲೇ ಇರುತ್ತದೆ"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> ನಿಲ್ಲುತ್ತಲೇ ಇರುತ್ತದೆ"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"ಅಪ್ಲಿಕೇಶನ್ ಮರುಪ್ರಾರಂಭಿಸಿ"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"ಅಪ್ಲಿಕೇಶನ್ ಮರುಹೊಂದಿಸಿ ಮತ್ತು ಮರುಪ್ರಾರಂಭಿಸಿ"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"ಅಪ್ಲಿಕೇಶನ್ ಮತ್ತೆ ತೆರೆಯಿರಿ"</string>
<string name="aerr_report" msgid="5371800241488400617">"ಪ್ರತಿಕ್ರಿಯೆ ಕಳುಹಿಸು"</string>
<string name="aerr_close" msgid="2991640326563991340">"ಮುಚ್ಚು"</string>
<string name="aerr_mute" msgid="1974781923723235953">"ಸಾಧನವು ಮರುಪ್ರಾರಂಭವಾಗುವವರೆಗೂ ಮ್ಯೂಟ್ ಮಾಡಿ"</string>
@@ -1028,28 +1059,28 @@
<string name="ringtone_picker_title" msgid="3515143939175119094">"ರಿಂಗ್ಟೋನ್ಗಳು"</string>
<string name="ringtone_unknown" msgid="5477919988701784788">"ಅಜ್ಞಾತ ರಿಂಗ್ಟೋನ್"</string>
<plurals name="wifi_available" formatted="false" msgid="7900333017752027322">
- <item quantity="one">Wi-Fi ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item>
- <item quantity="other">Wi-Fi ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item>
+ <item quantity="one">ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item>
+ <item quantity="other">ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item>
</plurals>
<plurals name="wifi_available_detailed" formatted="false" msgid="1140699367193975606">
- <item quantity="one">ಮುಕ್ತ Wi-Fi ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item>
- <item quantity="other">ಮುಕ್ತ Wi-Fi ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item>
+ <item quantity="one">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item>
+ <item quantity="other">ಮುಕ್ತ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿವೆ</item>
</plurals>
- <string name="wifi_available_sign_in" msgid="9157196203958866662">"Wi-Fi ನೆಟ್ವರ್ಕ್ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
+ <string name="wifi_available_sign_in" msgid="9157196203958866662">"ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
<string name="network_available_sign_in" msgid="1848877297365446605">"ನೆಟ್ವರ್ಕ್ಗೆ ಸೈನ್ ಇನ್ ಮಾಡಿ"</string>
<!-- no translation found for network_available_sign_in_detailed (8000081941447976118) -->
<skip />
<string name="wifi_no_internet" msgid="8451173622563841546">"ವೈ-ಫೈ ಯಾವುದೇ ಇಂಟರ್ನೆಟ್ ಪ್ರವೇಶವನ್ನು ಹೊಂದಿಲ್ಲ"</string>
<string name="wifi_no_internet_detailed" msgid="8083079241212301741">"ಆಯ್ಕೆಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
- <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"Wi-Fi ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
+ <string name="wifi_watchdog_network_disabled" msgid="7904214231651546347">"ವೈ-ಫೈ ಗೆ ಸಂಪರ್ಕಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ"</string>
<string name="wifi_watchdog_network_disabled_detailed" msgid="5548780776418332675">" ಕಳಪೆ ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವನ್ನು ಹೊಂದಿದೆ."</string>
<string name="wifi_connect_alert_title" msgid="8455846016001810172">"ಸಂಪರ್ಕವನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
<string name="wifi_connect_alert_message" msgid="6451273376815958922">"%2$s ವೈಫೈ ನೆಟ್ವರ್ಕ್ಗೆ ಸಂಪರ್ಕಿಸಲು %1$s ಅಪ್ಲಿಕೇಶನ್ ಬಯಸುತ್ತದೆ"</string>
<string name="wifi_connect_default_application" msgid="7143109390475484319">"ಅಪ್ಲಿಕೇಶನ್"</string>
- <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"Wi-Fi ಡೈರೆಕ್ಟ್"</string>
- <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"Wi-Fi ಡೈರೆಕ್ಟ್ ಪ್ರಾರಂಭಿಸಿ. ಇದು Wi-Fi ಕ್ಲೈಂಟ್/ಹಾಟ್ಸ್ಪಾಟ್ ಅನ್ನು ಆಫ್ ಮಾಡುತ್ತದೆ."</string>
- <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"Wi-Fi ಡೈರೆಕ್ಟ್ ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ."</string>
- <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"Wi-Fi ಡೈರೆಕ್ಟ್ ಆನ್ ಆಗಿದೆ"</string>
+ <string name="wifi_p2p_dialog_title" msgid="97611782659324517">"ವೈ-ಫೈ ಡೈರೆಕ್ಟ್"</string>
+ <string name="wifi_p2p_turnon_message" msgid="2909250942299627244">"ವೈ-ಫೈ ಡೈರೆಕ್ಟ್ ಪ್ರಾರಂಭಿಸಿ. ಇದು ವೈ-ಫೈ ಕ್ಲೈಂಟ್/ಹಾಟ್ಸ್ಪಾಟ್ ಅನ್ನು ಆಫ್ ಮಾಡುತ್ತದೆ."</string>
+ <string name="wifi_p2p_failed_message" msgid="3763669677935623084">"ವೈ-ಫೈ ಡೈರೆಕ್ಟ್ ಪ್ರಾರಂಭಿಸಲು ಸಾಧ್ಯವಾಗುತ್ತಿಲ್ಲ."</string>
+ <string name="wifi_p2p_enabled_notification_title" msgid="2068321881673734886">"ವೈ-ಫೈ ಡೈರೆಕ್ಟ್ ಆನ್ ಆಗಿದೆ"</string>
<string name="wifi_p2p_enabled_notification_message" msgid="8064677407830620023">"ಸೆಟ್ಟಿಂಗ್ಗಳಿಗೆ ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="accept" msgid="1645267259272829559">"ಸ್ವೀಕರಿಸು"</string>
<string name="decline" msgid="2112225451706137894">"ನಿರಾಕರಿಸು"</string>
@@ -1059,9 +1090,9 @@
<string name="wifi_p2p_to_message" msgid="248968974522044099">"ಗೆ:"</string>
<string name="wifi_p2p_enter_pin_message" msgid="5920929550367828970">"ಅಗತ್ಯವಿರುವ ಪಿನ್ ಟೈಪ್ ಮಾಡಿ:"</string>
<string name="wifi_p2p_show_pin_message" msgid="8530563323880921094">"ಪಿನ್:"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ಟ್ಯಾಬ್ಲೆಟ್ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಾಗ ಅದನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ Wi-Fi ನಿಂದ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗುತ್ತದೆ"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಳಿಸಿರುವಾಗ ಟಿವಿಯನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ Wi-Fi ನಿಂದ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿರುತ್ತದೆ"</string>
- <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ಫೋನ್ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಾಗ Wi-Fi ನಿಂದ ಅದು ತಾತ್ಕಾಲಿಕವಾಗಿ ಸಂಪರ್ಕ ಕಡಿತಗೊಳ್ಳುತ್ತದೆ"</string>
+ <string name="wifi_p2p_frequency_conflict_message" product="tablet" msgid="8012981257742232475">"ಟ್ಯಾಬ್ಲೆಟ್ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಾಗ ಅದನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ವೈ-ಫೈ ನಿಂದ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗುತ್ತದೆ"</string>
+ <string name="wifi_p2p_frequency_conflict_message" product="tv" msgid="3087858235069421128">"<xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಳಿಸಿರುವಾಗ ಟಿವಿಯನ್ನು ತಾತ್ಕಾಲಿಕವಾಗಿ ವೈ-ಫೈ ನಿಂದ ಸಂಪರ್ಕ ಕಡಿತಗೊಳಿಸಲಾಗಿರುತ್ತದೆ"</string>
+ <string name="wifi_p2p_frequency_conflict_message" product="default" msgid="7363907213787469151">"ಫೋನ್ <xliff:g id="DEVICE_NAME">%1$s</xliff:g> ಗೆ ಸಂಪರ್ಕಗೊಂಡಿರುವಾಗ ವೈ-ಫೈ ನಿಂದ ಅದು ತಾತ್ಕಾಲಿಕವಾಗಿ ಸಂಪರ್ಕ ಕಡಿತಗೊಳ್ಳುತ್ತದೆ"</string>
<string name="select_character" msgid="3365550120617701745">"ಅಕ್ಷರವನ್ನು ಸೇರಿಸಿ"</string>
<string name="sms_control_title" msgid="7296612781128917719">"SMS ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸಲಾಗುತ್ತಿದೆ"</string>
<string name="sms_control_message" msgid="3867899169651496433">"<b><xliff:g id="APP_NAME">%1$s</xliff:g></b> ಹೆಚ್ಚಿನ ಸಂಖ್ಯೆಯ SMS ಸಂದೇಶಗಳನ್ನು ಕಳುಹಿಸುತ್ತಿದೆ. ಸಂದೇಶಗಳ ಕಳುಹಿಸುವಿಕೆಯನ್ನು ಮುಂದುವರಿಸುವಂತೆ ಈ ಅಪ್ಲಿಕೇಶನ್ಗೆ ಅನುಮತಿಸಲು ನೀವು ಬಯಸುವಿರಾ?"</string>
@@ -1290,12 +1321,12 @@
<string name="data_usage_3g_limit_title" msgid="4361523876818447683">"2G-3G ಡೇಟಾ ಮೀತಿಯನ್ನು ತಲುಪಿದೆ"</string>
<string name="data_usage_4g_limit_title" msgid="4609566827219442376">"4G ಡೇಟಾ ಮೀತಿಯನ್ನು ತಲುಪಿದೆ"</string>
<string name="data_usage_mobile_limit_title" msgid="557158376602636112">"ಸೆಲ್ಯುಲಾರ್ ಡೇಟಾ ಮಿತಿಯನ್ನು ತಲುಪಿದೆ"</string>
- <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"Wi-Fi ಡೇಟಾ ಮಿತಿಯನ್ನು ತಲುಪಿದೆ"</string>
+ <string name="data_usage_wifi_limit_title" msgid="5803363779034792676">"ವೈ-ಫೈ ಡೇಟಾ ಮಿತಿಯನ್ನು ತಲುಪಿದೆ"</string>
<string name="data_usage_limit_body" msgid="291731708279614081">"ಉಳಿದಿರುವ ಆವರ್ತನೆಗೆ ಡೇಟಾವನ್ನು ವಿರಾಮಗೊಳಿಸಲಾಗಿದೆ"</string>
<string name="data_usage_3g_limit_snoozed_title" msgid="7026739121138005231">"2G-3G ಡೇಟಾ ಮಿತಿ ಮೀರಿದೆ"</string>
<string name="data_usage_4g_limit_snoozed_title" msgid="1106562779311209039">"4G ಡೇಟಾ ಮಿತಿ ಮೀರಿದೆ"</string>
<string name="data_usage_mobile_limit_snoozed_title" msgid="4941346653729943789">"ಸೆಲ್ಯುಲಾರ್ ಡೇಟಾ ಮಿತಿ ಮೀರಿದೆ"</string>
- <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"Wi-Fi ಡೇಟಾ ಮಿತಿ ಮೀರಿದೆ"</string>
+ <string name="data_usage_wifi_limit_snoozed_title" msgid="8743856006384825974">"ವೈ-ಫೈ ಡೇಟಾ ಮಿತಿ ಮೀರಿದೆ"</string>
<string name="data_usage_limit_snoozed_body" msgid="7035490278298441767">"<xliff:g id="SIZE">%s</xliff:g> ನಿರ್ದಿಷ್ಟಪಡಿಸಿದ ಮಿತಿ ಮೀರಿದೆ."</string>
<string name="data_usage_restricted_title" msgid="5965157361036321914">"ಹಿನ್ನೆಲೆ ಡೇಟಾವನ್ನು ನಿರ್ಬಂಧಿಸಲಾಗಿದೆ"</string>
<string name="data_usage_restricted_body" msgid="469866376337242726">"ನಿರ್ಬಂಧವನ್ನು ತೆಗೆದುಹಾಕಲು ಟ್ಯಾಪ್ ಮಾಡಿ."</string>
@@ -1349,7 +1380,7 @@
<string name="display_manager_overlay_display_secure_suffix" msgid="6022119702628572080">", ಸುರಕ್ಷಿತ"</string>
<string name="kg_forgot_pattern_button_text" msgid="8852021467868220608">"ಪ್ಯಾಟರ್ನ್ ಅನ್ನು ಮರೆತಿರುವಿರಿ"</string>
<string name="kg_wrong_pattern" msgid="1850806070801358830">"ತಪ್ಪು ಪ್ಯಾಟರ್ನ್"</string>
- <string name="kg_wrong_password" msgid="2333281762128113157">"ತಪ್ಪಾದ ಪಾಸ್ವರ್ಡ್"</string>
+ <string name="kg_wrong_password" msgid="2333281762128113157">"ತಪ್ಪು ಪಾಸ್ವರ್ಡ್"</string>
<string name="kg_wrong_pin" msgid="1131306510833563801">"ತಪ್ಪಾದ ಪಿನ್"</string>
<string name="kg_too_many_failed_attempts_countdown" msgid="6358110221603297548">"<xliff:g id="NUMBER">%1$d</xliff:g> ಸೆಕೆಂಡುಗಳಲ್ಲಿ ಮತ್ತೆ ಪ್ರಯತ್ನಿಸಿ."</string>
<string name="kg_pattern_instructions" msgid="398978611683075868">"ನಿಮ್ಮ ನಮೂನೆಯನ್ನು ಚಿತ್ರಿಸಿ"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ಅಳಿಸಲಾಗಿದೆ"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ಕೆಲಸ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ಈ ಪರದೆಯನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಹಿಂಂದೆ ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ಈ ಪರದೆಯನ್ನು ಅನ್ಪಿನ್ ಮಾಡಲು, ಅವಲೋಕನವನ್ನು ಸ್ಪರ್ಶಿಸಿ ಮತ್ತು ಒತ್ತಿ ಹಿಡಿಯಿರಿ."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ಅಪ್ಲಿಕೇಶನ್ ಪಿನ್ ಮಾಡಲಾಗಿದೆ: ಈ ಸಾಧನದಲ್ಲಿ ಅನ್ಪಿನ್ ಮಾಡುವುದನ್ನು ಅನುಮತಿಸಲಾಗುವುದಿಲ್ಲ."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ಸ್ಕ್ರೀನ್ ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"ಸ್ಕ್ರೀನ್ ಅನ್ಪಿನ್ ಮಾಡಲಾಗಿದೆ"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ವಿನಂತಿಯನ್ನು USSD ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ವಿನಂತಿಯನ್ನು ಹೊಸ SS ವಿನಂತಿಗೆ ಮಾರ್ಪಡಿಸಲಾಗಿದೆ."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ಉದ್ಯೋಗ ಪ್ರೊಫೈಲ್"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"ವಿಸ್ತರಿಸು ಬಟನ್"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB ಪೆರಿಪೆರಲ್ ಪೋರ್ಟ್"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB ಪೆರಿಪೆರಲ್ ಪೋರ್ಟ್"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"ಅನ್ಪಿನ್"</string>
<string name="app_info" msgid="6856026610594615344">"ಅಪ್ಲಿಕೇಶನ್ ಮಾಹಿತಿ"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"ಸೆಶನ್ ಮರುಪ್ರಾರಂಭಿಸಿ"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"ಹೊಸ ಡೆಮೊ ಸೆಶನ್ ಪ್ರಾರಂಭಿಸಲು ಟ್ಯಾಪ್ ಮಾಡಿ"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"ನಿರ್ಬಂಧಗಳು ಇಲ್ಲದೆಯೇ ಈ ಸಾಧನವನ್ನು ಬಳಸಲು ಫ್ಯಾಕ್ಟರಿ ಮರುಹೊಂದಿಸಿ"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"ಇನ್ನಷ್ಟು ತಿಳಿಯಲು ಸ್ಪರ್ಶಿಸಿ."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಲಾಗಿದೆ"</string>
</resources>
diff --git a/core/res/res/values-ko/strings.xml b/core/res/res/values-ko/strings.xml
index 6cb295c..76cda4b 100644
--- a/core/res/res/values-ko/strings.xml
+++ b/core/res/res/values-ko/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>년 후</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>년 후</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>분 전</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>분 전</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>시간 전</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>시간 전</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>일 전</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>일 전</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>년 전</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>년 전</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>분 후</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>분 후</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>시간 후</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>시간 후</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>일 후</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>일 후</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>년 후</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>년 후</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"영상 문제"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"이 기기로 스트리밍하기에 적합하지 않은 동영상입니다."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"동영상을 재생할 수 없습니다."</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g>이(가) 중지됨"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g>이(가) 계속 중단됨"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g>이(가) 계속 중단됨"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"앱 다시 시작"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"앱 재설정 및 다시 시작"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"의견 보내기"</string>
<string name="aerr_close" msgid="2991640326563991340">"닫기"</string>
<string name="aerr_mute" msgid="1974781923723235953">"기기가 다시 시작될 때까지 알림 끄기"</string>
@@ -1512,7 +1544,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 삭제됨"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"업무용 <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"이 화면을 고정 해제하려면 \'뒤로\'를 길게 터치합니다."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"이 화면을 고정 해제하려면 \'최근 사용\'을 길게 터치합니다."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"앱이 고정되었습니다. 이 기기에서는 고정 해제를 허용하지 않습니다."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"화면 고정됨"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"화면 고정 해제됨"</string>
@@ -1579,6 +1610,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS 요청이 USSD 요청으로 수정됩니다."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS 요청이 새로운 SS 요청으로 수정됩니다."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"직장 프로필"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB 주변기기 포트"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB 주변기기 포트"</string>
@@ -1616,8 +1651,11 @@
<string name="unpin_target" msgid="3556545602439143442">"고정 해제"</string>
<string name="app_info" msgid="6856026610594615344">"앱 정보"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"제한 없이 기기를 사용하기 위한 초기화"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"자세한 내용을 보려면 터치하세요."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> 사용 중지됨"</string>
</resources>
diff --git a/core/res/res/values-ky-rKG/strings.xml b/core/res/res/values-ky-rKG/strings.xml
index 9a1acfa..5db7343 100644
--- a/core/res/res/values-ky-rKG/strings.xml
+++ b/core/res/res/values-ky-rKG/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ж. кийин</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ж. кийин</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> мүнөт мурун</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> мүнөт мурун</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> саат мурун</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> саат мурун</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> күн мурун</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> күн мурун</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> жыл мурун</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> жыл мурун</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> мүнөттөн кийин</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> мүнөттөн кийин</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> сааттан кийин</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> сааттан кийин</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> күндөн кийин</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> күндөн кийин</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> жылдан кийин</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> жылдан кийин</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Видео маселеси"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Бул видеону ушул түзмөктө агылтып көрсөтүү мүмкүн эмес."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Бул видеону ойнотуу мүмкүн эмес."</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> токтотулду"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> колдонмосу иштебей калып жатат"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> колдонмосу иштебей калып жатат"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Колдонмону кайра жүргүзүү"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Колдонмону баштапкы абалга келтирип, кайра жүргүзүү"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Жооп пикир жөнөтүү"</string>
<string name="aerr_close" msgid="2991640326563991340">"Жабуу"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Түзмөк өчүрүлүп-күйгүзүлгүчө үнүн өчүрүү"</string>
@@ -1515,7 +1547,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> өчүрүлдү"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Жумуш <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Бул экранды бошотуу үчүн \"Артка\" баскычын басып, кармап туруңуз."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Бул экранды бошотуу үчүн \"Көз жүгүртүү\" баскычын басып, кармап туруңуз."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Колдонмо кадалган: Бул түзмөктө бошотууга уруксат жок."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Экран кадалды"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Экран бошотулду"</string>
@@ -1582,6 +1613,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS сурамы USSD сурамына өзгөртүлдү."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS сурамы жаңы SS сурамына өзгөртүлдү."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Жумуш профили"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Сырткы оюкча"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Сырткы оюкча"</string>
@@ -1619,8 +1654,11 @@
<string name="unpin_target" msgid="3556545602439143442">"Кадоодон алып коюу"</string>
<string name="app_info" msgid="6856026610594615344">"Колдонмо тууралуу"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Бул түзмөктү чектөөсүз колдонуу үчүн аны баштапкы абалга келтириңиз"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Көбүрөөк билүү үчүн тийип коюңуз."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> өчүрүлдү"</string>
</resources>
diff --git a/core/res/res/values-lo-rLA/strings.xml b/core/res/res/values-lo-rLA/strings.xml
index ee30deb..5e5c5af 100644
--- a/core/res/res/values-lo-rLA/strings.xml
+++ b/core/res/res/values-lo-rLA/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">ໃນ <xliff:g id="COUNT_1">%d</xliff:g>ປ</item>
<item quantity="one">ໃນ <xliff:g id="COUNT_0">%d</xliff:g>ປ</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ນາທີກ່ອນ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ນາທີກ່ອນ</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ຊົ່ວໂມງກ່ອນ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ຊົ່ວໂມງກ່ອນ</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ມື້ກ່ອນ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ມື້ກ່ອນ</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ປີກ່ອນ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ປີກ່ອນ</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">ໃນ <xliff:g id="COUNT_1">%d</xliff:g> ນາທີ</item>
+ <item quantity="one">ໃນ <xliff:g id="COUNT_0">%d</xliff:g> ນາທີ</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">ໃນ <xliff:g id="COUNT_1">%d</xliff:g> ຊົ່ວໂມງ</item>
+ <item quantity="one">ໃນ <xliff:g id="COUNT_0">%d</xliff:g> ຊົ່ວໂມງ</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">ໃນ <xliff:g id="COUNT_1">%d</xliff:g> ມື້</item>
+ <item quantity="one">ໃນ <xliff:g id="COUNT_0">%d</xliff:g> ມື້</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">ໃນ <xliff:g id="COUNT_1">%d</xliff:g> ປີ</item>
+ <item quantity="one">ໃນ <xliff:g id="COUNT_0">%d</xliff:g> ປີ</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"ບັນຫາວິດີໂອ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ວິດີໂອນີ້ບໍ່ຖືກຕ້ອງສຳລັບການສະແດງໃນອຸປະກອນນີ້."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ບໍ່ສາມາດຫຼິ້ນວິດີໂອນີ້ໄດ້."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> ໄດ້ຢຸດແລ້ວ"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> ຢຸດເລື້ອຍໆ"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> ຢຸດເລື້ອຍໆ"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"ເລີ່ມແອັບໃໝ່"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"ຣີເຊັດ ແລະ ເລີ່ມແອັບໃໝ່"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"ເປີດແອັບອີກຄັ້ງ"</string>
<string name="aerr_report" msgid="5371800241488400617">"ສົ່ງຄຳຕິຊົມ"</string>
<string name="aerr_close" msgid="2991640326563991340">"ປິດ"</string>
<string name="aerr_mute" msgid="1974781923723235953">"ປິດສຽງຈົນກວ່າວ່າອຸປະກອນເລີ່ມໃໝ່"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ຖືກລຶບແລ້ວ"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ບ່ອນເຮັດວຽກ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ກົດປຸ່ມກັບຄືນຄ້າງໄວ້ເພື່ອເຊົາປັກໝຸດໜ້າຈໍນີ້."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ກົດປຸ່ມພາບຮວມຄ້າງໄວ້ເພື່ອເຊົາປັກໝຸດໜ້າຈໍນີ້."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ແອັບຖືກປັກໝຸດແລ້ວ: ບໍ່ອະນຸຍາດໃຫ້ຖອນປັກໝຸດຢູ່ເທິງອຸປະກອນນີ້."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ປັກໝຸດໜ້າຈໍແລ້ວ"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"ຍົກເລີກການປັກໝຸນຫນ້າຈໍແລ້ວ"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"ການຂໍ SS ຖືກດັດແປງເປັນການຂໍ USSD ແລ້ວ."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"ການຂໍ SS ຖືກດັດແປງເປັນການຂໍ SS ໃໝ່ແລ້ວ."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ໂປຣໄຟລ໌ບ່ອນເຮັດວຽກ"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"ປຸ່ມຂະຫຍາຍ"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"ຜອດຮອບນອກ Android USB"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"ຜອດຮອບນອກ USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"ຖອນປັກໝຸດ"</string>
<string name="app_info" msgid="6856026610594615344">"ຂໍ້ມູນແອັບ"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"ເລີ່ມເຊດຊັນຄືນໃໝ່"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"ແຕະເພື່ອເລີ່ມເຊດຊັນເດໂມໃໝ່"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"ຣີເຊັດໃຫ້ເປັນຄ່າໂຮງງານເພື່ອໃຊ້ອຸປະກອນນີ້ໂດຍບໍ່ມີຂໍ້ຈຳກັດ"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"ແຕະເພື່ອສຶກສາເພີ່ມເຕີມ."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"ປິດການນຳໃຊ້ <xliff:g id="LABEL">%1$s</xliff:g> ແລ້ວ"</string>
</resources>
diff --git a/core/res/res/values-lt/strings.xml b/core/res/res/values-lt/strings.xml
index 7204328..cfbddfd 100644
--- a/core/res/res/values-lt/strings.xml
+++ b/core/res/res/values-lt/strings.xml
@@ -921,6 +921,54 @@
<item quantity="many">po <xliff:g id="COUNT_1">%d</xliff:g> m.</item>
<item quantity="other">po <xliff:g id="COUNT_1">%d</xliff:g> m.</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">prieš <xliff:g id="COUNT_1">%d</xliff:g> minutę</item>
+ <item quantity="few">prieš <xliff:g id="COUNT_1">%d</xliff:g> minutes</item>
+ <item quantity="many">prieš <xliff:g id="COUNT_1">%d</xliff:g> minutės</item>
+ <item quantity="other">prieš <xliff:g id="COUNT_1">%d</xliff:g> minučių</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">prieš <xliff:g id="COUNT_1">%d</xliff:g> valandą</item>
+ <item quantity="few">prieš <xliff:g id="COUNT_1">%d</xliff:g> valandas</item>
+ <item quantity="many">prieš <xliff:g id="COUNT_1">%d</xliff:g> valandos</item>
+ <item quantity="other">prieš <xliff:g id="COUNT_1">%d</xliff:g> valandų</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">prieš <xliff:g id="COUNT_1">%d</xliff:g> dieną</item>
+ <item quantity="few">prieš <xliff:g id="COUNT_1">%d</xliff:g> dienas</item>
+ <item quantity="many">prieš <xliff:g id="COUNT_1">%d</xliff:g> dienos</item>
+ <item quantity="other">prieš <xliff:g id="COUNT_1">%d</xliff:g> dienų</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">prieš <xliff:g id="COUNT_1">%d</xliff:g> metus</item>
+ <item quantity="few">prieš <xliff:g id="COUNT_1">%d</xliff:g> metus</item>
+ <item quantity="many">prieš <xliff:g id="COUNT_1">%d</xliff:g> metų</item>
+ <item quantity="other">prieš <xliff:g id="COUNT_1">%d</xliff:g> metų</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">po <xliff:g id="COUNT_1">%d</xliff:g> minutės</item>
+ <item quantity="few">po <xliff:g id="COUNT_1">%d</xliff:g> minučių</item>
+ <item quantity="many">po <xliff:g id="COUNT_1">%d</xliff:g> minutės</item>
+ <item quantity="other">po <xliff:g id="COUNT_1">%d</xliff:g> minučių</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">po <xliff:g id="COUNT_1">%d</xliff:g> valandos</item>
+ <item quantity="few">po <xliff:g id="COUNT_1">%d</xliff:g> valandų</item>
+ <item quantity="many">po <xliff:g id="COUNT_1">%d</xliff:g> valandos</item>
+ <item quantity="other">po <xliff:g id="COUNT_1">%d</xliff:g> valandų</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">po <xliff:g id="COUNT_1">%d</xliff:g> dienos</item>
+ <item quantity="few">po <xliff:g id="COUNT_1">%d</xliff:g> dienų</item>
+ <item quantity="many">po <xliff:g id="COUNT_1">%d</xliff:g> dienos</item>
+ <item quantity="other">po <xliff:g id="COUNT_1">%d</xliff:g> dienų</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">po <xliff:g id="COUNT_1">%d</xliff:g> metų</item>
+ <item quantity="few">po <xliff:g id="COUNT_1">%d</xliff:g> metų</item>
+ <item quantity="many">po <xliff:g id="COUNT_1">%d</xliff:g> metų</item>
+ <item quantity="other">po <xliff:g id="COUNT_1">%d</xliff:g> metų</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Vaizdo įrašo problema"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Šis vaizdo įrašas netinkamas srautiniu būdu perduoti į šį įrenginį."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Negalima paleisti šio vaizdo įrašo."</string>
@@ -992,8 +1040,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> sustabdytas"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"„<xliff:g id="APPLICATION">%1$s</xliff:g>“ vis sustabdoma"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Procesas „<xliff:g id="PROCESS">%1$s</xliff:g>“ vis sustabdomas"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Paleisti programą iš naujo"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Nustatyti ir paleisti programą iš naujo"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Atidaryti programą dar kartą"</string>
<string name="aerr_report" msgid="5371800241488400617">"Siųsti atsiliepimą"</string>
<string name="aerr_close" msgid="2991640326563991340">"Uždaryti"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ignoruoti, kol įrenginys bus paleistas iš naujo"</string>
@@ -1550,7 +1597,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Ištrinta: <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Darbo <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Kad atsegtumėte šį ekraną, palieskite ir palaikykite „Atgal“."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Kad atsegtumėte šį ekraną, palieskite ir palaikykite „Apžvalga“."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Programa prisegta: šiame įrenginyje negalima atsegti."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekrano prisegtas"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekranas atsegtas"</string>
@@ -1633,6 +1679,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS užklausa pakeista į USSD užklausą."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS užklausa pakeista į naują SS užklausą."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Darbo profilis"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Išskleidimo mygtukas"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"„Android“ USB išorinis prievadas"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB išorinis prievadas"</string>
@@ -1672,8 +1721,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Atsegti"</string>
<string name="app_info" msgid="6856026610594615344">"Programos informacija"</string>
<string name="negative_duration" msgid="5688706061127375131">"–<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Paleisti sesiją iš naujo"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Palieskite, kad pradėtumėte naują demonstracinės versijos sesiją"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Atkurkite gamyklinius nustatymus, kad galėtumėte naudoti šį įrenginį be apribojimų"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Palieskite, kad sužinotumėte daugiau."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Išj. valdiklis „<xliff:g id="LABEL">%1$s</xliff:g>“"</string>
</resources>
diff --git a/core/res/res/values-lv/strings.xml b/core/res/res/values-lv/strings.xml
index 9c6c5f7..5f8953a 100644
--- a/core/res/res/values-lv/strings.xml
+++ b/core/res/res/values-lv/strings.xml
@@ -607,7 +607,7 @@
<string name="phoneTypeRadio" msgid="4093738079908667513">"Radio"</string>
<string name="phoneTypeTelex" msgid="3367879952476250512">"Telekss"</string>
<string name="phoneTypeTtyTdd" msgid="8606514378585000044">"TTY TDD"</string>
- <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Mobilā tālruņa numurs darbā"</string>
+ <string name="phoneTypeWorkMobile" msgid="1311426989184065709">"Darba mobilais"</string>
<string name="phoneTypeWorkPager" msgid="649938731231157056">"Darba peidžers"</string>
<string name="phoneTypeAssistant" msgid="5596772636128562884">"Palīgs"</string>
<string name="phoneTypeMms" msgid="7254492275502768992">"Multiziņa"</string>
@@ -906,6 +906,46 @@
<item quantity="one">pēc <xliff:g id="COUNT_1">%d</xliff:g> g.</item>
<item quantity="other">pēc <xliff:g id="COUNT_1">%d</xliff:g> g.</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="zero">pirms <xliff:g id="COUNT_1">%d</xliff:g> minūtēm</item>
+ <item quantity="one">pirms <xliff:g id="COUNT_1">%d</xliff:g> minūtes</item>
+ <item quantity="other">pirms <xliff:g id="COUNT_1">%d</xliff:g> minūtēm</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="zero">pirms <xliff:g id="COUNT_1">%d</xliff:g> stundām</item>
+ <item quantity="one">pirms <xliff:g id="COUNT_1">%d</xliff:g> stundas</item>
+ <item quantity="other">pirms <xliff:g id="COUNT_1">%d</xliff:g> stundām</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="zero">pirms <xliff:g id="COUNT_1">%d</xliff:g> dienām</item>
+ <item quantity="one">pirms <xliff:g id="COUNT_1">%d</xliff:g> dienas</item>
+ <item quantity="other">pirms <xliff:g id="COUNT_1">%d</xliff:g> dienām</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="zero">pirms <xliff:g id="COUNT_1">%d</xliff:g> gadiem</item>
+ <item quantity="one">pirms <xliff:g id="COUNT_1">%d</xliff:g> gada</item>
+ <item quantity="other">pirms <xliff:g id="COUNT_1">%d</xliff:g> gadiem</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="zero">pēc <xliff:g id="COUNT_1">%d</xliff:g> minūtēm</item>
+ <item quantity="one">pēc <xliff:g id="COUNT_1">%d</xliff:g> minūtes</item>
+ <item quantity="other">pēc <xliff:g id="COUNT_1">%d</xliff:g> minūtēm</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="zero">pēc <xliff:g id="COUNT_1">%d</xliff:g> stundām</item>
+ <item quantity="one">pēc <xliff:g id="COUNT_1">%d</xliff:g> stundas</item>
+ <item quantity="other">pēc <xliff:g id="COUNT_1">%d</xliff:g> stundām</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="zero">pēc <xliff:g id="COUNT_1">%d</xliff:g> dienām</item>
+ <item quantity="one">pēc <xliff:g id="COUNT_1">%d</xliff:g> dienas</item>
+ <item quantity="other">pēc <xliff:g id="COUNT_1">%d</xliff:g> dienām</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="zero">pēc <xliff:g id="COUNT_1">%d</xliff:g> gadiem</item>
+ <item quantity="one">pēc <xliff:g id="COUNT_1">%d</xliff:g> gada</item>
+ <item quantity="other">pēc <xliff:g id="COUNT_1">%d</xliff:g> gadiem</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Video problēma"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Šis video nav derīgs straumēšanai uz šo ierīci."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Nevar atskaņot šo video."</string>
@@ -977,8 +1017,8 @@
<string name="aerr_process" msgid="6201597323218674729">"Lietotne <xliff:g id="PROCESS">%1$s</xliff:g> pārtrauca darboties."</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> atkārtoti pārtrauc darboties"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> atkārtoti pārtrauc darboties"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Restartēt lietotni"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Atiestatīt un restartēt lietotni"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Sūtīt atsauksmes"</string>
<string name="aerr_close" msgid="2991640326563991340">"Aizvērt"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Nerādīt, līdz ierīce tiks restartēta"</string>
@@ -1531,12 +1571,11 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> tika dzēsts."</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Darbā: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Lai atspraustu šo ekrānu, pieskarieties pogai “Atpakaļ” un turiet to."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Lai atspraustu šo ekrānu, pieskarieties pogai “Kopsavilkums” un turiet to."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Lietotne ir piesprausta. Atspraušana šajā ierīcē nav atļauta."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekrāns ir piesprausts"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekrāns ir atsprausts"</string>
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"Prasīt PIN kodu pirms atspraušanas"</string>
- <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pirms atspraušanas pieprasīt grafisko atslēgu"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Pirms atspraušanas pieprasīt grafisko atsl."</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Pirms atspraušanas pieprasīt paroli"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Instalēja jūsu administrators"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Atjaunināja administrators"</string>
@@ -1606,6 +1645,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS pieprasījums ir mainīts uz USSD pieprasījumu."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS pieprasījums ir mainīts uz jaunu SS pieprasījumu."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Darba profils"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB perifērijas ports"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB perifērijas ports"</string>
@@ -1644,8 +1687,11 @@
<string name="unpin_target" msgid="3556545602439143442">"Atspraust"</string>
<string name="app_info" msgid="6856026610594615344">"Lietotnes informācija"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Rūpnīcas datu atiestatīšana ierīces neierobežotai izmantošanai"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Pieskarieties, lai uzzinātu vairāk."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> atspējots"</string>
</resources>
diff --git a/core/res/res/values-mk-rMK/strings.xml b/core/res/res/values-mk-rMK/strings.xml
index 638f237..d7898a2 100644
--- a/core/res/res/values-mk-rMK/strings.xml
+++ b/core/res/res/values-mk-rMK/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one">за <xliff:g id="COUNT_1">%d</xliff:g>г.</item>
<item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g>г.</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">пред <xliff:g id="COUNT_1">%d</xliff:g> минута</item>
+ <item quantity="other">пред <xliff:g id="COUNT_1">%d</xliff:g> минути</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">пред <xliff:g id="COUNT_1">%d</xliff:g> час</item>
+ <item quantity="other">пред <xliff:g id="COUNT_1">%d</xliff:g> часа</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">пред <xliff:g id="COUNT_1">%d</xliff:g> ден</item>
+ <item quantity="other">пред <xliff:g id="COUNT_1">%d</xliff:g> дена</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">пред <xliff:g id="COUNT_1">%d</xliff:g> година</item>
+ <item quantity="other">пред <xliff:g id="COUNT_1">%d</xliff:g> години</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">за <xliff:g id="COUNT_1">%d</xliff:g> минута</item>
+ <item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g> минути</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">за <xliff:g id="COUNT_1">%d</xliff:g> час</item>
+ <item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g> часа</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">за <xliff:g id="COUNT_1">%d</xliff:g> ден</item>
+ <item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g> дена</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">за <xliff:g id="COUNT_1">%d</xliff:g> година</item>
+ <item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g> години</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Проблем со видео"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Видеово не е важечко за постојан тек до уредов."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Ова видео не може да се пушти."</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> запре"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> постојано запира"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> постојано запира"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Рестартирај ја апликацијата"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Ресетирај ја и рестартирај ја апликацијата"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Испрати повратни информации"</string>
<string name="aerr_close" msgid="2991640326563991340">"Затвори"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Исклучи го звукот додека уредот не се рестартира"</string>
@@ -1517,7 +1549,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Избришано <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Работа <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"За откачување на екранов, допрете и задржете Назад."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"За откачување на екранов, допрете и задржете Краток преглед."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Апликацијата е закачена: откачување не е дозволено на уредов."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Екранот е закачен"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Екранот е откачен"</string>
@@ -1584,6 +1615,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Барањето SS е изменето во барање USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Барањето SS е изменето во ново барање SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Работен профил"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Надворешна порта на УСБ за Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Надворешна порта на УСБ"</string>
@@ -1621,8 +1656,11 @@
<string name="unpin_target" msgid="3556545602439143442">"Откачете"</string>
<string name="app_info" msgid="6856026610594615344">"Информации за апликација"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Ресетирајте до фабричките поставки за уредов да го користите без ограничувања"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Допрете за да дознаете повеќе."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Оневозможен <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-ml-rIN/strings.xml b/core/res/res/values-ml-rIN/strings.xml
index 74b7570..9921f44 100644
--- a/core/res/res/values-ml-rIN/strings.xml
+++ b/core/res/res/values-ml-rIN/strings.xml
@@ -208,7 +208,7 @@
<string name="reboot_safemode_title" msgid="7054509914500140361">"സുരക്ഷിത മോഡിലേക്ക് റീബൂട്ടുചെയ്യുക"</string>
<string name="reboot_safemode_confirm" msgid="55293944502784668">"സുരക്ഷിത മോഡിലേക്ക് റീബൂട്ട് ചെയ്യണോ? ഇത് നിങ്ങൾ ഇൻസ്റ്റാളുചെയ്ത മൂന്നാം കക്ഷി അപ്ലിക്കേഷനുകളെയെല്ലാം പ്രവർത്തനരഹിതമാക്കും. നിങ്ങൾ വീണ്ടും റീബൂട്ടുചെയ്യുമ്പോൾ അവ പുനസ്ഥാപിക്കപ്പെടും."</string>
<string name="recent_tasks_title" msgid="3691764623638127888">"അടുത്തിടെയുള്ളത്"</string>
- <string name="no_recent_tasks" msgid="8794906658732193473">"അടുത്തിടെയുള്ള അപ്ലിക്കേഷനുകളൊന്നുമില്ല."</string>
+ <string name="no_recent_tasks" msgid="8794906658732193473">"അടുത്തിടെയുള്ള ആപ്സൊന്നുമില്ല."</string>
<string name="global_actions" product="tablet" msgid="408477140088053665">"ടാബ്ലെറ്റ് ഓപ്ഷനുകൾ"</string>
<string name="global_actions" product="tv" msgid="7240386462508182976">"ടിവി ഓപ്ഷനുകൾ"</string>
<string name="global_actions" product="default" msgid="2406416831541615258">"ഫോൺ ഓപ്ഷനുകൾ"</string>
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>വർഷത്തിൽ</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>വർഷത്തിൽ</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> മിനിറ്റ് മുമ്പ്</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> മിനിറ്റ് മുമ്പ്</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> മണിക്കൂർ മുമ്പ്</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> മണിക്കൂർ മുമ്പ്</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ദിവസം മുമ്പ്</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ദിവസം മുമ്പ്</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> വർഷം മുമ്പ്</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> വർഷം മുമ്പ്</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> മിനിറ്റിൽ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> മിനിറ്റിൽ</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> മണിക്കൂറിൽ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> മണിക്കൂറിൽ</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ദിവസത്തിൽ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ദിവസത്തിൽ</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> വർഷത്തിൽ</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> വർഷത്തിൽ</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"വീഡിയോ പ്രശ്നം"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ഈ വീഡിയോ ഈ ഉപകരണത്തിൽ സ്ട്രീം ചെയ്യുന്നതിന് സാധുവായതല്ല."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ഈ വീഡിയോ പ്ലേ ചെയ്യാനായില്ല."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> നിലച്ചിരിക്കുന്നു"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> നിലയ്ക്കുന്നത് തുടരുന്നു"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> നിലയ്ക്കുന്നത് തുടരുന്നു"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"ആപ്പ് പുനഃരാരംഭിക്കുക"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"ആപ്പ് പുനഃക്രമീകരിച്ച് പുനഃരാരംഭിക്കുക"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"ആപ്പ് വീണ്ടും തുറക്കുക"</string>
<string name="aerr_report" msgid="5371800241488400617">"ഫീഡ്ബാക്ക് അയയ്ക്കുക"</string>
<string name="aerr_close" msgid="2991640326563991340">"അടയ്ക്കുക"</string>
<string name="aerr_mute" msgid="1974781923723235953">"ഉപകരണം പുനഃരാരംഭിക്കുന്നത് വരെ മ്യൂട്ടുചെയ്യുക"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ഇല്ലാതാക്കി"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ഔദ്യോഗികം <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ, ബാക്ക് ബട്ടൺ സ്പർശിച്ച് പിടിക്കുക"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ഈ സ്ക്രീൻ അൺപിൻ ചെയ്യാൻ, ചുരുക്കവിവരണം സ്പർശിച്ച് പിടിക്കുക."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"അപ്ലിക്കേഷൻ പിൻ ചെയ്തു: ഈ ഉപകരണത്തിൽ അൺപിൻ ചെയ്യാനാവില്ല."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"സ്ക്രീൻ പിൻ ചെയ്തു"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"സ്ക്രീൻ അൺപിൻ ചെയ്തു"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS അഭ്യർത്ഥന, USSD അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS അഭ്യർത്ഥന, പുതിയ SS അഭ്യർത്ഥനയായി പരിഷ്ക്കരിച്ചു."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ഔദ്യോഗിക പ്രൊഫൈൽ"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"\'വികസിപ്പിക്കുക\' ബട്ടൺ"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB പെരിഫറൽ പോർട്ട്"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB പെരിഫറൽ പോർട്ട്"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"അൺപിൻ ചെയ്യുക"</string>
<string name="app_info" msgid="6856026610594615344">"ആപ്പ് വിവരം"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"സെഷൻ പുനരാരംഭിക്കുക"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"പുതിയൊരു ഡെമോ സെഷൻ ആരംഭിക്കാൻ ടാപ്പുചെയ്യുക"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"നിയന്ത്രണങ്ങൾ ഇല്ലാതെ ഈ ഉപകരണം ഉപയോഗിക്കാൻ ഫാക്ടറി റീസെറ്റ് നടത്തുക"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"കൂടുതലറിയുന്നതിന് സ്പർശിക്കുക."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> പ്രവർത്തനരഹിതമാക്കി"</string>
</resources>
diff --git a/core/res/res/values-mn-rMN/strings.xml b/core/res/res/values-mn-rMN/strings.xml
index f9ed6c1..c43a6a5 100644
--- a/core/res/res/values-mn-rMN/strings.xml
+++ b/core/res/res/values-mn-rMN/strings.xml
@@ -260,7 +260,7 @@
<string name="permgroupdesc_phone" msgid="6234224354060641055">"утасны дуудлага хийх, дуудлага удирдах"</string>
<string name="permgrouplab_sensors" msgid="416037179223226722">"Биеийн мэдрэгч"</string>
<string name="permgroupdesc_sensors" msgid="7147968539346634043">"таны биеийн байдлын талаарх мэдрэгч бүхий өгөгдөлд нэвтрэх"</string>
- <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Цонхны контентыг авах"</string>
+ <string name="capability_title_canRetrieveWindowContent" msgid="3901717936930170320">"Цонхны агуулгыг авах"</string>
<string name="capability_desc_canRetrieveWindowContent" msgid="3772225008605310672">"Таны харилцан үйлчлэх цонхны контентоос шалгах."</string>
<string name="capability_title_canRequestTouchExploration" msgid="3108723364676667320">"Хүрч танихыг асаах"</string>
<string name="capability_desc_canRequestTouchExploration" msgid="7543249041581408313">"Товшсон зүйлсийг чангаар хэлэх ба дэлгэцийг дохио ашиглан таних боломжтой."</string>
@@ -459,12 +459,12 @@
<string name="permdesc_writeSyncSettings" msgid="8956262591306369868">"Апп нь акаунтын синк тохиргоог өөрчлөх боломжтой. Жишээ нь энэ нь Хүмүүс апп акаунттай синк хийхийг идэвхжүүлэх боломжтой."</string>
<string name="permlab_readSyncStats" msgid="7396577451360202448">"синк статистикийг унших"</string>
<string name="permdesc_readSyncStats" msgid="1510143761757606156">"Апп нь синк үйлдэлийн түүх болон хэр их дата синк хийгдсэн зэрэг акаунтын синк статусыг унших боломжтой."</string>
- <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"таны USB сангийн контентыг унших боломжтой"</string>
- <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"таны SD картны контентыг унших боломжтой"</string>
- <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Апп нь таны USB сангийн контентыг унших боломжтой."</string>
- <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Апп нь таны SD картны контентыг унших боломжтой."</string>
- <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB сангийн контентыг өөрчлөх эсвэл устгах"</string>
- <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD картны контентыг өөрчлөх болон устгах"</string>
+ <string name="permlab_sdcardRead" product="nosdcard" msgid="367275095159405468">"таны USB сангийн агуулгыг унших боломжтой"</string>
+ <string name="permlab_sdcardRead" product="default" msgid="2188156462934977940">"таны SD картны агуулгыг унших боломжтой"</string>
+ <string name="permdesc_sdcardRead" product="nosdcard" msgid="3446988712598386079">"Апп нь таны USB сангийн агуулгыг унших боломжтой."</string>
+ <string name="permdesc_sdcardRead" product="default" msgid="2607362473654975411">"Апп нь таны SD картны агуулгыг унших боломжтой."</string>
+ <string name="permlab_sdcardWrite" product="nosdcard" msgid="8485979062254666748">"USB сангийн агуулгыг өөрчлөх эсвэл устгах"</string>
+ <string name="permlab_sdcardWrite" product="default" msgid="8805693630050458763">"SD картны агуулгыг өөрчлөх болон устгах"</string>
<string name="permdesc_sdcardWrite" product="nosdcard" msgid="6175406299445710888">"Апп нь USB санруу бичих боломжтой."</string>
<string name="permdesc_sdcardWrite" product="default" msgid="4337417790936632090">"Апп нь SD картруу бичих боломжтой."</string>
<string name="permlab_use_sip" msgid="2052499390128979920">"SIP дуудлага хийх/хүлээн авах"</string>
@@ -597,7 +597,7 @@
<string name="phoneTypeOther" msgid="1544425847868765990">"Бусад"</string>
<string name="phoneTypeCallback" msgid="2712175203065678206">"Буцаж холбоо барих"</string>
<string name="phoneTypeCar" msgid="8738360689616716982">"Машин"</string>
- <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Байгууллагын үндсэн"</string>
+ <string name="phoneTypeCompanyMain" msgid="540434356461478916">"Компаний үндсэн"</string>
<string name="phoneTypeIsdn" msgid="8022453193171370337">"ISDN"</string>
<string name="phoneTypeMain" msgid="6766137010628326916">"Үндсэн"</string>
<string name="phoneTypeOtherFax" msgid="8587657145072446565">"Бусад факс"</string>
@@ -891,6 +891,38 @@
<item quantity="other"> <xliff:g id="COUNT_1">%d</xliff:g>жилд</item>
<item quantity="one"> <xliff:g id="COUNT_0">%d</xliff:g>жилд</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> минутын өмнө</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> минутын өмнө</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> цагийн өмнө</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> цагийн өмнө</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> өдрийн өмнө</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> өдрийн өмнө</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> жилийн өмнө</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> жилийн өмнө</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"> <xliff:g id="COUNT_1">%d</xliff:g> минутад</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%d</xliff:g> минутад</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"> <xliff:g id="COUNT_1">%d</xliff:g> цагт</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%d</xliff:g> цагт</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"> <xliff:g id="COUNT_1">%d</xliff:g> өдөрт</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%d</xliff:g> өдөрт</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"> <xliff:g id="COUNT_1">%d</xliff:g> жилд</item>
+ <item quantity="one"> <xliff:g id="COUNT_0">%d</xliff:g> жилд</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Видео алдаа"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Энэ видео энэ төхөөрөмж дээр урсгалаар гарч чадахгүй."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Энэ видеог тоглуулах боломжгүй."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> зогсчихлоо"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> зогссоор байна"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> зогссоор байна"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Апп-ыг дахин эхлүүлэх"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Апп-ыг шинэчилж, дахин эхлүүлэх"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Апп-г дахин нээх"</string>
<string name="aerr_report" msgid="5371800241488400617">"Санал хүсэлт илгээх"</string>
<string name="aerr_close" msgid="2991640326563991340">"Хаах"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Төхөөрөмжийг дахин эхлүүлэх хүртэл дууг нь хаах"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> устсан"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Ажлын <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Энэ дэлгэцийг эхэнд нээхийг болиулахын тулд Буцах товчлуурыг дараад, хүлээнэ үү."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Энэ дэлгэцийг эхэнд нээхийг болиулахын тулд Тоймыг дараад, хүлээнэ үү."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App-ыг тусгайлан тэмдэглэсэн байна: Энэ төхөөрөмж дээр тусгайлан тэмдэглэсэн сонголтыг устгах боломжгүй."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Дэлгэцийг тогтоосон"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Дэлгэцийг сулласан"</string>
@@ -1577,6 +1607,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS хүсэлтийг USSD хүсэлт болгон өөрчилсөн байна."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS хүсэлтийг шинэ SS хүсэлт болгон өөрчилсөн байна."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Ажлын профайл"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Дэлгэх товчлуур"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Андройд USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
@@ -1614,8 +1647,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Unpin"</string>
<string name="app_info" msgid="6856026610594615344">"Апп-н мэдээлэл"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Харилцан үйлдлийг дахин эхлүүлэх"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Демо харилцан үйлдлийг шинээр эхлүүлэхийн тулд товшино уу"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Энэ төхөөрөмжийг хязгаарлалтгүй ашиглахын тулд үйлдвэрийн тохиргоонд дахин тохируулна уу"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Дэлгэрэнгүй үзэх бол дарна уу."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g>-г цуцалсан"</string>
</resources>
diff --git a/core/res/res/values-mr-rIN/strings.xml b/core/res/res/values-mr-rIN/strings.xml
index bd964f2..03f9429 100644
--- a/core/res/res/values-mr-rIN/strings.xml
+++ b/core/res/res/values-mr-rIN/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g>वर्षामध्ये</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>वर्षांमध्ये</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> मिनिटापूर्वी</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> मिनिटांंपूर्वी</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> तासापूर्वी</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> तासांंपूर्वी</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> दिवसापूर्वी</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> दिवसांंपूर्वी</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> वर्षापूर्वी</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> वर्षांपूर्वी</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> मिनिटात</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> मिनिटांमध्ये</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> तासामध्ये</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> तासांंमध्ये</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> दिवसात</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> दिवसांंमध्ये</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> वर्षात</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> वर्षांंमध्ये</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"व्हिडिओ समस्या"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"या डिव्हाइसवर प्रवाहित करण्यासाठी हा व्हिडिओ वैध नाही."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"हा व्हिडिओ प्ले करू शकत नाही."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> थांबली आहे"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> थांबतो"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> थांबते"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"अॅप रीस्टार्ट करा"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"अॅप रीसेट आणि रीस्टार्ट करा"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"अॅप पुन्हा उघडा"</string>
<string name="aerr_report" msgid="5371800241488400617">"अभिप्राय पाठवा"</string>
<string name="aerr_close" msgid="2991640326563991340">"बंद करा"</string>
<string name="aerr_mute" msgid="1974781923723235953">"डिव्हाइस रीस्टार्ट होईपर्यंत नि:शब्द करा"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> हटविली"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ही स्क्रीन अनपिन करण्यासाठी, परत ला स्पर्श करा आणि धरून ठेवा."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ही स्क्रीन अनपिन करण्यासाठी, विहंगावलोकनास स्पर्श करा आणि धरून ठेवा."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"अॅप पिन केलेला आहे: या डिव्हाइसवर अनपिन करण्यास अनुमती नाही."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रीन पिन केली"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"स्क्रीन अनपिन केली"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS विनंती USSD विनंतीवर सुधारित केली आहे."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS विनंती नवीन SS विनंतीवर सुधारित केली आहे."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"कार्य प्रोफाईल"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"विस्तृत करा बटण"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB परिधीय पोर्ट"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB परिधीय पोर्ट"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"अनपिन करा"</string>
<string name="app_info" msgid="6856026610594615344">"अॅप माहिती"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"सत्र पुन्हा सुरू करा"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"नवीन डेमो सत्राचा प्रारंभ करण्यासाठी टॅप करा"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"हे डिव्हाइस निर्बंधांशिवाय वापरण्यासाठी फॅक्टरी रीसेट करा"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"अधिक जाणून घेण्यासाठी स्पर्श करा."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> अक्षम केले"</string>
</resources>
diff --git a/core/res/res/values-ms-rMY/strings.xml b/core/res/res/values-ms-rMY/strings.xml
index 528b86b..189245e 100644
--- a/core/res/res/values-ms-rMY/strings.xml
+++ b/core/res/res/values-ms-rMY/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g>t</item>
<item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g>t</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minit yang lalu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minit yang lalu</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> jam yang lalu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> jam yang lalu</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> hari yang lalu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> hari yang lalu</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> tahun yang lalu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> tahun yang lalu</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g> minit</item>
+ <item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g> minit</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g> jam</item>
+ <item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g> jam</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g> hari</item>
+ <item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g> hari</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">dalam <xliff:g id="COUNT_1">%d</xliff:g> tahun</item>
+ <item quantity="one">dalam <xliff:g id="COUNT_0">%d</xliff:g> tahun</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Masalah video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Maaf, video ini tidak sah untuk penstriman ke peranti ini."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Tidak dapat mainkan video ini."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> telah berhenti"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> asyik berhenti"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> asyik berhenti"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Mulakan semula apl"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Tetapkan semula dan mulakan semula apl"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Buka apl sekali lagi"</string>
<string name="aerr_report" msgid="5371800241488400617">"Hantar maklum balas"</string>
<string name="aerr_close" msgid="2991640326563991340">"Tutup"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Redam sehingga peranti dimulakan semula"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> dipadamkan"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Kerja <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Untuk menyahsematkan skrin ni, ketik & tahan Kembali."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Untuk menyahsematkan skrin ini, ketik & tahan Ikhtisar."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Apl disemat: Nyahsemat tidak dibenarkan pada peranti ini."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skrin disemat"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Skrin dinyahsemat"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Permintaan SS diubah kepada permintaan USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Permintaan SS diubah kepada permintaan SS baharu."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil kerja"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Butang kembangkan"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port Persisian USB Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port Persisian USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Nyahsemat"</string>
<string name="app_info" msgid="6856026610594615344">"Maklumat apl"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Mulakan Semula Sesi"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Ketik untuk memulakan sesi tunjuk cara baharu"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Lakukan tetapan semula kilang untuk menggunakan peranti ini tanpa sekatan"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Ketik untuk mengetahui lebih lanjut."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> dilumpuhkan"</string>
</resources>
diff --git a/core/res/res/values-my-rMM/strings.xml b/core/res/res/values-my-rMM/strings.xml
index a508ef2..58acf51 100644
--- a/core/res/res/values-my-rMM/strings.xml
+++ b/core/res/res/values-my-rMM/strings.xml
@@ -742,7 +742,7 @@
<string name="keyguard_accessibility_status" msgid="8008264603935930611">"အခြေအနေ"</string>
<string name="keyguard_accessibility_camera" msgid="8904231194181114603">"ကင်မရာ"</string>
<string name="keygaurd_accessibility_media_controls" msgid="262209654292161806">"မီဒီယာ ထိန်းချုပ်မှုများ"</string>
- <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"ဝဒ်ဂျက်များ နေရာစီခြင်း စတင်ပါပြီ"</string>
+ <string name="keyguard_accessibility_widget_reorder_start" msgid="8736853615588828197">"ဝိဂျက်များ နေရာစီခြင်း စတင်ပါပြီ"</string>
<string name="keyguard_accessibility_widget_reorder_end" msgid="7170190950870468320">"ဝဒ်ဂျက်များကို နေရာ ပြန်စီပြီးပါပြီ"</string>
<string name="keyguard_accessibility_widget_deleted" msgid="4426204263929224434">"<xliff:g id="WIDGET_INDEX">%1$s</xliff:g> ဝဒ်ဂျက်ကို ဖျက်လိုက်ပြီးပါပြီ"</string>
<string name="keyguard_accessibility_expand_lock_area" msgid="519859720934178024">"သော့မချထားသာ နယ်ပယ်ကို ချဲ့ပါ"</string>
@@ -803,9 +803,9 @@
<string name="permlab_writeGeolocationPermissions" msgid="5962224158955273932">"ဘရောင်ဇာ ဘူမိဇုန်သတ်မှတ်မှု ခွင့်ပြုချက်များကို မွမ်းမံခြင်း"</string>
<string name="permdesc_writeGeolocationPermissions" msgid="1083743234522638747">"အက်ပ်အား ဘရောင်ဇာ၏ ဘူမိဇုန်သတ်မှတ်ရေး ခွင့်ပြုချက်များကို မွမ်းမံခွင့် ပြုသည်။ ကြံဖန် အက်ပ်များက ၎င်းကို အသုံးချပြီး လိုရာ ဝက်ဘ်ဆိုက်များသို့ တည်နေရာ အချက်အလက် ပို့မှုကို လုပ်နိုင်သည်။"</string>
<string name="save_password_message" msgid="767344687139195790">"ဤလျှို့ဝှက်စကားဝှက်အား ဘရောင်ဇာကိုမှတ်ခိုင်းမည်လား"</string>
- <string name="save_password_notnow" msgid="6389675316706699758">"ယခုမဟုတ်ပါ"</string>
+ <string name="save_password_notnow" msgid="6389675316706699758">"ယခုမလုပ်ပါ"</string>
<string name="save_password_remember" msgid="6491879678996749466">"မှတ်ထားရန်"</string>
- <string name="save_password_never" msgid="8274330296785855105">"မည်သည့်အခါမှ"</string>
+ <string name="save_password_never" msgid="8274330296785855105">"ကန့်သတ်မှုမရှိ"</string>
<string name="open_permission_deny" msgid="7374036708316629800">"သင့်ဆီမှာ ဒီစာမျက်နှာကို ဖွင့်ရန် ခွင့်ပြုချက် မရှိပါ။"</string>
<string name="text_copied" msgid="4985729524670131385">"clipboardထံ စာသားအားကူးယူမည်"</string>
<string name="more_item_label" msgid="4650918923083320495">"နောက်ထပ်"</string>
@@ -817,7 +817,7 @@
<string name="search_hint" msgid="1733947260773056054">"ရှာဖွေပါ..."</string>
<string name="searchview_description_search" msgid="6749826639098512120">"ရှာဖွေခြင်း"</string>
<string name="searchview_description_query" msgid="5911778593125355124">"ရှာစရာ အချက်အလက်နေရာ"</string>
- <string name="searchview_description_clear" msgid="1330281990951833033">"ရှာစရာ အချက်အလက်များ ရှင်းလင်းရန်"</string>
+ <string name="searchview_description_clear" msgid="1330281990951833033">"ရှာစရာ အချက်အလက်များ ဖယ်ရှားရန်"</string>
<string name="searchview_description_submit" msgid="2688450133297983542">"ရှာဖွေစရာ အချက်အလက်ကို အတည်ပြုရန်"</string>
<string name="searchview_description_voice" msgid="2453203695674994440">"အသံဖြင့် ရှာဖွေခြင်း"</string>
<string name="enable_explore_by_touch_warning_title" msgid="7460694070309730149">"ထိတွေ့ပြီး ရှာဖွေခြင်း ဖွင့်မည်မလား?"</string>
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g>နှစ်အတွင်း</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g>နှစ်အတွင်း</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">ပြီးခဲ့သည့် <xliff:g id="COUNT_1">%d</xliff:g> မိနစ်က</item>
+ <item quantity="one">ပြီးခဲ့သည့် <xliff:g id="COUNT_0">%d</xliff:g> မိနစ်က</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">ပြီးခဲ့သည့် <xliff:g id="COUNT_1">%d</xliff:g> နာရီက</item>
+ <item quantity="one">ပြီးခဲ့သည့် <xliff:g id="COUNT_0">%d</xliff:g> နာရီက</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">ပြီးခဲ့သည့် <xliff:g id="COUNT_1">%d</xliff:g> ရက်က</item>
+ <item quantity="one">ပြီးခဲ့သည့် <xliff:g id="COUNT_0">%d</xliff:g> ရက်က</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">ပြီးခဲ့သည့် <xliff:g id="COUNT_1">%d</xliff:g> နှစ်က</item>
+ <item quantity="one">ပြီးခဲ့သည့် <xliff:g id="COUNT_0">%d</xliff:g> နှစ်က</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> မိနစ်အတွင်း</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> မိနစ်အတွင်း</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> နာရီအတွင်း</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> နာရီအတွင်း</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ရက်အတွင်း</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ရက်အတွင်း</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> နှစ်အတွင်း</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> နှစ်အတွင်း</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"ဗီဒီယို ပြဿနာ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ဒီဗိဒီယိုမှာ ဒီကိရိယာ ပေါ်မှာ ဖွင့်ကြည့်၍ မရနိုင်ပါ။"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ဒီဗီဒီယိုကို ပြသလို့ မရပါ"</string>
@@ -924,9 +956,9 @@
<string name="app_running_notification_title" msgid="8718335121060787914">"<xliff:g id="APP_NAME">%1$s</xliff:g> က အလုပ်လုပ်နေသည်။"</string>
<string name="app_running_notification_text" msgid="1197581823314971177">"နောက်ထပ်အချက်အလက်များကို ကြည့်ရန် သို့မဟုတ် အက်ပ်ကိုရပ်တန့်ရန် တို့ပါ။"</string>
<string name="ok" msgid="5970060430562524910">"အိုကေ"</string>
- <string name="cancel" msgid="6442560571259935130">"ဖျက်သိမ်းရန်"</string>
+ <string name="cancel" msgid="6442560571259935130">"မလုပ်တော့ပါ"</string>
<string name="yes" msgid="5362982303337969312">"အိုကေ"</string>
- <string name="no" msgid="5141531044935541497">"ဖျက်သိမ်းရန်"</string>
+ <string name="no" msgid="5141531044935541497">"မလုပ်တော့ပါ"</string>
<string name="dialog_alert_title" msgid="2049658708609043103">"သတိပြုရန်"</string>
<string name="loading" msgid="7933681260296021180">"တင်နေ…"</string>
<string name="capital_on" msgid="1544682755514494298">"ဖွင့်ရန်"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> ရပ်တန့်သွားပါပြီ"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> သည်ထပ်တလဲလဲ ရပ်တန့်နေပါသည်"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> သည်ထပ်တလဲလဲ ရပ်တန့်နေပါသည်"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"အက်ပ်ကိုပြန်လည်စတင်ပါ"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"အက်ပ်ကို ပြန်လည်ပြင်ဆင်သတ်မှတ်ပြီး ပြန်လည်စတင်ပါ"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"အက်ပ်ကိုထပ်ဖွင့်ပါ"</string>
<string name="aerr_report" msgid="5371800241488400617">"တုံ့ပြန်ချက်ပို့ပါ"</string>
<string name="aerr_close" msgid="2991640326563991340">"ပိတ်ပါ"</string>
<string name="aerr_mute" msgid="1974781923723235953">"စက်ပစ္စည်း ပြန်လည်စတင်သည့်တိုင် အသံတိတ်ပါ"</string>
@@ -1071,7 +1102,7 @@
<string name="sms_short_code_details" msgid="5873295990846059400"><b>"ဒါက သင့် မိုဘိုင်း အကောင့် အတွက် "</b>" ကုန်ကျမှု ရှိလာနိုင်သည်။"</string>
<string name="sms_premium_short_code_details" msgid="7869234868023975"><b>"ဒါက သင့် မိုဘိုင်း အကောင့် အတွက် ကုန်ကျမှု ရှိလာနိုင်သည်။"</b></string>
<string name="sms_short_code_confirm_allow" msgid="4458878637111023413">"ပို့ရန်"</string>
- <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"ဖျက်သိမ်းရန်"</string>
+ <string name="sms_short_code_confirm_deny" msgid="2927389840209170706">"မလုပ်တော့ပါ"</string>
<string name="sms_short_code_remember_choice" msgid="5289538592272218136">"ကျွန်ပ်၏ရွေးချယ်မှုကို မှတ်ထားရန်"</string>
<string name="sms_short_code_remember_undo_instruction" msgid="4960944133052287484">"နောင်တွင် ဆက်တင် > အပလီကေးရှင်းများ မှပြောင်းနိုင်သည်"</string>
<string name="sms_short_code_confirm_always_allow" msgid="3241181154869493368">"အမြဲခွင့်ပြုရန်"</string>
@@ -1231,7 +1262,7 @@
<string name="gpsNotifTitle" msgid="5446858717157416839">"တည်နေရာအား တောင်းခံသည်"</string>
<string name="gpsNotifMessage" msgid="1374718023224000702">"<xliff:g id="NAME">%1$s</xliff:g> (<xliff:g id="SERVICE">%2$s</xliff:g>)မှတောင်းခံသည်"</string>
<string name="gpsVerifYes" msgid="2346566072867213563">"ဟုတ်ကဲ့"</string>
- <string name="gpsVerifNo" msgid="1146564937346454865">"မဟုတ်ပါ"</string>
+ <string name="gpsVerifNo" msgid="1146564937346454865">"No"</string>
<string name="sync_too_many_deletes" msgid="5296321850662746890">"ပယ်ဖျက်မည့်ကန့်သတ်နှုန်းကျော်လွန်သည်"</string>
<string name="sync_too_many_deletes_desc" msgid="496551671008694245">"<xliff:g id="TYPE_OF_SYNC">%2$s</xliff:g>၊ account <xliff:g id="ACCOUNT_NAME">%3$s</xliff:g> အတွက် စုစုပေါင်း <xliff:g id="NUMBER_OF_DELETED_ITEMS">%1$d</xliff:g> အရာဖျက်ထားပါသည်။ သင်ဘာလုပ်ချင်ပါလဲ?"</string>
<string name="sync_really_delete" msgid="2572600103122596243">"ဤအရာများကိုဖျက်ပါ"</string>
@@ -1259,7 +1290,7 @@
<string name="date_picker_prev_month_button" msgid="2858244643992056505">"ပြီးခဲ့သော လ"</string>
<string name="date_picker_next_month_button" msgid="5559507736887605055">"လာမည့် လ"</string>
<string name="keyboardview_keycode_alt" msgid="4856868820040051939">"Altခလုတ်"</string>
- <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"ဖျက်သိမ်းရန် ခလုတ်"</string>
+ <string name="keyboardview_keycode_cancel" msgid="1203984017245783244">"မလုပ်တော့ပါ ခလုတ်"</string>
<string name="keyboardview_keycode_delete" msgid="3337914833206635744">"ဖျက်ရန်ခလုတ်"</string>
<string name="keyboardview_keycode_done" msgid="1992571118466679775">"ပြီးဆုံးသည့်ခလုတ်"</string>
<string name="keyboardview_keycode_mode_change" msgid="4547387741906537519">"စနစ်ပြောင်းခြင်းခလုတ်"</string>
@@ -1398,7 +1429,7 @@
<string name="error_message_title" msgid="4510373083082500195">"အမှား"</string>
<string name="error_message_change_not_allowed" msgid="1347282344200417578">"ဒီအပြောင်းအလဲမျိုးကို သင့် စီမံအုပ်ချုပ်သူမှ ခွင့်မပြုပါ"</string>
<string name="app_not_found" msgid="3429141853498927379">"ဤလုပ်ဆောင်ချက်ကို ပြုလုပ်ပေးမည့် အက်ပ် မရှိပါ။"</string>
- <string name="revoke" msgid="5404479185228271586">"ဖျက်သိမ်းရန်"</string>
+ <string name="revoke" msgid="5404479185228271586">"မလုပ်တော့ပါ"</string>
<string name="mediasize_iso_a0" msgid="1994474252931294172">"အိုက်အက်စ်အို အေ ဝ"</string>
<string name="mediasize_iso_a1" msgid="3333060421529791786">"အိုက်အက်စ်အို အေ၁"</string>
<string name="mediasize_iso_a2" msgid="3097535991925798280">"အိုက်အက်စ်အို အေ ၂"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ကို ဖျက်ပြီးပါပြီ"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"အလုပ် <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန် \"နောက်သို့\" ကိုထိပြီးဖိထားပါ။"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ဤမျက်နှာပြင်ကို ပင်ဖြုတ်ရန် \"ခြုံငုံကြည့်ခြင်း\" ကိုထိပြီးဖိထားပါ။"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Appကို ပင်ထိုးထားသည်။ ပင်ဖျက်ခြင်းကို ဒီစက်မှာ မရနိုင်ပါ။"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"မျက်နှာပြင်ကို ပင်ထိုးထား"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"မျက်နှာပြင် ပင်ထိုးမှု ဖြတ်လိုက်ပြီ"</string>
@@ -1525,7 +1555,7 @@
<string name="package_installed_device_owner" msgid="8420696545959087545">"သင့် အက်ဒမင်မှ သွင်းယူထား၏"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"သင့်စီမံခန့်ခွဲသူမှ အဆင့်မြှင့်ထားပါသည်။"</string>
<string name="package_deleted_device_owner" msgid="7650577387493101353">"သင့် အက်ဒမင်အား ဖျက်ပစ်ရန်"</string>
- <string name="battery_saver_description" msgid="1960431123816253034">"ဘက်ထရီသက်တမ်း ကြာရှည်ခံရန်၊ ဘက်ထရီအားထိန်းသည် သင့်ကိရိယာ၏ ဆောင်ရွက်ချက်ကို လျှော့ပေးပြီး တုန်ခါမှု၊ တည်နေရာဝန်ဆောင်မှုများနှင့်၊ နောက်ခံဒေတာအများစုကို ကန့်သတ်ပေး၏။ စင့်လုပ်ပေးရလေ့ရှိသည့် အီးမေး၊ စာပို့ခြင်းနှင့်၊ အခြားအပလီကေးရှင်းများကို ၎င်းတို့အား သင် ဖွင့်မှသာ အဆင့်မြှင့်မွမ်းမံမည်ဖြစ်၏။ \n\n ကိရိယာအား အားသွင်းနေစဉ် ဘက်ထရီအားထိန်းအား အလိုအလျောက် ပိတ်ထားသည်။"</string>
+ <string name="battery_saver_description" msgid="1960431123816253034">"ဘက်ထရီသက်တမ်း ကြာရှည်ခံရန်၊ ဘက်ထရီအားထိန်းသည် သင့်ကိရိယာ၏ ဆောင်ရွက်ချက်ကို လျှော့ပေးပြီး တုန်ခါမှု၊ တည်နေရာဝန်ဆောင်မှုများနှင့်၊ နောက်ခံဒေတာအများစုကို ကန့်သတ်ပေး၏။ စင့်လုပ်ပေးရလေ့ရှိသည့် အီးမေးလ်၊ စာပို့ခြင်းနှင့်၊ အခြားအပလီကေးရှင်းများကို ၎င်းတို့အား သင် ဖွင့်မှသာ အဆင့်မြှင့်မွမ်းမံမည်ဖြစ်၏။ \n\n ကိရိယာအား အားသွင်းနေစဉ် ဘက်ထရီအားထိန်းအား အလိုအလျောက် ပိတ်ထားသည်။"</string>
<string name="data_saver_description" msgid="6015391409098303235">"ဒေတာအသုံးလျှော့ချနိုင်ရန် အက်ပ်များကို နောက်ခံတွင် ဒေတာပို့ခြင်းနှင့် လက်ခံခြင်းမရှိစေရန် ဒေတာချွေတာမှုစနစ်က တားဆီးထားပါသည်။ ယခုအက်ပ်ဖြင့် ဒေတာအသုံးပြုနိုင်သော်လည်း အကြိမ်လျှော့၍သုံးရပါမည်။ ဥပမာ၊ သင် မတို့မချင်း ပုံများပေါ်လာမည် မဟုတ်ပါ။"</string>
<string name="data_saver_enable_title" msgid="4674073932722787417">"ဒေတာအသုံးပြုမှု ချွေတာမှုစနစ်ကို ဖွင့်မလား။"</string>
<string name="data_saver_enable_button" msgid="7147735965247211818">"ဖွင့်ပါ"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"USSD တောင်းဆိုချက်အရ SS တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS တောင်းဆိုချက်အရ SS တောင်းဆိုချက်အား ပြင်ဆင်ထား၏။"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"အလုပ်ကိုယ်ရေးအချက်အလက်"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"တိုးချဲ့ရန်ခလုတ်"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB ဘေးဘက်အပေါက်"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"အန်းဒရွိုက်"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB ဘေးရှိပို့တ်"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"ဖြုတ်ပါ"</string>
<string name="app_info" msgid="6856026610594615344">"အက်ပ်အချက်အလက်"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"စက်ရှင်ကို ပြန်စပါ"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"သရုပ်ပြစက်ရှင်အသစ်စတင်ရန် တို့ပါ"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"ဤစက်ပစ္စည်းကို ကန့်သတ်ချက်များမပါဘဲ အသုံးပြုရန် စက်ရုံထုတ်ဆက်တင်အတိုင်း ပြန်လည်သတ်မှတ်ပါ"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"ပိုမိုလေ့လာရန် တို့ပါ။"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"ပိတ်ထားသည့် <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-nb/strings.xml b/core/res/res/values-nb/strings.xml
index c87f33b..9c8be75 100644
--- a/core/res/res/values-nb/strings.xml
+++ b/core/res/res/values-nb/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> år</item>
<item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> år</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">for <xliff:g id="COUNT_1">%d</xliff:g> minutter siden</item>
+ <item quantity="one">for <xliff:g id="COUNT_0">%d</xliff:g> minutt siden</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">for <xliff:g id="COUNT_1">%d</xliff:g> timer siden</item>
+ <item quantity="one">for <xliff:g id="COUNT_0">%d</xliff:g> time siden</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">for <xliff:g id="COUNT_1">%d</xliff:g> dager siden</item>
+ <item quantity="one">for <xliff:g id="COUNT_0">%d</xliff:g> dag siden</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">for <xliff:g id="COUNT_1">%d</xliff:g> år siden</item>
+ <item quantity="one">for <xliff:g id="COUNT_0">%d</xliff:g> år siden</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> minutter</item>
+ <item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> minutt</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> timer</item>
+ <item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> time</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> dager</item>
+ <item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> dag</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> år</item>
+ <item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> år</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Videoproblem"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Denne videoen er ikke gyldig for direkteavspilling på enheten."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Kan ikke spille av denne videoen."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> har stoppet"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> stopper gjentatte ganger"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> stopper gjentatte ganger"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Start appen på nytt"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Tilbakestill appen, og start den på nytt"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Åpne appen på nytt"</string>
<string name="aerr_report" msgid="5371800241488400617">"Send tilbakemelding"</string>
<string name="aerr_close" msgid="2991640326563991340">"Lukk"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ignorer frem til enheten starter på nytt"</string>
@@ -1512,12 +1543,11 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> er slettet"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Jobb-<xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"For å løsne denne skjermen, trykk og hold inne Tilbake."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"For å løsne denne skjermen, trykk og hold inne Oversikt."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Appen er festet – du kan ikke løsne apper på denne enheten."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skjermen er festet"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Skjermen er løsnet"</string>
<string name="lock_to_app_unlock_pin" msgid="2552556656504331634">"PIN-kode for å løsne apper"</string>
- <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Krev bruk av opplåsningsmønster for å løsne apper"</string>
+ <string name="lock_to_app_unlock_pattern" msgid="4182192144797225137">"Krev opplåsingsmønster for å løsne apper"</string>
<string name="lock_to_app_unlock_password" msgid="6380979775916974414">"Krev passord for å løsne apper"</string>
<string name="package_installed_device_owner" msgid="8420696545959087545">"Installert av administratoren"</string>
<string name="package_updated_device_owner" msgid="8856631322440187071">"Oppdatert av administratoren"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-forespørselen er endret til en USSD-forespørsel."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-forespørselen er endret til en ny SS-forespørsel."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Arbeidsprofil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Knapp for å vise mer"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port for USB-tilleggsutstyr for Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port for USB-tilleggsutstyr"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Løsne"</string>
<string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Start økten på nytt"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Trykk for å starte en ny demoøkt"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Tilbakestill til fabrikkstandard for å bruke denne enheten uten begrensninger"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Trykk for å finne ut mer."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> er slått av"</string>
</resources>
diff --git a/core/res/res/values-ne-rNP/strings.xml b/core/res/res/values-ne-rNP/strings.xml
index 1c9d96b..680f2d8 100644
--- a/core/res/res/values-ne-rNP/strings.xml
+++ b/core/res/res/values-ne-rNP/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> वर्षमा</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> वर्षमा</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> मिनेट अघि</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> मिनेट अघि</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> घन्टा अघि</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> घन्टा अघि</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> दिन अघि</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> दिन अघि</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> वर्ष अघि</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> वर्ष अघि</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> मिनेटमा</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> मिनेटमा</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> घन्टामा</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> घन्टामा</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> दिनमा</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> दिनमा</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> वर्षमा</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> वर्षमा</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"भिडियो समस्या"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"यो भिडियो यस उपकरणको लागि स्ट्रिमिङ गर्न मान्य छैन।"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"यो भिडियो चलाउन सक्दैन।"</string>
@@ -968,8 +1000,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> रोकिएको छ"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> रोकिरहन्छ"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> रोकिरहन्छ"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"अनुप्रयोगलाई पुन: सुरु गर्नुहोस्"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"अनुप्रयोगलाई रिसेट गरी पुन: सुरु गर्नुहोस्"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"अनुप्रयोगलाई फेरि खोल्नुहोस्"</string>
<string name="aerr_report" msgid="5371800241488400617">"प्रतिक्रिया पठाउनुहोस्"</string>
<string name="aerr_close" msgid="2991640326563991340">"बन्द गर्नुहोस्"</string>
<string name="aerr_mute" msgid="1974781923723235953">"यन्त्र पुनः सुरु नभएसम्म म्यूट गर्नुहोस्"</string>
@@ -1518,7 +1549,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> हटाइयो"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"कार्य <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"यस स्क्रिनलाई अनपिन गर्न पछाडि बटनलाई छोइराख्नुहोस्।"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"यस स्क्रिनलाई अनपिन गर्न परिदृश्य बटनलाई छोइराख्नुहोस्।"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"अनुप्रयोग पिन गरियो: यस यन्त्रमा अनपिन गर्ने अनुमति छैन।"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"स्क्रिन पिन गरियो"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"स्क्रिन अनपिन गरियो"</string>
@@ -1585,6 +1615,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS अनुरोध USSD अनुरोधमा परिमार्जन गरिएको छ।"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS अनुरोध नयाँ SS अनुरोधमा परिमार्जन गरिएको छ।"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"कार्य प्रोफाइल"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"विस्तृत गर्ने बटन"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB पेरिफेरल पोर्ट"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB पेरिफेरल पोर्ट"</string>
@@ -1622,8 +1655,9 @@
<string name="unpin_target" msgid="3556545602439143442">"अनपिन गर्नुहोस्"</string>
<string name="app_info" msgid="6856026610594615344">"अनुप्रयोगका बारे जानकारी"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"सत्रलाई पुन:सुरु गर्नुहोस्"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"एउटा नयाँ डेमो सम्बन्धी सत्र सुरु गर्न ट्याप गर्नुहोस्"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"यस यन्त्रलाई सीमितताहरू बिना प्रयोग गर्नका लागि फ्याक्ट्री रिसेट गर्नुहोस्"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"थप जान्नका लागि छुनुहोस्।"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> लाई असक्षम गरियो"</string>
</resources>
diff --git a/core/res/res/values-nl/strings.xml b/core/res/res/values-nl/strings.xml
index fdd6969..3833ab5 100644
--- a/core/res/res/values-nl/strings.xml
+++ b/core/res/res/values-nl/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">over <xliff:g id="COUNT_1">%d</xliff:g> j</item>
<item quantity="one">over <xliff:g id="COUNT_0">%d</xliff:g> j</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minuten geleden</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minuut geleden</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> uur geleden</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> uur geleden</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dagen geleden</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> dag geleden</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> jaar geleden</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> jaar geleden</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">over <xliff:g id="COUNT_1">%d</xliff:g> minuten</item>
+ <item quantity="one">over <xliff:g id="COUNT_0">%d</xliff:g> minuut</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">over <xliff:g id="COUNT_1">%d</xliff:g> uur</item>
+ <item quantity="one">over <xliff:g id="COUNT_0">%d</xliff:g> uur</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">over <xliff:g id="COUNT_1">%d</xliff:g> dagen</item>
+ <item quantity="one">over <xliff:g id="COUNT_0">%d</xliff:g> dag</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">over <xliff:g id="COUNT_1">%d</xliff:g> jaar</item>
+ <item quantity="one">over <xliff:g id="COUNT_0">%d</xliff:g> jaar</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Probleem met video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Deze video kan niet worden gestreamd naar dit apparaat."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Deze video kan niet worden afgespeeld."</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> is gestopt"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> stopt steeds"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> stopt steeds"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"App opnieuw starten"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"App resetten en opnieuw starten"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Feedback verzenden"</string>
<string name="aerr_close" msgid="2991640326563991340">"Sluiten"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Verbergen tot apparaat opnieuw wordt opgestart"</string>
@@ -1512,7 +1544,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> verwijderd"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Werk <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Tik op Terug en houd vast om dit scherm los te maken."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Tik op Overzicht en houd vast om dit scherm los te maken."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"App is vastgezet: losmaken is niet toegestaan op dit apparaat."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Scherm vastgezet"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Scherm losgemaakt"</string>
@@ -1579,6 +1610,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-verzoek is gewijzigd in USSD-verzoek."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-verzoek is gewijzigd in nieuw SS-verzoek."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Werkprofiel"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Poort voor Android-USB-randapparatuur"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Poort voor USB-randapparatuur"</string>
@@ -1616,8 +1651,11 @@
<string name="unpin_target" msgid="3556545602439143442">"Losmaken"</string>
<string name="app_info" msgid="6856026610594615344">"App-info"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Zet dit apparaat terug op de fabrieksinstellingen om het zonder beperkingen te gebruiken"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Tik voor meer informatie."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> uitgeschakeld"</string>
</resources>
diff --git a/core/res/res/values-pa-rIN/strings.xml b/core/res/res/values-pa-rIN/strings.xml
index 937f045..eb1d97b 100644
--- a/core/res/res/values-pa-rIN/strings.xml
+++ b/core/res/res/values-pa-rIN/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ਸਾਲ ਵਿੱਚ</item>
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਸਾਲ ਵਿੱਚ</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ਮਿੰਟ ਪਹਿਲਾਂ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਮਿੰਟ ਪਹਿਲਾਂ</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ਘੰਟੇ ਪਹਿਲਾਂ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਘੰਟੇ ਪਹਿਲਾਂ</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ਦਿਨ ਪਹਿਲਾਂ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਦਿਨ ਪਹਿਲਾਂ</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ਸਾਲ ਪਹਿਲਾਂ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਸਾਲ ਪਹਿਲਾਂ</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ਮਿੰਟ ਵਿੱਚ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਮਿੰਟ ਵਿੱਚ</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ਘੰਟੇ ਵਿੱਚ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਘੰਟੇ ਵਿੱਚ</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ਦਿਨ ਵਿੱਚ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਦਿਨ ਵਿੱਚ</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> ਸਾਲ ਵਿੱਚ</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ਸਾਲ ਵਿੱਚ</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"ਵੀਡੀਓ ਸਮੱਸਿਆ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ਇਹ ਵੀਡੀਓ ਇਸ ਡੀਵਾਈਸ ਤੇ ਸਟ੍ਰੀਮਿੰਗ ਲਈ ਪ੍ਰਮਾਣਿਕ ਨਹੀਂ ਹੈ।"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ਇਹ ਵੀਡੀਓ ਪਲੇ ਨਹੀਂ ਕਰ ਸਕਦਾ।"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> ਰੁਕ ਗਿਆ ਹੈ"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> ਵਾਰ-ਵਾਰ ਰੁਕ ਰਹੀ ਹੈ"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> ਵਾਰ-ਵਾਰ ਰੁਕ ਰਹੀ ਹੈ"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"ਐਪ ਨੂੰ ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"ਐਪ ਨੂੰ ਰੀਸੈੱਟ ਅਤੇ ਮੁੜ-ਚਾਲੂ ਕਰੋ"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"ਦੁਬਾਰਾ ਐਪ ਖੋਲ੍ਹੋ"</string>
<string name="aerr_report" msgid="5371800241488400617">"ਪ੍ਰਤੀਕਰਮ ਭੇਜੋ"</string>
<string name="aerr_close" msgid="2991640326563991340">"ਬੰਦ ਕਰੋ"</string>
<string name="aerr_mute" msgid="1974781923723235953">"ਡੀਵਾਈਸ ਦੇ ਮੁੜ-ਚਾਲੂ ਹੋਣ ਤੱਕ ਮਿਊਟ ਕਰੋ"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> ਹਟਾਇਆ ਗਿਆ"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"ਕੰਮ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, ਸਪਰਸ਼ ਕਰੋ & ਦਬਾਈ ਰੱਖੋ।"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ਇਸ ਸਕ੍ਰੀਨ ਨੂੰ ਅਨਪਿੰਨ ਕਰਨ ਲਈ, ਸਪਰਸ਼ ਕਰੋ & ਰੂਪਰੇਖਾ ਨੂੰ ਦਬਾਈ ਰੱਖੋ।"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ਐਪ ਪਿੰਨਡ ਹੈ: ਇਸ ਡੀਵਾਈਸ ਤੇ ਅਨਪਿਨ ਕਰਨ ਦੀ ਆਗਿਆ ਨਹੀਂ ਹੈ।"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ਸਕ੍ਰੀਨ ਪਿੰਨ ਕੀਤੀ"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"ਸਕ੍ਰੀਨ ਅਨਪਿਨ ਕੀਤੀ"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ਬੇਨਤੀ USSD ਬੇਨਤੀ ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ਬੇਨਤੀ ਨਵੀਂ SS ਵਿੱਚ ਸੰਸ਼ੋਧਿਤ ਕੀਤੀ ਗਈ ਹੈ।"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"ਕੰਮ ਪ੍ਰੋਫਾਈਲ"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"ਵਿਸਤਾਰ ਬਟਨ"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB ਪੈਰੀਫੈਰਲ ਪੋਰਟ"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB ਪੈਰੀਫੈਰਲ ਪੋਰਟ"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"ਅਨਪਿੰਨ ਕਰੋ"</string>
<string name="app_info" msgid="6856026610594615344">"ਐਪ ਜਾਣਕਾਰੀ"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"ਸੈਸ਼ਨ ਦੁਬਾਰਾ ਸ਼ੁਰੂ ਕਰੋ"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"ਇੱਕ ਨਵਾਂ ਡੈਮੋ ਸੈਸ਼ਨ ਸ਼ੁਰੂ ਕਰਨ ਲਈ ਟੈਪ ਕਰੋ"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"ਇਸ ਡੀਵਾਈਸ ਨੂੰ ਬਿਨਾਂ ਪਾਬੰਦੀਆਂ ਦੇ ਵਰਤਣ ਲਈ ਫੈਕਟਰੀ ਰੀਸੈੱਟ ਕਰੋ"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"ਹੋਰ ਜਾਣਨ ਲਈ ਸਪਰਸ਼ ਕਰੋ।"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"ਅਯੋਗ ਬਣਾਇਆ ਗਿਆ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-pl/strings.xml b/core/res/res/values-pl/strings.xml
index 84734b9..655ce2b 100644
--- a/core/res/res/values-pl/strings.xml
+++ b/core/res/res/values-pl/strings.xml
@@ -921,6 +921,54 @@
<item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> roku</item>
<item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> rok</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> minuty temu</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> minut temu</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minuty temu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minutę temu</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> godziny temu</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> godzin temu</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> godziny temu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> godzinę temu</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> dni temu</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> dni temu</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dnia temu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> dzień temu</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> lata temu</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> lat temu</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> roku temu</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> rok temu</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> minuty</item>
+ <item quantity="many">za <xliff:g id="COUNT_1">%d</xliff:g> minut</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> minuty</item>
+ <item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> minutę</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> godziny</item>
+ <item quantity="many">za <xliff:g id="COUNT_1">%d</xliff:g> godzin</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> godziny</item>
+ <item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> godzinę</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> dni</item>
+ <item quantity="many">za <xliff:g id="COUNT_1">%d</xliff:g> dni</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> dnia</item>
+ <item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> dzień</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="few">za <xliff:g id="COUNT_1">%d</xliff:g> lata</item>
+ <item quantity="many">za <xliff:g id="COUNT_1">%d</xliff:g> lat</item>
+ <item quantity="other">za <xliff:g id="COUNT_1">%d</xliff:g> roku</item>
+ <item quantity="one">za <xliff:g id="COUNT_0">%d</xliff:g> rok</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problem z filmem"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Ten film nie nadaje się do strumieniowego przesyłania do tego urządzenia."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Nie można odtworzyć tego filmu."</string>
@@ -992,8 +1040,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> przestał działać"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> wciąż przestaje działać"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> wciąż przestaje działać"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Uruchom aplikację ponownie"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Zresetuj aplikację i uruchom ją ponownie"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Ponownie otwórz aplikację"</string>
<string name="aerr_report" msgid="5371800241488400617">"Prześlij opinię"</string>
<string name="aerr_close" msgid="2991640326563991340">"Zamknij"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ignoruj do momentu ponownego uruchomienia urządzenia"</string>
@@ -1550,7 +1597,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> usunięte"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (praca)"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Aby odpiąć ten ekran, naciśnij i przytrzymaj Wstecz."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Aby odpiąć ten ekran, naciśnij i przytrzymaj Przegląd."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacja jest przypięta. Nie możesz jej odpiąć na tym urządzeniu."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran przypięty"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran odpięty"</string>
@@ -1633,6 +1679,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Żądanie SS zostało zmienione na żądanie USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Żądanie SS zostało zmienione na nowe żądanie SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil do pracy"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Przycisk rozwijania"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port peryferyjny USB na urządzeniu z Androidem"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port peryferyjny USB"</string>
@@ -1672,8 +1721,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Odepnij"</string>
<string name="app_info" msgid="6856026610594615344">"O aplikacji"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Ponowne rozpoczęcie sesji"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Kliknij, by rozpocząć nową sesję demonstracyjną"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Aby używać tego urządzenia bez ograniczeń, przywróć ustawienia fabryczne"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Kliknij, by dowiedzieć się więcej."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Wyłączono: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-pt-rBR/strings.xml b/core/res/res/values-pt-rBR/strings.xml
index f4edeb6..031d6cf 100644
--- a/core/res/res/values-pt-rBR/strings.xml
+++ b/core/res/res/values-pt-rBR/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> a</item>
<item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> minutos atrás</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minutos atrás</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> horas atrás</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> horas atrás</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> dias atrás</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dias atrás</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> anos atrás</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> anos atrás</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
+ <item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
+ <item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problema com o vídeo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Este vídeo não é válido para transmissão neste dispositivo."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Não é possível reproduzir este vídeo."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> parou"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> apresenta falhas continuamente"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> apresenta falhas continuamente"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Reiniciar app"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Redefinir e reiniciar app"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Abrir app novamente"</string>
<string name="aerr_report" msgid="5371800241488400617">"Enviar feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Fechar"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Desativar até que dispositivo seja reiniciado"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> excluído"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Trabalho: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para liberar esta tela, toque no botão \"Voltar\" e mantenha-o pressionado."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Para liberar esta tela, toque no botão \"Visão geral\" e mantenha-o pressionado."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"O app está fixado. A liberação não é permitida neste dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Tela fixada"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Tela liberada"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"A solicitação SS foi modificada para a solicitação USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"A solicitação SS foi modificada para a nova solicitação SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabalho"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Botão \"Expandir\""</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Porta USB periférica Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Porta USB periférica"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Liberar guia"</string>
<string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Reiniciar sessão"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Toque para iniciar uma nova sessão de demonstração"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Redefinir para a configuração original para usar este dispositivo sem restrições"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toque para saber mais."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Widget <xliff:g id="LABEL">%1$s</xliff:g> desativado"</string>
</resources>
diff --git a/core/res/res/values-pt-rPT/strings.xml b/core/res/res/values-pt-rPT/strings.xml
index 2bea25f..05bc0b8 100644
--- a/core/res/res/values-pt-rPT/strings.xml
+++ b/core/res/res/values-pt-rPT/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g>a</item>
<item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g>a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="one">há <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="one">há <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
+ <item quantity="one">há <xliff:g id="COUNT_0">%d</xliff:g> dia</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">há <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
+ <item quantity="one">há <xliff:g id="COUNT_0">%d</xliff:g> ano</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="one">dentro <xliff:g id="COUNT_0">%d</xliff:g> minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> hora</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> dia</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">dentro de <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
+ <item quantity="one">dentro de <xliff:g id="COUNT_0">%d</xliff:g> ano</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problema com o vídeo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Este vídeo não é válido para transmissão em fluxo contínuo neste aparelho."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Não é possível reproduzir este vídeo."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> sofreu uma falha de sistema."</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> continua a falhar"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> continua a falhar"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Reiniciar aplicação"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Repor e reiniciar aplicação"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Abrir aplicação novamente"</string>
<string name="aerr_report" msgid="5371800241488400617">"Enviar comentários"</string>
<string name="aerr_close" msgid="2991640326563991340">"Fechar"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Desativar som até o dispositivo reiniciar"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> eliminado"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de trabalho"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para soltar este ecrã, toque sem soltar em Anterior."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Para soltar este ecrã, toque sem soltar em Vista geral."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"A aplicação está fixa: não é permitido soltá-la neste dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ecrã fixo"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ecrã solto"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"O pedido SS foi modificado para um pedido USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"O pedido SS foi modificado para um novo pedido SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabalho"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Botão Expandir"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Porta periférica USB para Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Porta periférica USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Soltar"</string>
<string name="app_info" msgid="6856026610594615344">"Informações da aplicação"</string>
<string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Reiniciar sessão"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Toque para iniciar uma nova sessão de demonstração"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Repor os dados de fábrica para utilizar o dispositivo sem restrições"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toque para saber mais."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> desativado"</string>
</resources>
diff --git a/core/res/res/values-pt/strings.xml b/core/res/res/values-pt/strings.xml
index f4edeb6..031d6cf 100644
--- a/core/res/res/values-pt/strings.xml
+++ b/core/res/res/values-pt/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> a</item>
<item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> a</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> minutos atrás</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minutos atrás</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> horas atrás</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> horas atrás</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> dias atrás</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dias atrás</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> anos atrás</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> anos atrás</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ <item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> minutos</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ <item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> horas</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
+ <item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> dias</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">em <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
+ <item quantity="other">em <xliff:g id="COUNT_1">%d</xliff:g> anos</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problema com o vídeo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Este vídeo não é válido para transmissão neste dispositivo."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Não é possível reproduzir este vídeo."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> parou"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> apresenta falhas continuamente"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> apresenta falhas continuamente"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Reiniciar app"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Redefinir e reiniciar app"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Abrir app novamente"</string>
<string name="aerr_report" msgid="5371800241488400617">"Enviar feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Fechar"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Desativar até que dispositivo seja reiniciado"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> excluído"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Trabalho: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Para liberar esta tela, toque no botão \"Voltar\" e mantenha-o pressionado."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Para liberar esta tela, toque no botão \"Visão geral\" e mantenha-o pressionado."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"O app está fixado. A liberação não é permitida neste dispositivo."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Tela fixada"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Tela liberada"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"A solicitação SS foi modificada para a solicitação USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"A solicitação SS foi modificada para a nova solicitação SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Perfil de trabalho"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Botão \"Expandir\""</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Porta USB periférica Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Porta USB periférica"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Liberar guia"</string>
<string name="app_info" msgid="6856026610594615344">"Informações do app"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Reiniciar sessão"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Toque para iniciar uma nova sessão de demonstração"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Redefinir para a configuração original para usar este dispositivo sem restrições"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Toque para saber mais."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Widget <xliff:g id="LABEL">%1$s</xliff:g> desativado"</string>
</resources>
diff --git a/core/res/res/values-ro/strings.xml b/core/res/res/values-ro/strings.xml
index 023932e..dd0bc08 100644
--- a/core/res/res/values-ro/strings.xml
+++ b/core/res/res/values-ro/strings.xml
@@ -682,7 +682,7 @@
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Încercați din nou"</string>
<string name="lockscreen_password_wrong" msgid="5737815393253165301">"Încercați din nou"</string>
<string name="faceunlock_multiple_failures" msgid="754137583022792429">"S-a depășit numărul maxim de încercări pentru Deblocare facială"</string>
- <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Fără SIM."</string>
+ <string name="lockscreen_missing_sim_message_short" msgid="5099439277819215399">"Fără SIM"</string>
<string name="lockscreen_missing_sim_message" product="tablet" msgid="151659196095791474">"Nu există card SIM în computerul tablet PC."</string>
<string name="lockscreen_missing_sim_message" product="tv" msgid="1943633865476989599">"Niciun card SIM în televizor."</string>
<string name="lockscreen_missing_sim_message" product="default" msgid="2186920585695169078">"Telefonul nu are card SIM."</string>
@@ -906,6 +906,46 @@
<item quantity="other">peste <xliff:g id="COUNT_1">%d</xliff:g> de ani</item>
<item quantity="one">peste <xliff:g id="COUNT_0">%d</xliff:g> an</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="few">acum <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">acum <xliff:g id="COUNT_1">%d</xliff:g> de minute</item>
+ <item quantity="one">acum <xliff:g id="COUNT_0">%d</xliff:g> minut</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="few">acum <xliff:g id="COUNT_1">%d</xliff:g> ore</item>
+ <item quantity="other">acum <xliff:g id="COUNT_1">%d</xliff:g> de ore</item>
+ <item quantity="one">acum <xliff:g id="COUNT_0">%d</xliff:g> oră</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="few">acum <xliff:g id="COUNT_1">%d</xliff:g> zile</item>
+ <item quantity="other">acum <xliff:g id="COUNT_1">%d</xliff:g> de zile</item>
+ <item quantity="one">acum <xliff:g id="COUNT_0">%d</xliff:g> zi</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="few">acum <xliff:g id="COUNT_1">%d</xliff:g> ani</item>
+ <item quantity="other">acum <xliff:g id="COUNT_1">%d</xliff:g> de ani</item>
+ <item quantity="one">acum <xliff:g id="COUNT_0">%d</xliff:g> an</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="few">peste <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">peste <xliff:g id="COUNT_1">%d</xliff:g> de minute</item>
+ <item quantity="one">peste <xliff:g id="COUNT_0">%d</xliff:g> minut</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="few">peste <xliff:g id="COUNT_1">%d</xliff:g> ore</item>
+ <item quantity="other">peste <xliff:g id="COUNT_1">%d</xliff:g> de ore</item>
+ <item quantity="one">peste <xliff:g id="COUNT_0">%d</xliff:g> oră</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="few">peste <xliff:g id="COUNT_1">%d</xliff:g> zile</item>
+ <item quantity="other">peste <xliff:g id="COUNT_1">%d</xliff:g> de zile</item>
+ <item quantity="one">peste <xliff:g id="COUNT_0">%d</xliff:g> zi</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="few">peste <xliff:g id="COUNT_1">%d</xliff:g> ani</item>
+ <item quantity="other">peste <xliff:g id="COUNT_1">%d</xliff:g> de ani</item>
+ <item quantity="one">peste <xliff:g id="COUNT_0">%d</xliff:g> an</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problemă video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Acest fișier video nu este valid pentru a fi transmis în flux către acest dispozitiv."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Nu puteți reda acest videoclip"</string>
@@ -977,8 +1017,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> s-a oprit"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> se oprește încontinuu"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> se oprește încontinuu"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Reporniți aplicația"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Resetați și reporniți aplicația"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Deschideți din nou aplicația"</string>
<string name="aerr_report" msgid="5371800241488400617">"Trimiteți feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Închideți"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Dezactivați până la repornirea dispozitivului"</string>
@@ -1531,7 +1570,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> a fost șters"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> de serviciu"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Pentru a anula fixarea acestui ecran, atingeți lung opțiunea Înapoi."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Pentru a anula fixarea acestui ecran, atingeți lung opțiunea Recente."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplicația este fixată: Anularea fixării nu este permisă pe acest dispozitiv."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ecran fixat"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Fixarea ecranului anulată"</string>
@@ -1606,6 +1644,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Solicitarea SS este modificată într-o solicitare USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Solicitarea SS este modificată într-o nouă solicitare SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profil de serviciu"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Butonul de extindere"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port USB Android periferic"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port USB periferic"</string>
@@ -1644,8 +1685,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Anulați fixarea"</string>
<string name="app_info" msgid="6856026610594615344">"Informații despre aplicație"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Reporniți sesiunea"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Atingeți pentru a începe o nouă sesiune demonstrativă"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Reveniți la setările din fabrică pentru a folosi acest dispozitiv fără restricții"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Atingeți pentru a afla mai multe."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> a fost dezactivat"</string>
</resources>
diff --git a/core/res/res/values-ru/strings.xml b/core/res/res/values-ru/strings.xml
index 4767638..4b859f7 100644
--- a/core/res/res/values-ru/strings.xml
+++ b/core/res/res/values-ru/strings.xml
@@ -921,6 +921,54 @@
<item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> л.</item>
<item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> г.</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> минуту назад</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> минуты назад</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> минут назад</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> минуты назад</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> час назад</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> часа назад</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> часов назад</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> часа назад</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> день назад</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> дня назад</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> дней назад</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> дня назад</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> год назад</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> года назад</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> лет назад</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> года назад</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">через <xliff:g id="COUNT_1">%d</xliff:g> минуту</item>
+ <item quantity="few">через <xliff:g id="COUNT_1">%d</xliff:g> минуты</item>
+ <item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> минут</item>
+ <item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> минуты</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">через <xliff:g id="COUNT_1">%d</xliff:g> час</item>
+ <item quantity="few">через <xliff:g id="COUNT_1">%d</xliff:g> часа</item>
+ <item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> часов</item>
+ <item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> часа</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">через <xliff:g id="COUNT_1">%d</xliff:g> день</item>
+ <item quantity="few">через <xliff:g id="COUNT_1">%d</xliff:g> дня</item>
+ <item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> дней</item>
+ <item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> дня</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">через <xliff:g id="COUNT_1">%d</xliff:g> год</item>
+ <item quantity="few">через <xliff:g id="COUNT_1">%d</xliff:g> года</item>
+ <item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> лет</item>
+ <item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> года</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Ошибка"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Это видео не предназначено для потокового воспроизведения на данном устройстве."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Не удалось воспроизвести видео."</string>
@@ -992,8 +1040,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Во время процесса \"<xliff:g id="PROCESS">%1$s</xliff:g>\" произошел сбой"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"В приложении \"<xliff:g id="APPLICATION">%1$s</xliff:g>\" снова произошел сбой"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"В приложении \"<xliff:g id="PROCESS">%1$s</xliff:g>\" снова произошел сбой"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Перезапустить приложение"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Сбросить и перезапустить"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Перезапустить приложение"</string>
<string name="aerr_report" msgid="5371800241488400617">"Отправить отзыв"</string>
<string name="aerr_close" msgid="2991640326563991340">"Закрыть"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Отключить до перезагрузки устройства"</string>
@@ -1550,7 +1597,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Цифра <xliff:g id="KEY">%1$s</xliff:g> удалена"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Рабочий <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Чтобы открепить экран, нажмите и удерживайте кнопку \"Назад\"."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Чтобы открепить экран, нажмите и удерживайте кнопку \"Обзор\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Включена блокировка в приложении. Ее отключение запрещено правилами организации."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Блокировка включена"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Блокировка выключена"</string>
@@ -1633,6 +1679,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-запрос преобразован в USSD-запрос."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-запрос преобразован в новый SS-запрос."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Рабочий профиль"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Кнопка \"Развернуть\""</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Внешний USB-порт Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Внешний USB-порт"</string>
@@ -1672,8 +1721,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Открепить"</string>
<string name="app_info" msgid="6856026610594615344">"О приложении"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Начните сеанс заново"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Нажмите, чтобы начать новый демосеанс."</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Сброс до заводских настроек для работы без ограничений"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Нажмите, чтобы узнать больше."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Виджет <xliff:g id="LABEL">%1$s</xliff:g> отключен"</string>
</resources>
diff --git a/core/res/res/values-si-rLK/strings.xml b/core/res/res/values-si-rLK/strings.xml
index fc99747..1e21275 100644
--- a/core/res/res/values-si-rLK/strings.xml
+++ b/core/res/res/values-si-rLK/strings.xml
@@ -893,6 +893,38 @@
<item quantity="one">ව <xliff:g id="COUNT_1">%d</xliff:g>කදී</item>
<item quantity="other">ව <xliff:g id="COUNT_1">%d</xliff:g>කදී</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">මිනිත්තු <xliff:g id="COUNT_1">%d</xliff:g>කට පෙර</item>
+ <item quantity="other">මිනිත්තු <xliff:g id="COUNT_1">%d</xliff:g>කට පෙර</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">පැය <xliff:g id="COUNT_1">%d</xliff:g>කට පෙර</item>
+ <item quantity="other">පැය <xliff:g id="COUNT_1">%d</xliff:g>කට පෙර</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">දින <xliff:g id="COUNT_1">%d</xliff:g>කට පෙර</item>
+ <item quantity="other">දින <xliff:g id="COUNT_1">%d</xliff:g>කට පෙර</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">වසර <xliff:g id="COUNT_1">%d</xliff:g>කට පෙර</item>
+ <item quantity="other">වසර <xliff:g id="COUNT_1">%d</xliff:g>කට පෙර</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">මිනිත්තු <xliff:g id="COUNT_1">%d</xliff:g>කින්</item>
+ <item quantity="other">මිනිත්තු <xliff:g id="COUNT_1">%d</xliff:g>කින්</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">පැය <xliff:g id="COUNT_1">%d</xliff:g>කින්</item>
+ <item quantity="other">පැය <xliff:g id="COUNT_1">%d</xliff:g>කින්</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">දින <xliff:g id="COUNT_1">%d</xliff:g>කින්</item>
+ <item quantity="other">දින <xliff:g id="COUNT_1">%d</xliff:g>කින්</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">වසර <xliff:g id="COUNT_1">%d</xliff:g>කින්</item>
+ <item quantity="other">වසර <xliff:g id="COUNT_1">%d</xliff:g>කින්</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"වීඩියෝ ගැටලුව"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"මේ වීඩියෝව මෙම උපාංගයට ප්රවාහනය සඳහා වලංගු නැත."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"මෙම වීඩියෝව ධාවනය කළ නොහැක."</string>
@@ -964,8 +996,8 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> නැවතී ඇත"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> නැවතෙමින් ඇත"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> නැවතෙමින් ඇත"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"යෙදුම නැවත ආරම්භ කරන්න"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"යෙදුම නැවත සකසා නැවත ආරම්භ කරන්න"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"ප්රතිපෝෂණය යවන්න"</string>
<string name="aerr_close" msgid="2991640326563991340">"වසන්න"</string>
<string name="aerr_mute" msgid="1974781923723235953">"උපාංගය නැවත ආරම්භ වන තෙක් නිහඬ කරන්න"</string>
@@ -1514,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> මකා දමන ලදි"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"වැඩ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"මෙම තිරය ඇමුණුම් ඉවත් කිරීමට, ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"මෙම තිරය ඇමුණුම් ඉවත් කිරීමට, දළ විශ්ලේෂණය ස්පර්ශ කර අල්ලා ගෙන සිටින්න."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"යෙදුම අමුණා ඇත: ගැලවීමට මෙම උපාංගය මත ඉඩ දිය නොහැකිය."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"තිරය අගුළු දමා ඇත"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"තිරයේ අගුළු ඇර ඇත"</string>
@@ -1581,6 +1612,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS ඉල්ලීම USSD ඉල්ලීම වෙත විකරණය කරන ලදී."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS ඉල්ලීම නව DIAL ඉල්ලීම වෙත විකරණය කරන ලදී."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"කාර්යාල පැතිකඩ"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB පර්යන්ත තොට"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB පර්යන්ත තොට"</string>
@@ -1618,8 +1653,11 @@
<string name="unpin_target" msgid="3556545602439143442">"ගලවන්න"</string>
<string name="app_info" msgid="6856026610594615344">"යෙදුම් තොරතුරු"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"සීමා කිරීම්වලින් තොරව මෙම උපාංගය භාවිත කිරීමට කර්මාන්ත ශාලා යළි සැකසීම"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"තව දැන ගැනීමට ස්පර්ශ කරන්න."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"අබල කළ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-sk/strings.xml b/core/res/res/values-sk/strings.xml
index bafb794..430619c 100644
--- a/core/res/res/values-sk/strings.xml
+++ b/core/res/res/values-sk/strings.xml
@@ -679,7 +679,7 @@
<string name="lockscreen_instructions_when_pattern_enabled" msgid="46154051614126049">"Ak chcete odomknúť telefón alebo uskutočniť tiesňové volanie, stlačte Menu."</string>
<string name="lockscreen_instructions_when_pattern_disabled" msgid="686260028797158364">"Telefón odomknete stlačením tlačidla Menu."</string>
<string name="lockscreen_pattern_instructions" msgid="7478703254964810302">"Odomknite nakreslením vzoru"</string>
- <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Tiesňové volanie"</string>
+ <string name="lockscreen_emergency_call" msgid="5298642613417801888">"Stav tiesne"</string>
<string name="lockscreen_return_to_call" msgid="5244259785500040021">"Zavolať späť"</string>
<string name="lockscreen_pattern_correct" msgid="9039008650362261237">"Správne!"</string>
<string name="lockscreen_pattern_wrong" msgid="4317955014948108794">"Skúsiť znova"</string>
@@ -921,6 +921,54 @@
<item quantity="other">o <xliff:g id="COUNT_1">%d</xliff:g> r.</item>
<item quantity="one">o <xliff:g id="COUNT_0">%d</xliff:g> r.</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> minútami</item>
+ <item quantity="many">pred <xliff:g id="COUNT_1">%d</xliff:g> minútou</item>
+ <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> minútami</item>
+ <item quantity="one">pred <xliff:g id="COUNT_0">%d</xliff:g> minútou</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> hodinami</item>
+ <item quantity="many">pred <xliff:g id="COUNT_1">%d</xliff:g> hodinou</item>
+ <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> hodinami</item>
+ <item quantity="one">pred <xliff:g id="COUNT_0">%d</xliff:g> hodinou</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> dňami</item>
+ <item quantity="many">pred <xliff:g id="COUNT_1">%d</xliff:g> dňom</item>
+ <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> dňami</item>
+ <item quantity="one">pred <xliff:g id="COUNT_0">%d</xliff:g> dňom</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> rokmi</item>
+ <item quantity="many">pred <xliff:g id="COUNT_1">%d</xliff:g> rokom</item>
+ <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> rokmi</item>
+ <item quantity="one">pred <xliff:g id="COUNT_0">%d</xliff:g> rokom</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="few">o <xliff:g id="COUNT_1">%d</xliff:g> minúty</item>
+ <item quantity="many">o <xliff:g id="COUNT_1">%d</xliff:g> minúty</item>
+ <item quantity="other">o <xliff:g id="COUNT_1">%d</xliff:g> minút</item>
+ <item quantity="one">o <xliff:g id="COUNT_0">%d</xliff:g> minútu</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="few">o <xliff:g id="COUNT_1">%d</xliff:g> hodiny</item>
+ <item quantity="many">o <xliff:g id="COUNT_1">%d</xliff:g> hodiny</item>
+ <item quantity="other">o <xliff:g id="COUNT_1">%d</xliff:g> hodín</item>
+ <item quantity="one">o <xliff:g id="COUNT_0">%d</xliff:g> hodinu</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="few">o <xliff:g id="COUNT_1">%d</xliff:g> dni</item>
+ <item quantity="many">o <xliff:g id="COUNT_1">%d</xliff:g> dňa</item>
+ <item quantity="other">o <xliff:g id="COUNT_1">%d</xliff:g> dní</item>
+ <item quantity="one">o <xliff:g id="COUNT_0">%d</xliff:g> deň</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="few">o <xliff:g id="COUNT_1">%d</xliff:g> roky</item>
+ <item quantity="many">o <xliff:g id="COUNT_1">%d</xliff:g> roka</item>
+ <item quantity="other">o <xliff:g id="COUNT_1">%d</xliff:g> rokov</item>
+ <item quantity="one">o <xliff:g id="COUNT_0">%d</xliff:g> rok</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problém s videom"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Je nám ľúto, ale toto video sa nedá streamovať do tohto zariadenia."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Toto video nie je možné prehrať."</string>
@@ -992,8 +1040,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> sa zastavil"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> sa opakovane zastavuje"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> sa opakovane zastavuje"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Reštartovať aplikáciu"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Resetovať a reštartovať aplikáciu"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Spustiť aplikáciu znova"</string>
<string name="aerr_report" msgid="5371800241488400617">"Odoslať spätnú väzbu"</string>
<string name="aerr_close" msgid="2991640326563991340">"Zavrieť"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ignorovať do reštartu zariadenia"</string>
@@ -1550,7 +1597,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Číslo <xliff:g id="KEY">%1$s</xliff:g> bolo odstránené"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Práca – <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Ak chcete uvoľniť túto obrazovku, klepnite na tlačidlo Späť a podržte ho."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Ak chcete uvoľniť túto obrazovku, klepnite na tlačidlo Prehľad a podržte ho."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikácia je pripnutá. Uvoľnenie nie je na tomto zariadení povolené."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Obrazovka bola pripnutá"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Obrazovka bola uvoľnená"</string>
@@ -1633,6 +1679,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Žiadosť SS bola upravená na žiadosť USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Žiadosť SS bola upravená na novú žiadosť SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Pracovný profil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Tlačidlo rozbalenia"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Port USB pre periférne zariadenia s Androidom"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Port USB pre periférne zariadenia"</string>
@@ -1672,8 +1721,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Uvoľniť"</string>
<string name="app_info" msgid="6856026610594615344">"Info o aplikácii"</string>
<string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Reštartujte reláciu"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Klepnutím začnete novú demo reláciu"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Ak chcete toto zariadenie používať bez obmedzení, obnovte na ňom továrenské nastavenia"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Klepnutím získate ďalšie informácie."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Deaktivovaná miniaplikácia <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-sl/strings.xml b/core/res/res/values-sl/strings.xml
index 2780808..ccaa4f8 100644
--- a/core/res/res/values-sl/strings.xml
+++ b/core/res/res/values-sl/strings.xml
@@ -535,7 +535,7 @@
<string name="policylab_wipeData" msgid="3910545446758639713">"Brisanje vseh podatkov"</string>
<string name="policydesc_wipeData" product="tablet" msgid="4306184096067756876">"Izbris podatkov v tabličnem računalniku brez opozorila s ponastavitvijo na tovarniške nastavitve"</string>
<string name="policydesc_wipeData" product="tv" msgid="5816221315214527028">"Brez opozorila izbriše podatke v televizorju, tako da izvede ponastavitev na tovarniške nastavitve."</string>
- <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Izbris podatkov v telefonu brez opozorila s ponastavitvijo na tovarniške nastavitve"</string>
+ <string name="policydesc_wipeData" product="default" msgid="5096895604574188391">"Izbris podatkov v telefonu brez opozorila s ponastavitvijo na tovarniške nastavitve."</string>
<string name="policylab_wipeData_secondaryUser" msgid="8362863289455531813">"Izbris podatkov uporabnika"</string>
<string name="policydesc_wipeData_secondaryUser" product="tablet" msgid="6336255514635308054">"Izbris podatkov uporabnika v tem tabličnem računalniku brez opozorila."</string>
<string name="policydesc_wipeData_secondaryUser" product="tv" msgid="2086473496848351810">"Izbris podatkov uporabnika v tem televizorju brez opozorila."</string>
@@ -921,6 +921,54 @@
<item quantity="few">čez <xliff:g id="COUNT_1">%d</xliff:g> l</item>
<item quantity="other">čez <xliff:g id="COUNT_1">%d</xliff:g> l</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">ped <xliff:g id="COUNT_1">%d</xliff:g> minuto</item>
+ <item quantity="two">pred <xliff:g id="COUNT_1">%d</xliff:g> minutama</item>
+ <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> minutami</item>
+ <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> minutami</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">pred <xliff:g id="COUNT_1">%d</xliff:g> uro</item>
+ <item quantity="two">pred <xliff:g id="COUNT_1">%d</xliff:g> urama</item>
+ <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> urami</item>
+ <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> urami</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">pred <xliff:g id="COUNT_1">%d</xliff:g> dnevom</item>
+ <item quantity="two">pred <xliff:g id="COUNT_1">%d</xliff:g> dnevoma</item>
+ <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> dnevi</item>
+ <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> dnevi</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">pred <xliff:g id="COUNT_1">%d</xliff:g> letom</item>
+ <item quantity="two">pred <xliff:g id="COUNT_1">%d</xliff:g> letoma</item>
+ <item quantity="few">pred <xliff:g id="COUNT_1">%d</xliff:g> leti</item>
+ <item quantity="other">pred <xliff:g id="COUNT_1">%d</xliff:g> leti</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">čez <xliff:g id="COUNT_1">%d</xliff:g> minuto</item>
+ <item quantity="two">čez <xliff:g id="COUNT_1">%d</xliff:g> minuti</item>
+ <item quantity="few">čez <xliff:g id="COUNT_1">%d</xliff:g> minute</item>
+ <item quantity="other">čez <xliff:g id="COUNT_1">%d</xliff:g> minut</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">čez <xliff:g id="COUNT_1">%d</xliff:g> uro</item>
+ <item quantity="two">čez <xliff:g id="COUNT_1">%d</xliff:g> uri</item>
+ <item quantity="few">čez <xliff:g id="COUNT_1">%d</xliff:g> ure</item>
+ <item quantity="other">čez <xliff:g id="COUNT_1">%d</xliff:g> ur</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">čez <xliff:g id="COUNT_1">%d</xliff:g> dan</item>
+ <item quantity="two">čez <xliff:g id="COUNT_1">%d</xliff:g> dneva</item>
+ <item quantity="few">čez <xliff:g id="COUNT_1">%d</xliff:g> dni</item>
+ <item quantity="other">čez <xliff:g id="COUNT_1">%d</xliff:g> dni</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">čez <xliff:g id="COUNT_1">%d</xliff:g> leto</item>
+ <item quantity="two">čez <xliff:g id="COUNT_1">%d</xliff:g> leti</item>
+ <item quantity="few">čez <xliff:g id="COUNT_1">%d</xliff:g> leta</item>
+ <item quantity="other">čez <xliff:g id="COUNT_1">%d</xliff:g> let</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Težava z videoposnetkom"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Ta videoposnetek ni veljaven za pretakanje v to napravo."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Tega videoposnetka ni mogoče predvajati."</string>
@@ -992,8 +1040,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se je ustavil"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"Aplikacija <xliff:g id="APPLICATION">%1$s</xliff:g> se stalno ustavlja"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Proces <xliff:g id="PROCESS">%1$s</xliff:g> se stalno ustavlja"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Vnovični zagon aplikacije"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Ponastavitev in vnovični zagon aplikacije"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Znova odpri aplikacijo"</string>
<string name="aerr_report" msgid="5371800241488400617">"Pošlji povratne informacije"</string>
<string name="aerr_close" msgid="2991640326563991340">"Zapri"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Prezri do vnovičnega zagona naprave"</string>
@@ -1550,7 +1597,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Številka <xliff:g id="KEY">%1$s</xliff:g> je izbrisana"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> za delo"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Če želite odpeti ta zaslon, se dotaknite tipke za nazaj in jo pridržite."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Če želite odpeti ta zaslon, se dotaknite tipke za pregled in jo pridržite."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Aplikacija je pripeta: v tej napravi odpenjanje ni dovoljeno."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Zaslon je pripet"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Zaslon je odpet"</string>
@@ -1633,6 +1679,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Zahteva SS je spremenjena v zahtevo USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Zahteva SS je spremenjena v novo zahtevo SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Delovni profil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Gumb za razširitev"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Vrata USB za dodatno opremo za Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Vrata USB za dodatno opremo"</string>
@@ -1672,8 +1721,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Odpenjanje"</string>
<string name="app_info" msgid="6856026610594615344">"Podatki o aplikaciji"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Vnovični zagon seje"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Dotaknite se, če želite začeti novo predstavitveno sejo"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Ponastavitev naprave na tovarniške nastavitve za uporabo brez omejitev"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Dotaknite se, če želite izvedeti več."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> – onemogočeno"</string>
</resources>
diff --git a/core/res/res/values-sq-rAL/strings.xml b/core/res/res/values-sq-rAL/strings.xml
index fc3fac4..ede50ba 100644
--- a/core/res/res/values-sq-rAL/strings.xml
+++ b/core/res/res/values-sq-rAL/strings.xml
@@ -247,7 +247,7 @@
<string name="permgrouplab_location" msgid="7275582855722310164">"Vendndodhja"</string>
<string name="permgroupdesc_location" msgid="1346617465127855033">"qasjen te vendndodhja e kësaj pajisjeje"</string>
<string name="permgrouplab_calendar" msgid="5863508437783683902">"Kalendari"</string>
- <string name="permgroupdesc_calendar" msgid="3889615280211184106">"qasu te kalendari yt"</string>
+ <string name="permgroupdesc_calendar" msgid="3889615280211184106">"qasje te kalendari yt"</string>
<string name="permgrouplab_sms" msgid="228308803364967808">"SMS"</string>
<string name="permgroupdesc_sms" msgid="4656988620100940350">"dërgo dhe shiko mesazhet SMS"</string>
<string name="permgrouplab_storage" msgid="1971118770546336966">"Hapësira e ruajtjes"</string>
@@ -891,6 +891,38 @@
<item quantity="other">në <xliff:g id="COUNT_1">%d</xliff:g> vite</item>
<item quantity="one">në <xliff:g id="COUNT_0">%d</xliff:g> vit</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> minuta më parë</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> minutë më parë</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> orë më parë</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> orë më parë</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ditë më parë</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ditë më parë</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> vite më parë</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> vit më parë</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">për <xliff:g id="COUNT_1">%d</xliff:g> minuta</item>
+ <item quantity="one">për <xliff:g id="COUNT_0">%d</xliff:g> minutë</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">për <xliff:g id="COUNT_1">%d</xliff:g> orë</item>
+ <item quantity="one">për <xliff:g id="COUNT_0">%d</xliff:g> orë</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">për <xliff:g id="COUNT_1">%d</xliff:g> ditë</item>
+ <item quantity="one">për <xliff:g id="COUNT_0">%d</xliff:g> ditë</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">për <xliff:g id="COUNT_1">%d</xliff:g> vite</item>
+ <item quantity="one">për <xliff:g id="COUNT_0">%d</xliff:g> vit</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problem me videon"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Kjo video nuk ofrohet për transmetim në këtë pajisje."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Videoja nuk mund të luhet."</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> ka ndaluar"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> vazhdon të ndalojë"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> vazhdon të ndalojë"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Rinis aplikacionin"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Rivendos dhe rinis aplikacionin"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Dërgo komentin"</string>
<string name="aerr_close" msgid="2991640326563991340">"Mbyll"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Vendose në heshtje deri kur të riniset pajisja"</string>
@@ -1515,7 +1547,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> u fshi"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Puna <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Për të hequr gozhdimin e ekranit, prek dhe mbaj të shtypur \"Prapa\"."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Për të hequr gozhdimin e ekranit, prek dhe mbaj të shtypur \"Përmbledhja\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Ekrani është i gozhduar. Anulimi i mbërthimit nuk lejohet nga organizata jote."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekrani u gozhdua"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekrani u hoq nga gozhdimi"</string>
@@ -1582,6 +1613,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Kërkesa SS është modifikuar në kërkesën USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Kërkesa SS është e modifikuar në kërkesën e re SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profili i punës"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Porta periferike USB e Androidit"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Porta periferike USB"</string>
@@ -1619,8 +1654,11 @@
<string name="unpin_target" msgid="3556545602439143442">"Zhgozhdo"</string>
<string name="app_info" msgid="6856026610594615344">"Informacioni mbi aplikacionin"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Rivendos cilësimet e fabrikës për ta përdorur këtë pajisje pa kufizime"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Prek për të mësuar më shumë."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> u çaktivizua"</string>
</resources>
diff --git a/core/res/res/values-sr/strings.xml b/core/res/res/values-sr/strings.xml
index 1a63a3b..cbd16e8 100644
--- a/core/res/res/values-sr/strings.xml
+++ b/core/res/res/values-sr/strings.xml
@@ -906,6 +906,46 @@
<item quantity="few">за <xliff:g id="COUNT_1">%d</xliff:g> год</item>
<item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g> год</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one">пре <xliff:g id="COUNT_1">%d</xliff:g> минута</item>
+ <item quantity="few">пре <xliff:g id="COUNT_1">%d</xliff:g> минута</item>
+ <item quantity="other">пре <xliff:g id="COUNT_1">%d</xliff:g> минута</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one">пре <xliff:g id="COUNT_1">%d</xliff:g> сата</item>
+ <item quantity="few">пре <xliff:g id="COUNT_1">%d</xliff:g> сата</item>
+ <item quantity="other">пре <xliff:g id="COUNT_1">%d</xliff:g> сати</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one">Пре <xliff:g id="COUNT_1">%d</xliff:g> дана</item>
+ <item quantity="few">Пре <xliff:g id="COUNT_1">%d</xliff:g> дана</item>
+ <item quantity="other">Пре <xliff:g id="COUNT_1">%d</xliff:g> дана</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one">пре <xliff:g id="COUNT_1">%d</xliff:g> године</item>
+ <item quantity="few">пре <xliff:g id="COUNT_1">%d</xliff:g> године</item>
+ <item quantity="other">пре <xliff:g id="COUNT_1">%d</xliff:g> година</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">за <xliff:g id="COUNT_1">%d</xliff:g> минут</item>
+ <item quantity="few">за <xliff:g id="COUNT_1">%d</xliff:g> минута</item>
+ <item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g> минута</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">за <xliff:g id="COUNT_1">%d</xliff:g> сат</item>
+ <item quantity="few">за <xliff:g id="COUNT_1">%d</xliff:g> сата</item>
+ <item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g> сати</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">за <xliff:g id="COUNT_1">%d</xliff:g> дан</item>
+ <item quantity="few">за <xliff:g id="COUNT_1">%d</xliff:g> дана</item>
+ <item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g> дана</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">за <xliff:g id="COUNT_1">%d</xliff:g> годину</item>
+ <item quantity="few">за <xliff:g id="COUNT_1">%d</xliff:g> године</item>
+ <item quantity="other">за <xliff:g id="COUNT_1">%d</xliff:g> година</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Проблем са видео снимком"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Овај видео не може да се стримује на овом уређају."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Не можете да пустите овај видео."</string>
@@ -977,8 +1017,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> је заустављен"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> се стално зауставља"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> се стално зауставља"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Поново покрени апликацију"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Ресетуј и поново покрени апликацију"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Поново отвори апликацију"</string>
<string name="aerr_report" msgid="5371800241488400617">"Пошаљите повратне информације"</string>
<string name="aerr_close" msgid="2991640326563991340">"Затвори"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Игнориши док се уређај не покрене поново"</string>
@@ -1531,7 +1570,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Избрисали сте <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> на послу"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Да бисте откачили овај екран, додирните и задржите Назад."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Да бисте откачили овај екран, додирните и задржите Преглед."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Апликација је закачена: откачињање није дозвољено на овом уређају."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Екран је закачен"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Екран је откачен"</string>
@@ -1606,6 +1644,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS захтев је промењен у USSD захтев."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS захтев је промењен у нови SS захтев."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Профил за Work"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Дугме Прошири"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB порт за периферијске уређаје"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB порт за периферијске уређаје"</string>
@@ -1644,8 +1685,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Откачи"</string>
<string name="app_info" msgid="6856026610594615344">"Информације о апликацији"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Поново покрените сесију"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Додирните да бисте покренули нову сесију демонстрације"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Ресетујте уређај на фабричка подешавања да бисте га користили без ограничења"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Додирните да бисте сазнали више."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Виџет <xliff:g id="LABEL">%1$s</xliff:g> је онемогућен"</string>
</resources>
diff --git a/core/res/res/values-sv/strings.xml b/core/res/res/values-sv/strings.xml
index f69d620..2113440 100644
--- a/core/res/res/values-sv/strings.xml
+++ b/core/res/res/values-sv/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> år</item>
<item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> år</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">för <xliff:g id="COUNT_1">%d</xliff:g> minuter sedan</item>
+ <item quantity="one">för <xliff:g id="COUNT_0">%d</xliff:g> minut sedan</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">för <xliff:g id="COUNT_1">%d</xliff:g> timmar sedan</item>
+ <item quantity="one">för <xliff:g id="COUNT_0">%d</xliff:g> timme sedan</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">för <xliff:g id="COUNT_1">%d</xliff:g> dagar sedan</item>
+ <item quantity="one">för <xliff:g id="COUNT_0">%d</xliff:g> dag sedan</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">för <xliff:g id="COUNT_1">%d</xliff:g> år sedan</item>
+ <item quantity="one">för <xliff:g id="COUNT_0">%d</xliff:g> år sedan</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> minuter</item>
+ <item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> minut</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> timmar</item>
+ <item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> timme</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> dagar</item>
+ <item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> dag</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">om <xliff:g id="COUNT_1">%d</xliff:g> år</item>
+ <item quantity="one">om <xliff:g id="COUNT_0">%d</xliff:g> år</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Videoproblem"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Videon kan tyvärr inte spelas upp i den här enheten."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Det går inte att spela upp videon."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> har kraschat"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> kraschar gång på gång"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> kraschar gång på gång"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Starta om appen"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Återställ och starta om appen"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Öppna appen igen"</string>
<string name="aerr_report" msgid="5371800241488400617">"Skicka feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Stäng"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Ignorera tills enheten har startat om"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> har tagits bort"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> för arbetet"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Om du vill lossa skärmen trycker du länge på Tillbaka."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Om du vill lossa skämen trycker du länge på Översikt."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Appen är fäst. Att lossa den är inte tillåtet på den här enheten."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skärmen är fäst"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Skärmen är inte längre fäst"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS-begäran har ändrats till en USSD-begäran."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS-begäran har ändrats till en ny SS-begäran."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Jobbprofil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Knappen Utöka"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"USB-port för Android-kringutrustning"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB-port för kringutrustning"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Lossa"</string>
<string name="app_info" msgid="6856026610594615344">"Info om appen"</string>
<string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Starta om sessionen"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Tryck om du vill starta en ny demosession"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Återställ enheten till standardinställningarna om du vill använda den utan begränsningar"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Tryck här om du vill läsa mer."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> har inaktiverats"</string>
</resources>
diff --git a/core/res/res/values-sw/strings.xml b/core/res/res/values-sw/strings.xml
index be3acf0..cad5f6a 100644
--- a/core/res/res/values-sw/strings.xml
+++ b/core/res/res/values-sw/strings.xml
@@ -889,6 +889,38 @@
<item quantity="other">kwa miaka <xliff:g id="COUNT_1">%d</xliff:g></item>
<item quantity="one">kwa maka <xliff:g id="COUNT_0">%d</xliff:g></item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other">Dakika <xliff:g id="COUNT_1">%d</xliff:g> zilizopita</item>
+ <item quantity="one">Dakika <xliff:g id="COUNT_0">%d</xliff:g> iliyopita</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other">Saa <xliff:g id="COUNT_1">%d</xliff:g> zilizopita</item>
+ <item quantity="one">Saa <xliff:g id="COUNT_0">%d</xliff:g> iliyopita</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other">Siku <xliff:g id="COUNT_1">%d</xliff:g> zilizopita</item>
+ <item quantity="one">Siku <xliff:g id="COUNT_0">%d</xliff:g> iliyopita</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other">Miaka <xliff:g id="COUNT_1">%d</xliff:g> iliyopita</item>
+ <item quantity="one">Mwaka <xliff:g id="COUNT_0">%d</xliff:g> uliopita</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">baada ya dakika <xliff:g id="COUNT_1">%d</xliff:g></item>
+ <item quantity="one">baada ya dakika <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">baada ya saa <xliff:g id="COUNT_1">%d</xliff:g></item>
+ <item quantity="one">baada ya saa <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">baada ya siku <xliff:g id="COUNT_1">%d</xliff:g></item>
+ <item quantity="one">baada ya siku <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">baada ya miaka <xliff:g id="COUNT_1">%d</xliff:g></item>
+ <item quantity="one">baada ya mwaka <xliff:g id="COUNT_0">%d</xliff:g></item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Shida ya video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Video hii si halali kutiririshwa kwa kifaa hiki."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Haiwezi kucheza video hii."</string>
@@ -960,8 +992,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> imeacha kufanya kazi"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> inaacha kufanya kazi kila mara"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> inaacha kufanya kazi kila mara"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Anzisha upya programu"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Weka na uanzishe upya programu"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Fungua programu tena"</string>
<string name="aerr_report" msgid="5371800241488400617">"Tuma maoni yako"</string>
<string name="aerr_close" msgid="2991640326563991340">"Funga"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Komesha hadi kifaa kianze upya"</string>
@@ -1510,7 +1541,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> kimefutwa"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Ya kazini <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Ili kubandua skrini hii, gusa na ushikilie Nyuma."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Ili kubandua skrini hii, gusa na ushikile Muhtasari."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Programu imebanwa: Kubanuliwa hakuruhusiwi kwenye kifaa hiki."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Skrini imebandikwa"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Skrini imebanduliwa"</string>
@@ -1577,6 +1607,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Ombi la SS limerekebishwa na kuwa ombi la USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Ombi la SS limerekebishwa na kuwa ombi jipya la SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Wasifu wa kazini"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Kitufe cha kupanua"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Mlango wa USB wa Pembeni wa Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Mlango wa USB wa Pembeni"</string>
@@ -1614,8 +1647,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Bandua"</string>
<string name="app_info" msgid="6856026610594615344">"Maelezo ya programu"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Anzisha Kipindi Upya"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Gonga ili uanzishe kipindi kipya cha onyesho"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Rejesha mipangilio iliyotoka nayo kiwandani ili utumie kifaa hiki bila vikwazo"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Gusa ili kupata maelezo zaidi."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> imezimwa"</string>
</resources>
diff --git a/core/res/res/values-ta-rIN/strings.xml b/core/res/res/values-ta-rIN/strings.xml
index 8216c50..f3b456f 100644
--- a/core/res/res/values-ta-rIN/strings.xml
+++ b/core/res/res/values-ta-rIN/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ஆண்டுகளில்</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ஆண்டில்</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> நிமிடங்களுக்கு முன்பு</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> நிமிடத்திற்கு முன்பு</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> மணிநேரத்திற்கு முன்பு</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> மணிநேரத்திற்கு முன்பு</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> நாட்களுக்கு முன்பு</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> நாளுக்கு முன்பு</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ஆண்டுகளுக்கு முன்பு</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ஆண்டிற்கு முன்பு</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">in <xliff:g id="COUNT_1">%d</xliff:g> நிமிடங்களில்</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> நிமிடத்தில்</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> மணிநேரத்தில்</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> மணிநேரத்தில்</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> நாட்களில்</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> நாளில்</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ஆண்டுகளில்</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ஆண்டில்</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"வீடியோவில் சிக்கல்"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"சாதனத்தில் ஸ்ட்ரீம் செய்வதற்கு இது சரியான வீடியோ அல்ல."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"இந்த வீடியோவை இயக்க முடியவில்லை."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> செயலிழந்தது"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> தொடர்ந்து செயலிழக்கிறது"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> தொடர்ந்து செயலிழக்கிறது"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"பயன்பாட்டை மீண்டும் தொடங்கு"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"பயன்பாட்டை மீட்டமைத்து மீண்டும் தொடங்கு"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"பயன்பாட்டை மீண்டும் திற"</string>
<string name="aerr_report" msgid="5371800241488400617">"கருத்து தெரிவி"</string>
<string name="aerr_close" msgid="2991640326563991340">"மூடு"</string>
<string name="aerr_mute" msgid="1974781923723235953">"சாதனம் மீண்டும் தொடங்கும் வரை முடக்கு"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> நீக்கப்பட்டது"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"பணியிடம் <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"இந்தத் திரையை விலக்க, \"முந்தையது\" பொத்தானைத் தொட்டுப் பிடிக்கவும்."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"இந்தத் திரையை விலக்க, \"மேலோட்டப் பார்வை\" பொத்தானைத் தொட்டுப் பிடிக்கவும்."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"பயன்பாடு பொருத்தப்பட்டது: பொருத்தியதை நீக்குவதற்கு இந்தச் சாதனத்தில் அனுமதியில்லை."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"திரை பின் செய்யப்பட்டது"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"திரையின் பின் அகற்றப்பட்டது"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS கோரிக்கையானது USSD கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS கோரிக்கையானது புதிய SS கோரிக்கைக்கு மாற்றப்பட்டது."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"பணி சுயவிவரம்"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"விரி பொத்தான்"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB பெரிபெரல் போர்ட்"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB பெரிபெரல் போர்ட்"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"பின்னை அகற்று"</string>
<string name="app_info" msgid="6856026610594615344">"பயன்பாட்டுத் தகவல்"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"அமர்வை மீண்டும் தொடங்கு"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"புதிய டெமோ அமர்வைத் தொடங்க, தட்டவும்"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"இந்தச் சாதனத்தைக் கட்டுப்பாடுகளின்றிப் பயன்படுத்த, ஆரம்ப நிலைக்கு மீட்டமைக்கவும்"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"மேலும் அறிய தொடவும்."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"முடக்கப்பட்டது: <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-te-rIN/strings.xml b/core/res/res/values-te-rIN/strings.xml
index 37ed0e5..65f135a 100644
--- a/core/res/res/values-te-rIN/strings.xml
+++ b/core/res/res/values-te-rIN/strings.xml
@@ -55,7 +55,7 @@
<string name="mmiComplete" msgid="8232527495411698359">"MMI పూర్తయింది."</string>
<string name="badPin" msgid="9015277645546710014">"మీరు టైప్ చేసిన పాత పిన్ చెల్లదు."</string>
<string name="badPuk" msgid="5487257647081132201">"మీరు టైప్ చేసిన PUK చెల్లదు."</string>
- <string name="mismatchPin" msgid="609379054496863419">"మీరు టైప్ చేసిన PINలు సరిపోలలేదు."</string>
+ <string name="mismatchPin" msgid="609379054496863419">"మీరు టైప్ చేసిన పిన్లు సరిపోలలేదు."</string>
<string name="invalidPin" msgid="3850018445187475377">"4 నుండి 8 సంఖ్యలు ఉండే పిన్ను టైప్ చేయండి."</string>
<string name="invalidPuk" msgid="8761456210898036513">"8 సంఖ్యలు లేదా అంతకంటే పొడవు ఉండే PUKని టైప్ చేయండి."</string>
<string name="needPuk" msgid="919668385956251611">"మీ సిమ్ కార్డు PUK-లాక్ చేయబడింది. దీన్ని అన్లాక్ చేయడానికి PUK కోడ్ను టైప్ చేయండి."</string>
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> సం.లో</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> సం.లో</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> నిమిషాల క్రితం</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> నిమిషం క్రితం</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> గంటల క్రితం</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> గంట క్రితం</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> రోజుల క్రితం</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> రోజు క్రితం</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> సంవత్సరాల క్రితం</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> సంవత్సరం క్రితం</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> నిమిషాల్లో</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> నిమిషంలో</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> గంటల్లో</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> గంటలో</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> రోజుల్లో</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> రోజులో</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> సంవత్సరాల్లో</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> సంవత్సరంలో</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"వీడియో సమస్య"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"ఈ పరికరంలో ప్రసారం చేయడానికి ఈ వీడియో చెల్లదు."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ఈ వీడియోను ప్లే చేయడం సాధ్యపడదు."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> ఆపివేయబడింది"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> పునరావృతంగా ఆపివేయబడుతోంది"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> పునరావృతంగా ఆపివేయబడుతోంది"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"అనువర్తనాన్ని పునఃప్రారంభించు"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"రీసెట్ చేసి, అనువర్తనాన్ని పునఃప్రారంభించు"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"అనువర్తనాన్ని మళ్లీ తెరువు"</string>
<string name="aerr_report" msgid="5371800241488400617">"అభిప్రాయాన్ని పంపు"</string>
<string name="aerr_close" msgid="2991640326563991340">"మూసివేయి"</string>
<string name="aerr_mute" msgid="1974781923723235953">"పరికరం పునఃప్రారంభమయ్యే వరకు మ్యూట్ చేయి"</string>
@@ -1495,7 +1526,7 @@
<string name="restr_pin_enter_new_pin" msgid="5959606691619959184">"కొత్త పిన్"</string>
<string name="restr_pin_confirm_pin" msgid="8501523829633146239">"కొత్త పిన్ను నిర్ధారించండి"</string>
<string name="restr_pin_create_pin" msgid="8017600000263450337">"నియంత్రణలను సవరించడానికి పిన్ను రూపొందించండి"</string>
- <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"PINలు సరిపోలలేదు. మళ్లీ ప్రయత్నించండి."</string>
+ <string name="restr_pin_error_doesnt_match" msgid="2224214190906994548">"పిన్లు సరిపోలలేదు. మళ్లీ ప్రయత్నించండి."</string>
<string name="restr_pin_error_too_short" msgid="8173982756265777792">"పిన్ చాలా చిన్నదిగా ఉంది. తప్పనిసరిగా కనీసం 4 అంకెలు ఉండాలి."</string>
<plurals name="restr_pin_countdown" formatted="false" msgid="9061246974881224688">
<item quantity="other"><xliff:g id="COUNT">%d</xliff:g> సెకన్లలో మళ్లీ ప్రయత్నించండి</item>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> తొలగించబడింది"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"కార్యాలయం <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"ఈ స్క్రీన్ని అన్పిన్ చేయడానికి, వెనుకకు తాకి & అలాగే పట్టుకోండి."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"ఈ స్క్రీన్ని అన్పిన్ చేయడానికి, స్థూల దృష్టిని తాకి & అలాగే పట్టుకోండి."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"అనువర్తనం పిన్ చేయబడింది: ఈ పరికరంలో అన్పిన్ చేయడానికి అనుమతి లేదు."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"స్క్రీన్ పిన్ చేయబడింది"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"స్క్రీన్ అన్పిన్ చేయబడింది"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS అభ్యర్థన USSD అభ్యర్థనగా సవరించబడింది."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS అభ్యర్థన కొత్త SS అభ్యర్థనగా సవరించబడింది."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"కార్యాలయ ప్రొఫైల్"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"విస్తరింపజేయి బటన్"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB పెరిఫెరల్ పోర్ట్"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB పెరిఫెరల్ పోర్ట్"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"అన్పిన్ చేయి"</string>
<string name="app_info" msgid="6856026610594615344">"అనువర్తన సమాచారం"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"సెషన్ను పునఃప్రారంభించండి"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"కొత్త డెమో సెషన్ను ప్రారంభించడానికి నొక్కండి"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"ఈ పరికరాన్ని ఎటువంటి పరిమితులు లేకుండా ఉపయోగించడానికి ఫ్యాక్టరీ రీసెట్ చేయండి"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"మరింత తెలుసుకోవడానికి తాకండి."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> నిలిపివేయబడింది"</string>
</resources>
diff --git a/core/res/res/values-th/strings.xml b/core/res/res/values-th/strings.xml
index 9d20655..73cbc73 100644
--- a/core/res/res/values-th/strings.xml
+++ b/core/res/res/values-th/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">ใน <xliff:g id="COUNT_1">%d</xliff:g> ปี</item>
<item quantity="one">ใน <xliff:g id="COUNT_0">%d</xliff:g> ปี</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> นาทีที่ผ่านมา</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> นาทีที่ผ่านมา</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ชั่วโมงที่ผ่านมา</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ชั่วโมงที่ผ่านมา</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> วันที่ผ่านมา</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> วันที่ผ่านมา</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ปีที่ผ่านมา</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ปีที่ผ่านมา</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">ใน <xliff:g id="COUNT_1">%d</xliff:g> นาที</item>
+ <item quantity="one">ใน <xliff:g id="COUNT_0">%d</xliff:g> นาที</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">ใน <xliff:g id="COUNT_1">%d</xliff:g> ชั่วโมง</item>
+ <item quantity="one">ใน <xliff:g id="COUNT_0">%d</xliff:g> ชั่วโมง</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">ใน <xliff:g id="COUNT_1">%d</xliff:g> วัน</item>
+ <item quantity="one">ใน <xliff:g id="COUNT_0">%d</xliff:g> วัน</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">ใน <xliff:g id="COUNT_1">%d</xliff:g> ปี</item>
+ <item quantity="one">ใน <xliff:g id="COUNT_0">%d</xliff:g> ปี</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"ปัญหาเกี่ยวกับวิดีโอ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"วิดีโอนี้ไม่สามารถสตรีมไปยังอุปกรณ์นี้"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"ไม่สามารถเล่นวิดีโอนี้"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> หยุดทำงาน"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> หยุดทำงานอยู่เรื่อยๆ"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> หยุดทำงานอยู่เรื่อยๆ"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"เปิดแอปใหม่"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"รีเซ็ตแอปและเปิดใหม่"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"เปิดแอปอีกครั้ง"</string>
<string name="aerr_report" msgid="5371800241488400617">"ส่งความคิดเห็น"</string>
<string name="aerr_close" msgid="2991640326563991340">"ปิด"</string>
<string name="aerr_mute" msgid="1974781923723235953">"ปิดการแจ้งเตือนจนกว่าอุปกรณ์จะรีสตาร์ท"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"ลบ <xliff:g id="KEY">%1$s</xliff:g> แล้ว"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g>ที่ทำงาน"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"หากต้องการเลิกตรึงหน้าจอนี้ แตะ \"กลับ\" ค้างไว้"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"หากต้องการเลิกตรึงหน้าจอนี้ แตะ \"ภาพรวม\" ค้างไว้"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"มีการตรึงแอป: ไม่อนุญาตให้เลิกตรึงบนอุปกรณ์นี้"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"ตรึงหน้าจอแล้ว"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"เลิกตรึงหน้าจอแล้ว"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"คำขอ SS ได้รับการแก้ไขให้เป็นคำขอ USSD"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"คำขอ SS ได้รับการแก้ไขให้เป็นคำขอ SS ใหม่"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"โปรไฟล์งาน"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"ปุ่มขยาย"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"อุปกรณ์สำหรับต่อพอร์ต USB ของ Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"อุปกรณ์สำหรับต่อพอร์ต USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"เลิกปักหมุด"</string>
<string name="app_info" msgid="6856026610594615344">"ข้อมูลแอป"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"เริ่มเซสชันอีกครั้ง"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"แตะเพื่อเริ่มเซสชันสาธิตใหม่"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"รีเซ็ตเป็นค่าเริ่มต้นเพื่อใช้อุปกรณ์นี้โดยไร้ข้อจำกัด"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"แตะเพื่อเรียนรู้เพิ่มเติม"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"ปิดใช้ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-tl/strings.xml b/core/res/res/values-tl/strings.xml
index 34cc2ce..405e05e 100644
--- a/core/res/res/values-tl/strings.xml
+++ b/core/res/res/values-tl/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one">sa loob ng <xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other">sa loob ng <xliff:g id="COUNT_1">%d</xliff:g>y</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> minuto na ang nakakalipas</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> na minuto na ang nakakalipas</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> oras na ang nakakalipas</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> na oras na ang nakakalipas</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> araw na ang nakakalipas</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> na araw na ang nakakalipas</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> taon na ang nakakalipas</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> na taon na ang nakakalipas</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">pagkalipas ng <xliff:g id="COUNT_1">%d</xliff:g> minuto</item>
+ <item quantity="other">pagkalipas ng <xliff:g id="COUNT_1">%d</xliff:g> na minuto</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">pagkalipas ng <xliff:g id="COUNT_1">%d</xliff:g> oras</item>
+ <item quantity="other">pagkalipas ng <xliff:g id="COUNT_1">%d</xliff:g> na oras</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">pagkalipas ng <xliff:g id="COUNT_1">%d</xliff:g> araw</item>
+ <item quantity="other">pagkalipas ng <xliff:g id="COUNT_1">%d</xliff:g> na araw</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">pagkalipas ng <xliff:g id="COUNT_1">%d</xliff:g> taon</item>
+ <item quantity="other">pagkalipas ng <xliff:g id="COUNT_1">%d</xliff:g> na taon</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Problema sa video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Hindi wasto ang video na ito para sa streaming sa device na ito."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Hindi ma-play ang video na ito."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Huminto ang <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"Paulit-ulit na humihinto ang <xliff:g id="APPLICATION">%1$s</xliff:g>"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Paulit-ulit na humihinto ang <xliff:g id="PROCESS">%1$s</xliff:g>"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"I-restart ang app"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"I-reset at i-restart ang app"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Buksang muli ang app"</string>
<string name="aerr_report" msgid="5371800241488400617">"Magpadala ng feedback"</string>
<string name="aerr_close" msgid="2991640326563991340">"Isara"</string>
<string name="aerr_mute" msgid="1974781923723235953">"I-mute hanggang sa mag-restart ang device"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Tinanggal ang <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> sa Trabaho"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Upang i-unpin ang screen na ito, pindutin nang matagal ang Bumalik."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Upang i-unpin ang screen na ito, pindutin nang matagal ang Pangkalahatang-ideya."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Naka-pin ang app: Hindi pinapayagan ang pag-a-unpin sa device na ito."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Naka-pin ang screen"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Naka-unpin ang screen"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Ginawang USSD request ang SS request."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Ginawang bagong SS request ang SS request."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Profile sa trabaho"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Button na Palawakin"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Peripheral Port"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Peripheral Port"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"I-unpin"</string>
<string name="app_info" msgid="6856026610594615344">"Impormasyon ng app"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"I-restart ang Session"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"I-tap upang magsimula ng bagong session ng demo"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"I-factory reset upang magamit ang device na ito nang walang mga paghihigpit"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Pindutin upang matuto nang higit pa."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Na-disable ang <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-tr/strings.xml b/core/res/res/values-tr/strings.xml
index 112cdc9..ac55821 100644
--- a/core/res/res/values-tr/strings.xml
+++ b/core/res/res/values-tr/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> y içinde</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> y içinde</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dakika önce</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> dakika önce</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> saat önce</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> saat önce</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> gün önce</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> gün önce</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> yıl önce</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> yıl önce</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> dakika içinde</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> dakika içinde</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> saat içinde</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> saat içinde</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> gün içinde</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> gün içinde</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> yıl içinde</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> yıl içinde</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Video sorunu"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Bu video bu cihazda akış için uygun değil."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Bu video oynatılamıyor."</string>
@@ -962,8 +994,8 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> durdu"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> sürekli olarak duruyor"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> sürekli olarak duruyor"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Uygulamayı yeniden başlat"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Uygulamayı sıfırla ve yeniden başlat"</string>
+ <!-- no translation found for aerr_restart (7581308074153624475) -->
+ <skip />
<string name="aerr_report" msgid="5371800241488400617">"Geri bildirim gönder"</string>
<string name="aerr_close" msgid="2991640326563991340">"Kapat"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Cihaz yeniden başlatılana kadar bir daha gösterme"</string>
@@ -1512,7 +1544,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> silindi"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> (İş)"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Bu ekranın sabitlemesini kaldırmak için Geri\'ye dokunup basılı tutun."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Bu ekranın sabitlemesini kaldırmak için Genel Bakış\'a dokunup basılı tutun."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Uygulama sabitlendi. Bu cihazda sabitlemenin kaldırılmasına izin verilmiyor."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran sabitlendi"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran sabitlemesi kaldırıldı"</string>
@@ -1579,6 +1610,10 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS isteği USSD isteği olarak değiştirildi."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS isteği yeni SS isteği olarak değiştirildi."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"İş profili"</string>
+ <!-- no translation found for expand_button_content_description (5855955413376384681) -->
+ <skip />
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB Çevre Birimi Bağlantı Noktası"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB Çevre Birimi Bağlantı Noktası"</string>
@@ -1616,8 +1651,11 @@
<string name="unpin_target" msgid="3556545602439143442">"Sabitlemeyi kaldır"</string>
<string name="app_info" msgid="6856026610594615344">"Uygulama bilgileri"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <!-- no translation found for reset_retail_demo_mode_title (2187220736280147886) -->
+ <skip />
+ <!-- no translation found for reset_retail_demo_mode_text (5687062656885515019) -->
+ <skip />
<string name="audit_safemode_notification" msgid="6416076898350685856">"Bu cihazı kısıtlama olmadan kullanmak için fabrika ayarlarına sıfırlayın"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Daha fazla bilgi edinmek için dokunun."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> devre dışı"</string>
</resources>
diff --git a/core/res/res/values-uk/strings.xml b/core/res/res/values-uk/strings.xml
index 4a3c3ff..5406729 100644
--- a/core/res/res/values-uk/strings.xml
+++ b/core/res/res/values-uk/strings.xml
@@ -921,6 +921,54 @@
<item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> років</item>
<item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> року</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> хвилину тому</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> хвилини тому</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> хвилин тому</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> хвилини тому</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> годину тому</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> години тому</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> годин тому</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> години тому</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> день тому</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> дні тому</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> днів тому</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> дня тому</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> рік тому</item>
+ <item quantity="few"><xliff:g id="COUNT_1">%d</xliff:g> роки тому</item>
+ <item quantity="many"><xliff:g id="COUNT_1">%d</xliff:g> років тому</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> року тому</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">через <xliff:g id="COUNT_1">%d</xliff:g> хвилину</item>
+ <item quantity="few">через <xliff:g id="COUNT_1">%d</xliff:g> хвилини</item>
+ <item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> хвилин</item>
+ <item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> хвилини</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">через <xliff:g id="COUNT_1">%d</xliff:g> годину</item>
+ <item quantity="few">через <xliff:g id="COUNT_1">%d</xliff:g> години</item>
+ <item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> годин</item>
+ <item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> години</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">через <xliff:g id="COUNT_1">%d</xliff:g> день</item>
+ <item quantity="few">через <xliff:g id="COUNT_1">%d</xliff:g> дні</item>
+ <item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> днів</item>
+ <item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> дня</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">через <xliff:g id="COUNT_1">%d</xliff:g> рік</item>
+ <item quantity="few">через <xliff:g id="COUNT_1">%d</xliff:g> роки</item>
+ <item quantity="many">через <xliff:g id="COUNT_1">%d</xliff:g> років</item>
+ <item quantity="other">через <xliff:g id="COUNT_1">%d</xliff:g> року</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Проблема з відео"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Відео не придатне для потокового передавання в цей пристрій."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Неможливо відтворити це відео."</string>
@@ -992,8 +1040,7 @@
<string name="aerr_process" msgid="6201597323218674729">"Процес <xliff:g id="PROCESS">%1$s</xliff:g> перестав працювати"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"Додаток <xliff:g id="APPLICATION">%1$s</xliff:g> періодично перестає працювати"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"Процес \"<xliff:g id="PROCESS">%1$s</xliff:g>\" періодично перестає працювати"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Перезапустити додаток"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Скинути та перезапустити додаток"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Відкрити додаток знову"</string>
<string name="aerr_report" msgid="5371800241488400617">"Надіслати відгук"</string>
<string name="aerr_close" msgid="2991640326563991340">"Закрити"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Вимкнути звук до перезавантаження пристрою"</string>
@@ -1550,7 +1597,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> видалено"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Робоча <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Щоб відкріпити цей екран, натисніть і утримуйте кнопку \"Назад\"."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Щоб відкріпити цей екран, натисніть і утримуйте кнопку \"Огляд\"."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Додаток закріплено. Його не можна відкріпити на цьому пристрої."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Екран закріплено"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Екран відкріплено"</string>
@@ -1633,6 +1679,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Запит SS перетворено на запит USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Запит SS перетворено на новий запит SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Робочий профіль"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Кнопка \"Розгорнути\""</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Периферійний USB-порт Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Периферійний USB-порт"</string>
@@ -1672,8 +1721,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Відкріпити"</string>
<string name="app_info" msgid="6856026610594615344">"Про додаток"</string>
<string name="negative_duration" msgid="5688706061127375131">"-<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Новий сеанс"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Торкніться, щоб почати новий демо-сеанс"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Відновіть заводські параметри, щоб використовувати пристрій без обмежень"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Торкніться, щоб дізнатися більше."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> вимкнено"</string>
</resources>
diff --git a/core/res/res/values-ur-rPK/strings.xml b/core/res/res/values-ur-rPK/strings.xml
index 03e961a..79b5107 100644
--- a/core/res/res/values-ur-rPK/strings.xml
+++ b/core/res/res/values-ur-rPK/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> سال میں</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> سال میں</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> منٹ قبل</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> منٹ قبل</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> گھنٹے قبل</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> گھنٹہ قبل</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> دن قبل</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> دن قبل</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> سال قبل</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> سال قبل</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> منٹ میں</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> منٹ میں</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> گھنٹے میں</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> گھنٹہ میں</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> دن میں</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> دن میں</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> سال میں</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> سال میں</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"ویڈیو مسئلہ"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"یہ ویڈیو اس آلہ پر سلسلہ بندی کیلئے درست نہیں ہے۔"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"یہ ویڈیو نہیں چل سکتا۔"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> بند ہو گیا ہے"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> بار بار بند ہوتی ہے"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> بار بار بند ہوتی ہے"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"ایپ دوبارہ شروع کریں"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"ایپ کو دوبارہ ترتیب دیں اور دوبارہ شروع کریں"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"ایپ دوبارہ کھولیں"</string>
<string name="aerr_report" msgid="5371800241488400617">"تاثرات بھیجیں"</string>
<string name="aerr_close" msgid="2991640326563991340">"بند کریں"</string>
<string name="aerr_mute" msgid="1974781923723235953">"آلہ دوبارہ اسٹارٹ ہونے تک خاموش رکھیں"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> کو حذف کر دیا گیا"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"دفتر <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"اس اسکرین سے پن ہٹانے کیلئے، پیچھے کو تھپتھپائیں اور دبا کر رکھیں۔"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"اس اسکرین سے پن ہٹانے کیلئے، مجموعی جائزہ کو تھپتھپائیں اور دبا کر رکھیں۔"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"ایپ کو پن کر دیا گیا ہے: اس آلہ پر پن ہٹانے کی اجازت نہیں ہے۔"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"اسکرین کو پن کر دیا گیا"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"اسکرین کا پن ہٹا دیا گیا"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS درخواست میں ترمیم کر کے USSD درخواست بنا دی گئی ہے۔"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS درخواست میں ترمیم کر کے نئی SS درخواست بنا دی گئی ہے۔"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"دفتری پروفائل"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"پھیلائیں بٹن"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB پیرفرل پورٹ"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB پیرفرل پورٹ"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"پن ہٹائیں"</string>
<string name="app_info" msgid="6856026610594615344">"ایپ کی معلومات"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"سیشن دوبارہ شروع کریں"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"نیا ڈیمو سیشن شروع کرنے کیلئے تھپتھپائیں"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"بغیر کسی حدود کے استعمال کرنے کیلئے اس آلے کو فیکٹری ری سیٹ کریں"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"مزید جاننے کیلئے ٹچ کریں۔"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"غیر فعال کردہ <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-uz-rUZ/strings.xml b/core/res/res/values-uz-rUZ/strings.xml
index 3da5c9d..2d0af55 100644
--- a/core/res/res/values-uz-rUZ/strings.xml
+++ b/core/res/res/values-uz-rUZ/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> yildan keyin</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> yildan keyin</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> daqiqa oldin</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> daqiqa oldin</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> soat oldin</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> soat oldin</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> kun oldin</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> kun oldin</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> yil oldin</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> yil oldin</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> daqiqadan keyin</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> daqiqadan keyin</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> soatdan keyin</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> soatdan keyin</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> kundan keyin</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> kundan keyin</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> yildan keyin</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> yildan keyin</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Video muammosi"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Ushbu videoni mazkur qurilmada oqimli rejimda ijro etib bo‘lmaydi."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Ushbu videoni ijro etib bo‘lmadi."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> jarayoni ishdan chiqdi"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> yana ishdan chiqdi"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> yana ishdan chiqdi"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Ilovani qayta ishga tushirish"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Ilovani qayta tiklash va qayta ishga tushirish"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Ilovani qayta ochish"</string>
<string name="aerr_report" msgid="5371800241488400617">"Fikr-mulohaza yuborish"</string>
<string name="aerr_close" msgid="2991640326563991340">"Yopish"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Qurilma o‘chib yonguncha e’tiborsiz qoldirish"</string>
@@ -1168,7 +1199,7 @@
<string name="ime_action_go" msgid="8320845651737369027">"O‘tish"</string>
<string name="ime_action_search" msgid="658110271822807811">"Qidirish"</string>
<string name="ime_action_send" msgid="2316166556349314424">"Yuborish"</string>
- <string name="ime_action_next" msgid="3138843904009813834">"Keyingi"</string>
+ <string name="ime_action_next" msgid="3138843904009813834">"Keyingisi"</string>
<string name="ime_action_done" msgid="8971516117910934605">"Tayyor"</string>
<string name="ime_action_previous" msgid="1443550039250105948">"Old."</string>
<string name="ime_action_default" msgid="2840921885558045721">"Bajarish"</string>
@@ -1211,7 +1242,7 @@
<string name="tethered_notification_title" msgid="3146694234398202601">"Modem rejimi yoniq"</string>
<string name="tethered_notification_message" msgid="2113628520792055377">"Sozlash uchun bosing."</string>
<string name="back_button_label" msgid="2300470004503343439">"Orqaga"</string>
- <string name="next_button_label" msgid="1080555104677992408">"Keyingi"</string>
+ <string name="next_button_label" msgid="1080555104677992408">"Keyingisi"</string>
<string name="skip_button_label" msgid="1275362299471631819">"Tashlab o‘tish"</string>
<string name="no_matches" msgid="8129421908915840737">"Topilmadi"</string>
<string name="find_on_page" msgid="1946799233822820384">"Sahifadan topish"</string>
@@ -1515,7 +1546,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> raqami o‘chirib tashlandi"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Ish <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Bu ekrandan chiqish uchun “Orqaga” tugmasini bosib turing."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Bu ekrandan chiqish uchun “Umumiy ma’lumot” tugmasini bosib turing."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Ilova qadab qo‘yilgan. Uni ekrandan yechish ushbu qurilmada ta’qiqlangan."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Ekran qadab qo‘yildi"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Ekran bo‘shatildi"</string>
@@ -1582,6 +1612,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS so‘rovi USSD so‘roviga o‘zgartirildi."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS so‘rovi yangi SS so‘roviga o‘zgartirildi."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Ishchi profil"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Yoyish tugmasi"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android tashqi USB porti"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Tashqi USB porti"</string>
@@ -1619,8 +1652,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Olib tashlash"</string>
<string name="app_info" msgid="6856026610594615344">"Ilova haqida"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Yangi seans"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Yangi demo-seans boshlash uchun bosing"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Bu qurilmadan cheklovlarsiz foydalanish uchun zavod sozlamalarini tiklang"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Ko‘proq o‘rganish uchun bosing."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"<xliff:g id="LABEL">%1$s</xliff:g> vidjeti o‘chirilgan"</string>
</resources>
diff --git a/core/res/res/values-vi/strings.xml b/core/res/res/values-vi/strings.xml
index cb315d9..9d3fe5d 100644
--- a/core/res/res/values-vi/strings.xml
+++ b/core/res/res/values-vi/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other">trong <xliff:g id="COUNT_1">%d</xliff:g> năm</item>
<item quantity="one">trong <xliff:g id="COUNT_0">%d</xliff:g> năm</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> phút trước</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> phút trước</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> giờ trước</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> giờ trước</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> ngày trước</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> ngày trước</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> năm trước</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> năm trước</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other">sau <xliff:g id="COUNT_1">%d</xliff:g> phút</item>
+ <item quantity="one">sau <xliff:g id="COUNT_0">%d</xliff:g> phút</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other">sau <xliff:g id="COUNT_1">%d</xliff:g> giờ</item>
+ <item quantity="one">sau <xliff:g id="COUNT_0">%d</xliff:g> giờ</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other">sau <xliff:g id="COUNT_1">%d</xliff:g> ngày</item>
+ <item quantity="one">sau <xliff:g id="COUNT_0">%d</xliff:g> ngày</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other">sau <xliff:g id="COUNT_1">%d</xliff:g> năm</item>
+ <item quantity="one">sau <xliff:g id="COUNT_0">%d</xliff:g> năm</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Sự cố video"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Video này không hợp lệ để phát trực tuyến đến thiết bị này."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Không thể phát video này."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g> đã dừng"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g> tiếp tục dừng"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g> tiếp tục dừng"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Khởi động lại ứng dụng"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Đặt lại và khởi động lại ứng dụng"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Mở lại ứng dụng"</string>
<string name="aerr_report" msgid="5371800241488400617">"Gửi phản hồi"</string>
<string name="aerr_close" msgid="2991640326563991340">"Đóng"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Tắt tiếng cho đến khi thiết bị khởi động lại"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"Đã xóa <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"<xliff:g id="LABEL">%1$s</xliff:g> làm việc"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Để bỏ ghim màn hình này, nhấn và giữ Quay lại."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Để bỏ ghim màn hình này, chạm và giữ Tổng quan."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Ứng dụng được ghim: Không được phép bỏ ghim trên thiết bị này."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Đã ghim màn hình"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Đã bỏ ghim màn hình"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Yêu cầu SS được sửa đổi thành yêu cầu USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Yêu cầu SS được sửa đổi thành yêu cầu SS mới."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Hồ sơ công việc"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Nút mở rộng"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Cổng ngoại vi USB Android"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Cổng ngoại vi USB"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Bỏ ghim"</string>
<string name="app_info" msgid="6856026610594615344">"Thông tin ứng dụng"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Khởi động lại phiên"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Nhấn để bắt đầu phiên trình diễn mới"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Khôi phục cài đặt gốc để sử dụng thiết bị này mà không bị hạn chế"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Chạm để tìm hiểu thêm."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"Đã tắt <xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-zh-rCN/strings.xml b/core/res/res/values-zh-rCN/strings.xml
index 505d5a0..82f737c 100644
--- a/core/res/res/values-zh-rCN/strings.xml
+++ b/core/res/res/values-zh-rCN/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年后</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年后</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 分钟前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 分钟前</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 小时前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 小时前</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 天前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 天前</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年前</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 分钟后</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 分钟后</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 小时后</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 小时后</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 天后</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 天后</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年后</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年后</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"视频问题"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"抱歉,该视频不适合在此设备上播放。"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"无法播放此视频。"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"<xliff:g id="PROCESS">%1$s</xliff:g>已停止运行"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"<xliff:g id="APPLICATION">%1$s</xliff:g>屡次停止运行"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"<xliff:g id="PROCESS">%1$s</xliff:g>屡次停止运行"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"重启应用"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"重置并重启应用"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"重新打开应用"</string>
<string name="aerr_report" msgid="5371800241488400617">"发送反馈"</string>
<string name="aerr_close" msgid="2991640326563991340">"关闭"</string>
<string name="aerr_mute" msgid="1974781923723235953">"忽略(直到设备重启)"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"已删除<xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"工作<xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"要取消固定此屏幕,请触摸并按住“返回”按钮。"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"要取消固定此屏幕,请触摸并按住“概览”按钮。"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"应用处于固定状态:在此设备上不允许退出该模式。"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"已固定屏幕"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"已取消固定屏幕"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS 请求已修改为 USSD 请求。"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS 请求已修改为新的 SS 请求。"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"工作资料"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"展开按钮"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB 外设端口"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB 外设端口"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"取消固定"</string>
<string name="app_info" msgid="6856026610594615344">"应用信息"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"重新启动会话"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"点按即可启动新的演示会话"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"恢复出厂设置即可正常使用此设备,不受任何限制"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"触摸即可了解详情。"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"已停用的<xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-zh-rHK/strings.xml b/core/res/res/values-zh-rHK/strings.xml
index 33ab32e..692501a 100644
--- a/core/res/res/values-zh-rHK/strings.xml
+++ b/core/res/res/values-zh-rHK/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年後</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年後</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 分鐘前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 分鐘前</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 小時前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 小時前</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 天前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 天前</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年前</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 分鐘後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 分鐘後</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 小時後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 小時後</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 天後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 天後</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年後</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"影片問題"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"這部影片的格式無效,無法以串流傳送至這部裝置。"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"無法播放這部影片。"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"「<xliff:g id="PROCESS">%1$s</xliff:g>」已經停止運作"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"「<xliff:g id="APPLICATION">%1$s</xliff:g>」不斷停止運作"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"「<xliff:g id="PROCESS">%1$s</xliff:g>」不斷停止運作"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"重新啟動應用程式"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"重設並重新啟動應用程式"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"再次開啟應用程式"</string>
<string name="aerr_report" msgid="5371800241488400617">"傳送意見反映"</string>
<string name="aerr_close" msgid="2991640326563991340">"關閉"</string>
<string name="aerr_mute" msgid="1974781923723235953">"忽略直至裝置重新啟動"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"<xliff:g id="KEY">%1$s</xliff:g> 已刪除"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"公司<xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"如要取消固定這個畫面,請按住 [返回]。"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"如要取消固定這個畫面,請按住 [概覽]。"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"應用程式已固定:不允許在此裝置上取消固定。"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"螢幕已固定"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"已取消固定螢幕"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS 要求已修改為 USSD 要求。"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS 要求已修改為新的 SS 要求。"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"工作設定檔"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"展開按鈕"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB 外端連接埠"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB 外端連接埠"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"取消固定"</string>
<string name="app_info" msgid="6856026610594615344">"應用程式資料"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"重新開始時段"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"輕按即可開始新示範時段"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"將此裝置回復至原廠設定後,使用將不受限制"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"輕觸以瞭解詳情。"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"「<xliff:g id="LABEL">%1$s</xliff:g>」已停用"</string>
</resources>
diff --git a/core/res/res/values-zh-rTW/strings.xml b/core/res/res/values-zh-rTW/strings.xml
index c6211cd..3c4d4bd 100644
--- a/core/res/res/values-zh-rTW/strings.xml
+++ b/core/res/res/values-zh-rTW/strings.xml
@@ -891,6 +891,38 @@
<item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年內</item>
<item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年內</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 分鐘前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 分鐘前</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 小時前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 小時前</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 天前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 天前</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年前</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年前</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 分鐘後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 分鐘後</item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 小時後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 小時後</item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 天後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 天後</item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> 年後</item>
+ <item quantity="one"><xliff:g id="COUNT_0">%d</xliff:g> 年後</item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"影片發生問題"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"這部影片的格式無效,因此無法在此裝置中串流播放。"</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"無法播放這部影片。"</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"「<xliff:g id="PROCESS">%1$s</xliff:g>」已停止運作"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"「<xliff:g id="APPLICATION">%1$s</xliff:g>」屢次停止運作"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"「<xliff:g id="PROCESS">%1$s</xliff:g>」屢次停止運作"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"重新啟動應用程式"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"重設並重新啟動應用程式"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"再次開啟應用程式"</string>
<string name="aerr_report" msgid="5371800241488400617">"提供意見"</string>
<string name="aerr_close" msgid="2991640326563991340">"關閉"</string>
<string name="aerr_mute" msgid="1974781923723235953">"略過直到裝置重新啟動"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"已刪除 <xliff:g id="KEY">%1$s</xliff:g>"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"公司<xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"如要取消固定這個畫面,請按住「返回」按鈕。"</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"如要取消固定這個畫面,請按住「總覽」按鈕。"</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"應用程式已固定:無法在這部裝置取消固定。"</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"已固定螢幕"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"已取消固定螢幕"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"SS 要求已改為 USSD 要求。"</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"SS 要求已改為新的 SS 要求。"</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Work 設定檔"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"展開按鈕"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Android USB 週邊連接埠"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"USB 週邊連接埠"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"取消固定"</string>
<string name="app_info" msgid="6856026610594615344">"應用程式資訊"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"重新啟動工作階段"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"輕觸即可啟動新的示範工作階段"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"恢復原廠設定即可正常使用這個裝置"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"輕觸即可瞭解詳情。"</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"已停用的<xliff:g id="LABEL">%1$s</xliff:g>"</string>
</resources>
diff --git a/core/res/res/values-zu/strings.xml b/core/res/res/values-zu/strings.xml
index f0e7f2b..edc9d72 100644
--- a/core/res/res/values-zu/strings.xml
+++ b/core/res/res/values-zu/strings.xml
@@ -891,6 +891,38 @@
<item quantity="one">ku-<xliff:g id="COUNT_1">%d</xliff:g>y</item>
<item quantity="other">ku-<xliff:g id="COUNT_1">%d</xliff:g>y</item>
</plurals>
+ <plurals name="duration_minutes_relative" formatted="false" msgid="3178131706192980192">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> amaminithi adlule</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> amaminithi adlule</item>
+ </plurals>
+ <plurals name="duration_hours_relative" formatted="false" msgid="676894109982008411">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> amahora adlule</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> amahora adlule</item>
+ </plurals>
+ <plurals name="duration_days_relative" formatted="false" msgid="2203515825765397130">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> izinsuku ezidlule</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> izinsuku ezidlule</item>
+ </plurals>
+ <plurals name="duration_years_relative" formatted="false" msgid="4820062134188885734">
+ <item quantity="one"><xliff:g id="COUNT_1">%d</xliff:g> iminyaka eyedlule</item>
+ <item quantity="other"><xliff:g id="COUNT_1">%d</xliff:g> iminyaka eyedlule</item>
+ </plurals>
+ <plurals name="duration_minutes_relative_future" formatted="false" msgid="4655043589817680966">
+ <item quantity="one">kumaminithi angu-<xliff:g id="COUNT_1">%d</xliff:g></item>
+ <item quantity="other">kumaminithi angu-<xliff:g id="COUNT_1">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_hours_relative_future" formatted="false" msgid="8084579714205223891">
+ <item quantity="one">emahoreni angu-<xliff:g id="COUNT_1">%d</xliff:g></item>
+ <item quantity="other">emahoreni angu-<xliff:g id="COUNT_1">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_days_relative_future" formatted="false" msgid="333215369363433992">
+ <item quantity="one">ezinsukwini ezingu-<xliff:g id="COUNT_1">%d</xliff:g></item>
+ <item quantity="other">ezinsukwini ezingu-<xliff:g id="COUNT_1">%d</xliff:g></item>
+ </plurals>
+ <plurals name="duration_years_relative_future" formatted="false" msgid="8644862986413104011">
+ <item quantity="one">eminyakeni engu-<xliff:g id="COUNT_1">%d</xliff:g></item>
+ <item quantity="other">eminyakeni engu-<xliff:g id="COUNT_1">%d</xliff:g></item>
+ </plurals>
<string name="VideoView_error_title" msgid="3534509135438353077">"Inkinga yevidiyo"</string>
<string name="VideoView_error_text_invalid_progressive_playback" msgid="3186670335938670444">"Uxolo, le vidiyo ayilungele ukusakaza bukhomo kwale divaysi."</string>
<string name="VideoView_error_text_unknown" msgid="3450439155187810085">"Iyehluleka ukudlala levidiyo."</string>
@@ -962,8 +994,7 @@
<string name="aerr_process" msgid="6201597323218674729">"I-<xliff:g id="PROCESS">%1$s</xliff:g> imile"</string>
<string name="aerr_application_repeated" msgid="3146328699537439573">"I-<xliff:g id="APPLICATION">%1$s</xliff:g> ilokhu iyama"</string>
<string name="aerr_process_repeated" msgid="6235302956890402259">"I-<xliff:g id="PROCESS">%1$s</xliff:g> ilokhu iyama"</string>
- <string name="aerr_restart" msgid="9001379185665886595">"Qala kabusha uhlelo lokusebenza"</string>
- <string name="aerr_reset" msgid="7645427603514220451">"Setha kabusha uphinde uqalise kabusha uhlelo lokusebenza"</string>
+ <string name="aerr_restart" msgid="7581308074153624475">"Vula uhlelo lokusebenza futhi"</string>
<string name="aerr_report" msgid="5371800241488400617">"Thumela impendulo"</string>
<string name="aerr_close" msgid="2991640326563991340">"Vala"</string>
<string name="aerr_mute" msgid="1974781923723235953">"Thulisa ize iqalise kabusha idivayisi"</string>
@@ -1512,7 +1543,6 @@
<string name="deleted_key" msgid="7659477886625566590">"I-<xliff:g id="KEY">%1$s</xliff:g> isusiwe"</string>
<string name="managed_profile_label_badge" msgid="2355652472854327647">"Umsebenzi <xliff:g id="LABEL">%1$s</xliff:g>"</string>
<string name="lock_to_app_toast" msgid="1420543809500606964">"Ukuze ususe ukuphina lesi sikrini, thinta futhi ubambe okuthi Emuva."</string>
- <string name="lock_to_app_toast_accessible" msgid="2302154926850846096">"Ukuze ususe ukuphina lesi sikrini, thinta futhi ubambe okuthi Buka konke."</string>
<string name="lock_to_app_toast_locked" msgid="9125176335701699164">"Uhlelo lokusebenza luphiniwe: Ukususa ukuphina akuvunyelwe kule divayisi."</string>
<string name="lock_to_app_start" msgid="6643342070839862795">"Isikrini siphiniwe"</string>
<string name="lock_to_app_exit" msgid="8598219838213787430">"Isikrini sisuswe ukuphina"</string>
@@ -1579,6 +1609,9 @@
<string name="stk_cc_ss_to_ussd" msgid="3951862188105305589">"Isicelo se-SS siguqulelwe kusicelo se-USSD."</string>
<string name="stk_cc_ss_to_ss" msgid="5470768854991452695">"Isicelo se-SS siguqulelwe kusicelo esisha se-SS."</string>
<string name="notification_work_profile_content_description" msgid="4600554564103770764">"Iphrofayela yomsebenzi"</string>
+ <string name="expand_button_content_description" msgid="5855955413376384681">"Inkinobho yokunweba"</string>
+ <!-- no translation found for expand_action_accessibility (5307730695723718254) -->
+ <skip />
<string name="usb_midi_peripheral_name" msgid="7221113987741003817">"Imbobo ye-Android USB Peripheral"</string>
<string name="usb_midi_peripheral_manufacturer_name" msgid="7176526170008970168">"I-Android"</string>
<string name="usb_midi_peripheral_product_name" msgid="4971827859165280403">"Imbobo ye-USB Peripheral"</string>
@@ -1616,8 +1649,9 @@
<string name="unpin_target" msgid="3556545602439143442">"Susa ukuphina"</string>
<string name="app_info" msgid="6856026610594615344">"Ulwazi lohlelo lokusebenza"</string>
<string name="negative_duration" msgid="5688706061127375131">"−<xliff:g id="TIME">%1$s</xliff:g>"</string>
+ <string name="reset_retail_demo_mode_title" msgid="2187220736280147886">"Qalisa kabusha isikhathi"</string>
+ <string name="reset_retail_demo_mode_text" msgid="5687062656885515019">"Thepha ukuze uqale isikhathi esisha sedemo"</string>
<string name="audit_safemode_notification" msgid="6416076898350685856">"Setha kabusha ukuze usebenzise idivayisi ngaphandle kwemikhawulo"</string>
<string name="audit_safemode_notification_details" msgid="1860601176690176413">"Thinta ukuze ufunde kabanzi."</string>
- <!-- no translation found for suspended_widget_accessibility (6712143096475264190) -->
- <skip />
+ <string name="suspended_widget_accessibility" msgid="6712143096475264190">"I-<xliff:g id="LABEL">%1$s</xliff:g> ekhutshaziwe"</string>
</resources>
diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml
index 88c5629..60b0ef2 100644
--- a/core/res/res/values/attrs.xml
+++ b/core/res/res/values/attrs.xml
@@ -8248,10 +8248,9 @@
<declare-styleable name="Shortcut">
<attr name="shortcutId" format="string" />
<attr name="enabled" />
- <attr name="shortcutRank" format="integer" />
<attr name="shortcutIcon" format="reference" />
- <attr name="shortcutTitle" format="reference" />
- <attr name="shortcutText" format="reference" />
+ <attr name="shortcutShortLabel" format="reference" />
+ <attr name="shortcutLongLabel" format="reference" />
<attr name="shortcutDisabledMessage" format="reference" />
<attr name="shortcutCategories" format="string" />
<attr name="shortcutIntentAction" format="string" />
diff --git a/core/res/res/values/attrs_manifest.xml b/core/res/res/values/attrs_manifest.xml
index d69d73d..0872ef9 100644
--- a/core/res/res/values/attrs_manifest.xml
+++ b/core/res/res/values/attrs_manifest.xml
@@ -62,6 +62,20 @@
a reference to a Drawable resource containing the image definition. -->
<attr name="icon" format="reference" />
+ <!-- A Drawable resource providing a graphical representation of its
+ associated item. Use with the
+ application tag (to supply a default round icon for all application
+ components), or with the activity, receiver, service, or instrumentation
+ tag (to supply a specific round icon for that component). It may also be
+ used with the intent-filter tag to supply a round icon to show to the
+ user when an activity is being selected based on a particular Intent.
+
+ <p>The given round icon will be used to display to the user a graphical
+ representation of its associated component; for example, as the round icon
+ for main activity that is displayed in the launcher. This must be
+ a reference to a Drawable resource containing the image definition. -->
+ <attr name="roundIcon" format="reference" />
+
<!-- A Drawable resource providing an extended graphical banner for its
associated item. Use with the application tag (to supply a default
banner for all application activities), or with the activity, tag to
@@ -1236,6 +1250,7 @@
<attr name="theme" />
<attr name="label" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="description" />
@@ -1335,6 +1350,7 @@
<attr name="name" />
<attr name="label" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="permissionGroup" />
@@ -1362,6 +1378,7 @@
<attr name="name" />
<attr name="label" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="description" />
@@ -1395,6 +1412,7 @@
<attr name="name" />
<attr name="label" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
</declare-styleable>
@@ -1676,6 +1694,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="process" />
@@ -1759,6 +1778,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="permission" />
@@ -1807,6 +1827,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="permission" />
@@ -1843,6 +1864,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="launchMode" />
@@ -1926,6 +1948,7 @@
<attr name="label" />
<attr name="description" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="permission" />
@@ -1998,6 +2021,7 @@
parent="AndroidManifestActivity AndroidManifestReceiver AndroidManifestService">
<attr name="label" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="priority" />
@@ -2128,6 +2152,7 @@
<attr name="targetPackage" />
<attr name="label" />
<attr name="icon" />
+ <attr name="roundIcon" />
<attr name="banner" />
<attr name="logo" />
<attr name="handleProfiling" />
diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml
index 421bc2a..f1e2e26 100644
--- a/core/res/res/values/public.xml
+++ b/core/res/res/values/public.xml
@@ -2739,12 +2739,12 @@
=============================================================== -->
<eat-comment />
<public type="attr" name="shortcutId" />
- <public type="attr" name="shortcutRank" />
<public type="attr" name="shortcutIcon" />
- <public type="attr" name="shortcutTitle" />
- <public type="attr" name="shortcutText" />
+ <public type="attr" name="shortcutShortLabel" />
+ <public type="attr" name="shortcutLongLabel" />
<public type="attr" name="shortcutDisabledMessage" />
<public type="attr" name="shortcutCategories" />
<public type="attr" name="shortcutIntentAction" />
<public type="attr" name="shortcutIntentData" />
+ <public type="attr" name="roundIcon" />
</resources>
diff --git a/core/res/res/values/strings.xml b/core/res/res/values/strings.xml
index 3b3fc43..5db562d 100644
--- a/core/res/res/values/strings.xml
+++ b/core/res/res/values/strings.xml
@@ -4289,6 +4289,10 @@
DO NOT TRANSLATE -->
<string name="notification_inbox_ellipsis">\u2026</string>
+ <!-- Tempalate for Notification.MessagingStyle to join a conversation name with the name of the sender of a message, to make a notification title [CHAR LIMIT=NONE] -->
+ <string name="notification_messaging_title_template"><xliff:g id="conversation_title" example="Tasty Treat Team">%1$s</xliff:g>: <xliff:g id="sender_name" example="Adrian Baker">%2$s</xliff:g></string>
+
+
<!-- Label describing the number of selected items [CHAR LIMIT=48] -->
<plurals name="selected_count">
<item quantity="one"><xliff:g id="count" example="1">%1$d</xliff:g> selected</item>
@@ -4366,6 +4370,12 @@
<string name="reset_retail_demo_mode_title">Restart Session</string>
<!-- Text of notification to start a new demo session when device is in retail mode [CHAR LIMIT=NONE] -->
<string name="reset_retail_demo_mode_text">Tap to start a new demo session</string>
+ <!-- Text of dialog shown when starting a demo user for the first time [CHAR LIMIT=40] -->
+ <string name="demo_starting_message">Starting demo</string>
+ <!-- Text of dialog shown when starting a new demo user in retail demo mode [CHAR LIMIT=40] -->
+ <string name="demo_restarting_message">Restarting session</string>
+
+
<!-- Title of notification shown when device has been forced to safe mode after a security compromise. -->
<string name="audit_safemode_notification">Factory reset to use this device without restrictions</string>
diff --git a/core/res/res/values/symbols.xml b/core/res/res/values/symbols.xml
index 2de5006..8edd9d1 100644
--- a/core/res/res/values/symbols.xml
+++ b/core/res/res/values/symbols.xml
@@ -1104,6 +1104,9 @@
<java-symbol type="string" name="config_ethernet_tcp_buffers" />
<java-symbol type="string" name="config_wifi_tcp_buffers" />
<java-symbol type="string" name="config_demoModeLauncherComponent" />
+ <java-symbol type="string" name="demo_starting_message" />
+ <java-symbol type="string" name="demo_restarting_message" />
+
<java-symbol type="plurals" name="bugreport_countdown" />
<java-symbol type="plurals" name="duration_hours" />
@@ -2601,6 +2604,7 @@
<!-- TV Remote Service package -->
<java-symbol type="string" name="config_tvRemoteServicePackage" />
+ <java-symbol type="string" name="notification_messaging_title_template" />
<java-symbol type="bool" name="config_supportPreRebootSecurityLogs" />
diff --git a/data/etc/platform.xml b/data/etc/platform.xml
index a26850f..627f360 100644
--- a/data/etc/platform.xml
+++ b/data/etc/platform.xml
@@ -170,7 +170,7 @@
<!-- These are the standard packages that are white-listed to always have internet
access while in power save mode, even if they aren't in the foreground. -->
- <allow-in-power-save-except-idle package="com.android.providers.downloads" />
+ <allow-in-power-save package="com.android.providers.downloads" />
<!-- These are the standard packages that are white-listed to always have internet
access while in data mode, even if they aren't in the foreground. -->
diff --git a/docs/html/_redirects.yaml b/docs/html/_redirects.yaml
index 2464e9e..741e85c 100644
--- a/docs/html/_redirects.yaml
+++ b/docs/html/_redirects.yaml
@@ -706,7 +706,9 @@
- from: /training/enterprise/app-compatibility.html
to: /work/managed-profiles.html
- from: /training/enterprise/app-restrictions.html
- to: /work/app-restrictions.html
+ to: /work/managed-configurations.html
+- from: /work/app-restrictions.html
+ to: /work/managed-configurations.html
- from: /training/enterprise/cosu.html
to: /work/cosu.html
- from: /training/enterprise/device-management-policy.html
diff --git a/docs/html/distribute/googleplay/work/about.jd b/docs/html/distribute/googleplay/work/about.jd
index 79e8a89..b60c197 100644
--- a/docs/html/distribute/googleplay/work/about.jd
+++ b/docs/html/distribute/googleplay/work/about.jd
@@ -56,8 +56,8 @@
properly. Businesses are more conscious of data security and
employee productivity, especially when it comes to features that
share information with other services.</li>
- <li>Support the <a href="{@docRoot}work/app-restrictions.html"
- >App Configuration framework</a> to let an administrator remotely
+ <li>Support <a href="{@docRoot}work/managed-configurations.html"
+ >managed configurations</a> to let an administrator remotely
configure app settings such as:
<ul>
<li>Server address and protocol settings</li>
@@ -74,16 +74,26 @@
profile</a> and test that with the
<a href="{@docRoot}samples/BasicManagedProfile/index.html"
>BasicManagedProfile sample app</a>.</li>
- <li>Support <a href="{@docRoot}work/app-restrictions.html">app restrictions</a>
- so that IT admins can remotely configure your app through leading
- EMM solutions.</li>
+ <li>Support <a href="{@docRoot}work/managed-configurations.html"
+ >managed configurations</a> so that IT admins can remotely
+ configure your app through leading EMM solutions.</li>
</ul>
<h3 id="support">Provide support and maintenance</h3>
<ul>
-<li>Consider offering enhanced support to cover extended hours or specific means of contact. Businesses are often willing to pay for this service.</li>
-<li>If you update the App Configuration / App Restrictions schema for your app, make sure it remains backward compatible. This is because it’s possible that different users will have different versions of your app (at least temporarily), and IT admin will want a consistent remote configuration experience between versions to ensure efficient management of apps in the field.</li>
+ <li>
+ Consider offering enhanced support to cover extended hours or
+ specific means of contact. Businesses are often willing to pay for
+ this service.
+ </li>
+ <li>
+ If you update the app configuration / managed configuration schema for
+ your app, make sure it remains backward compatible. This is because
+ it’s possible that different users will have different versions of
+ your app (at least temporarily), and IT admin will want a consistent
+ remote configuration experience between versions to ensure efficient
+ management of apps in the field.</li>
</ul>
<h2 id=related_resources>Related resources</h2>
diff --git a/docs/html/guide/topics/manifest/manifest-intro.jd b/docs/html/guide/topics/manifest/manifest-intro.jd
index d7b176e..c843567 100644
--- a/docs/html/guide/topics/manifest/manifest-intro.jd
+++ b/docs/html/guide/topics/manifest/manifest-intro.jd
@@ -31,27 +31,27 @@
<li>It names the Java package for the application.
The package name serves as a unique identifier for the application.</li>
-<li>It describes the components of the application — the activities,
-services, broadcast receivers, and content providers that the application is
-composed of. It names the classes that implement each of the components and
-publishes their capabilities (for example, which {@link android.content.Intent
-Intent} messages they can handle). These declarations let the Android system
+<li>It describes the components of the application — the activities,
+services, broadcast receivers, and content providers that the application is
+composed of. It names the classes that implement each of the components and
+publishes their capabilities (for example, which {@link android.content.Intent
+Intent} messages they can handle). These declarations let the Android system
know what the components are and under what conditions they can be launched.</li>
-<li>It determines which processes will host application components.</li>
+<li>It determines which processes will host application components.</li>
-<li>It declares which permissions the application must have in order to
-access protected parts of the API and interact with other applications.</li>
+<li>It declares which permissions the application must have in order to
+access protected parts of the API and interact with other applications.</li>
-<li>It also declares the permissions that others are required to have in
+<li>It also declares the permissions that others are required to have in
order to interact with the application's components.</li>
-<li>It lists the {@link android.app.Instrumentation} classes that provide
-profiling and other information as the application is running. These declarations
-are present in the manifest only while the application is being developed and
+<li>It lists the {@link android.app.Instrumentation} classes that provide
+profiling and other information as the application is running. These declarations
+are present in the manifest only while the application is being developed and
tested; they're removed before the application is published.</li>
-<li>It declares the minimum level of the Android API that the application
+<li>It declares the minimum level of the Android API that the application
requires.</li>
<li>It lists the libraries that the application must be linked against.</li>
@@ -61,12 +61,12 @@
<h2 id="filestruct">Structure of the Manifest File</h2>
<p>
-The diagram below shows the general structure of the manifest file and
-every element that it can contain. Each element, along with all of its
-attributes, is documented in full in a separate file. To view detailed
-information about any element, click on the element name in the diagram,
+The diagram below shows the general structure of the manifest file and
+every element that it can contain. Each element, along with all of its
+attributes, is documented in full in a separate file. To view detailed
+information about any element, click on the element name in the diagram,
in the alphabetical list of elements that follows the diagram, or on any
-other mention of the element name.
+other mention of the element name.
</p>
<pre>
@@ -126,9 +126,9 @@
</pre>
<p>
-All the elements that can appear in the manifest file are listed below
-in alphabetical order. These are the only legal elements; you cannot
-add your own elements or attributes.
+All the elements that can appear in the manifest file are listed below
+in alphabetical order. These are the only legal elements; you cannot
+add your own elements or attributes.
</p>
<p style="margin-left: 2em">
@@ -158,74 +158,86 @@
</p>
-
+
<h2 id="filec">File Conventions</h2>
<p>
-Some conventions and rules apply generally to all elements and attributes
+Some conventions and rules apply generally to all elements and attributes
in the manifest:
</p>
<dl>
<dt><b>Elements</b></dt>
-<dd>Only the
+<dd>Only the
<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code> and
-<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>
-elements are required, they each must be present and can occur only once.
-Most of the others can occur many times or not at all — although at
-least some of them must be present for the manifest to accomplish anything
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>
+elements are required, they each must be present and can occur only once.
+Most of the others can occur many times or not at all — although at
+least some of them must be present for the manifest to accomplish anything
meaningful.
<p>
-If an element contains anything at all, it contains other elements.
+If an element contains anything at all, it contains other elements.
All values are set through attributes, not as character data within an element.
</p>
<p>
Elements at the same level are generally not ordered. For example,
-<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>,
-<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code>, and
-<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code>
-elements can be intermixed in any sequence. (An
-<code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html"><activity-alias></a></code>
-element is the exception to this rule: It must follow the
-<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>
-it is an alias for.)
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>,
+<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code>, and
+<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code>
+elements can be intermixed in any sequence. There are two key exceptions to this
+rule, however:
+<ul>
+ <li>
+ An <code><a href="{@docRoot}guide/topics/manifest/activity-alias-element.html"><activity-alias></a></code>
+ element must follow the
+ <code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>
+ it is an alias for.
+ </li>
+ <li>
+ The <code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>
+ element must be the last element inside the
+ <code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code>
+ element. In other words, the <code></application></code> closing tag
+ must appear immediately before the <code></manifest></code> closing
+ tag.
+ </li>
</p></dd>
<dt><b>Attributes</b></dt>
-<dd>In a formal sense, all attributes are optional. However, there are some
-that must be specified for an element to accomplish its purpose. Use the
-documentation as a guide. For truly optional attributes, it mentions a default
+<dd>In a formal sense, all attributes are optional. However, there are some
+that must be specified for an element to accomplish its purpose. Use the
+documentation as a guide. For truly optional attributes, it mentions a default
value or states what happens in the absence of a specification.
-<p>Except for some attributes of the root
-<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code>
-element, all attribute names begin with an {@code android:} prefix —
-for example, {@code android:alwaysRetainTaskState}. Because the prefix is
-universal, the documentation generally omits it when referring to attributes
+<p>Except for some attributes of the root
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code>
+element, all attribute names begin with an {@code android:} prefix —
+for example, {@code android:alwaysRetainTaskState}. Because the prefix is
+universal, the documentation generally omits it when referring to attributes
by name.</p></dd>
<dt><b>Declaring class names</b></dt>
-<dd>Many elements correspond to Java objects, including elements for the
-application itself (the
-<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>
-element) and its principal components — activities
-(<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>),
-services
-(<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code>),
-broadcast receivers
-(<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code>),
-and content providers
-(<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code>).
+<dd>Many elements correspond to Java objects, including elements for the
+application itself (the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>
+element) and its principal components — activities
+(<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>),
+services
+(<code><a href="{@docRoot}guide/topics/manifest/service-element.html"><service></a></code>),
+broadcast receivers
+(<code><a href="{@docRoot}guide/topics/manifest/receiver-element.html"><receiver></a></code>),
+and content providers
+(<code><a href="{@docRoot}guide/topics/manifest/provider-element.html"><provider></a></code>).
<p>
-If you define a subclass, as you almost always would for the component classes
-({@link android.app.Activity}, {@link android.app.Service},
-{@link android.content.BroadcastReceiver}, and {@link android.content.ContentProvider}),
-the subclass is declared through a {@code name} attribute. The name must include
-the full package designation.
+If you define a subclass, as you almost always would for the component classes
+({@link android.app.Activity}, {@link android.app.Service},
+{@link android.content.BroadcastReceiver}, and {@link android.content.ContentProvider}),
+the subclass is declared through a {@code name} attribute. The name must include
+the full package designation.
For example, an {@link android.app.Service} subclass might be declared as follows:
</p>
@@ -239,12 +251,12 @@
</manifest></pre>
<p>
-However, as a shorthand, if the first character of the string is a period, the
-string is appended to the application's package name (as specified by the
-<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code>
-element's
-<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html#package">package</a></code>
-attribute). The following assignment is the same as the one above:
+However, as a shorthand, if the first character of the string is a period, the
+string is appended to the application's package name (as specified by the
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html"><manifest></a></code>
+element's
+<code><a href="{@docRoot}guide/topics/manifest/manifest-element.html#package">package</a></code>
+attribute). The following assignment is the same as the one above:
</p>
<pre><manifest package="com.example.project" . . . >
@@ -257,13 +269,13 @@
</manifest></pre>
<p>
-When starting a component, Android creates an instance of the named subclass.
+When starting a component, Android creates an instance of the named subclass.
If a subclass isn't specified, it creates an instance of the base class.
</p></dd>
<dt><b>Multiple values</b></dt>
-<dd>If more than one value can be specified, the element is almost always
-repeated, rather than listing multiple values within a single element.
+<dd>If more than one value can be specified, the element is almost always
+repeated, rather than listing multiple values within a single element.
For example, an intent filter can list several actions:
<pre><intent-filter . . . >
@@ -274,24 +286,24 @@
</intent-filter></pre></dd>
<dt><b>Resource values</b></dt>
-<dd>Some attributes have values that can be displayed to users — for
-example, a label and an icon for an activity. The values of these attributes
-should be localized and therefore set from a resource or theme. Resource
+<dd>Some attributes have values that can be displayed to users — for
+example, a label and an icon for an activity. The values of these attributes
+should be localized and therefore set from a resource or theme. Resource
values are expressed in the following format,</p>
<p style="margin-left: 2em">{@code @[<i>package</i>:]<i>type</i>/<i>name</i>}</p>
<p>
-where the <i>package</i> name can be omitted if the resource is in the same package
-as the application, <i>type</i> is a type of resource — such as "string" or
-"drawable" — and <i>name</i> is the name that identifies the specific resource.
+where the <i>package</i> name can be omitted if the resource is in the same package
+as the application, <i>type</i> is a type of resource — such as "string" or
+"drawable" — and <i>name</i> is the name that identifies the specific resource.
For example:
</p>
<pre><activity android:icon="@drawable/smallPic" . . . ></pre>
<p>
-Values from a theme are expressed in a similar manner, but with an initial '{@code ?}'
+Values from a theme are expressed in a similar manner, but with an initial '{@code ?}'
rather than '{@code @}':
</p>
@@ -299,8 +311,8 @@
</p></dd>
<dt><b>String values</b></dt>
-<dd>Where an attribute value is a string, double backslashes ('{@code \\}')
-must be used to escape characters — for example, '{@code \\n}' for
+<dd>Where an attribute value is a string, double backslashes ('{@code \\}')
+must be used to escape characters — for example, '{@code \\n}' for
a newline or '{@code \\uxxxx}' for a Unicode character.</dd>
</dl>
@@ -308,7 +320,7 @@
<h2 id="filef">File Features</h2>
<p>
-The following sections describe how some Android features are reflected
+The following sections describe how some Android features are reflected
in the manifest file.
</p>
@@ -316,23 +328,23 @@
<h3 id="ifs">Intent Filters</h3>
<p>
-The core components of an application (its activities, services, and broadcast
-receivers) are activated by <i>intents</i>. An intent is a
-bundle of information (an {@link android.content.Intent} object) describing a
-desired action — including the data to be acted upon, the category of
-component that should perform the action, and other pertinent instructions.
-Android locates an appropriate component to respond to the intent, launches
-a new instance of the component if one is needed, and passes it the
+The core components of an application (its activities, services, and broadcast
+receivers) are activated by <i>intents</i>. An intent is a
+bundle of information (an {@link android.content.Intent} object) describing a
+desired action — including the data to be acted upon, the category of
+component that should perform the action, and other pertinent instructions.
+Android locates an appropriate component to respond to the intent, launches
+a new instance of the component if one is needed, and passes it the
Intent object.
</p>
<p>
-Components advertise their capabilities — the kinds of intents they can
-respond to — through <i>intent filters</i>. Since the Android system
-must learn which intents a component can handle before it launches the component,
-intent filters are specified in the manifest as
-<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a></code>
-elements. A component may have any number of filters, each one describing
+Components advertise their capabilities — the kinds of intents they can
+respond to — through <i>intent filters</i>. Since the Android system
+must learn which intents a component can handle before it launches the component,
+intent filters are specified in the manifest as
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a></code>
+elements. A component may have any number of filters, each one describing
a different capability.
</p>
@@ -344,9 +356,9 @@
</p>
<p>
-For information on how Intent objects are tested against intent filters,
-see a separate document,
-<a href="{@docRoot}guide/components/intents-filters.html">Intents
+For information on how Intent objects are tested against intent filters,
+see a separate document,
+<a href="{@docRoot}guide/components/intents-filters.html">Intents
and Intent Filters</a>.
</p>
@@ -354,42 +366,42 @@
<h3 id="iconlabel">Icons and Labels</h3>
<p>
-A number of elements have {@code icon} and {@code label} attributes for a
-small icon and a text label that can be displayed to users. Some also have a
-{@code description} attribute for longer explanatory text that can also be
-shown on-screen. For example, the
+A number of elements have {@code icon} and {@code label} attributes for a
+small icon and a text label that can be displayed to users. Some also have a
+{@code description} attribute for longer explanatory text that can also be
+shown on-screen. For example, the
<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
-element has all three of these attributes, so that when the user is asked whether
-to grant the permission to an application that has requested it, an icon representing
-the permission, the name of the permission, and a description of what it
+element has all three of these attributes, so that when the user is asked whether
+to grant the permission to an application that has requested it, an icon representing
+the permission, the name of the permission, and a description of what it
entails can all be presented to the user.
</p>
<p>
-In every case, the icon and label set in a containing element become the default
-{@code icon} and {@code label} settings for all of the container's subelements.
-Thus, the icon and label set in the
-<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>
-element are the default icon and label for each of the application's components.
-Similarly, the icon and label set for a component — for example, an
-<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>
-element — are the default settings for each of the component's
-<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a></code>
+In every case, the icon and label set in a containing element become the default
+{@code icon} and {@code label} settings for all of the container's subelements.
+Thus, the icon and label set in the
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>
+element are the default icon and label for each of the application's components.
+Similarly, the icon and label set for a component — for example, an
+<code><a href="{@docRoot}guide/topics/manifest/activity-element.html"><activity></a></code>
+element — are the default settings for each of the component's
+<code><a href="{@docRoot}guide/topics/manifest/intent-filter-element.html"><intent-filter></a></code>
elements. If an
-<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>
-element sets a label, but an activity and its intent filter do not,
-the application label is treated as the label for both the activity and
+<code><a href="{@docRoot}guide/topics/manifest/application-element.html"><application></a></code>
+element sets a label, but an activity and its intent filter do not,
+the application label is treated as the label for both the activity and
the intent filter.
</p>
<p>
-The icon and label set for an intent filter are used to represent a component
+The icon and label set for an intent filter are used to represent a component
whenever the component is presented to the user as fulfilling the function
-advertised by the filter. For example, a filter with
-"{@code android.intent.action.MAIN}" and
-"{@code android.intent.category.LAUNCHER}" settings advertises an activity
+advertised by the filter. For example, a filter with
+"{@code android.intent.action.MAIN}" and
+"{@code android.intent.category.LAUNCHER}" settings advertises an activity
as one that initiates an application — that is, as
-one that should be displayed in the application launcher. The icon and label
+one that should be displayed in the application launcher. The icon and label
set in the filter are therefore the ones displayed in the launcher.
</p>
@@ -397,14 +409,14 @@
<h3 id="perms">Permissions</h3>
<p>
-A <i>permission</i> is a restriction limiting access to a part of the code
-or to data on the device. The limitation is imposed to protect critical
-data and code that could be misused to distort or damage the user experience.
+A <i>permission</i> is a restriction limiting access to a part of the code
+or to data on the device. The limitation is imposed to protect critical
+data and code that could be misused to distort or damage the user experience.
</p>
<p>
-Each permission is identified by a unique label. Often the label indicates
-the action that's restricted. For example, here are some permissions defined
+Each permission is identified by a unique label. Often the label indicates
+the action that's restricted. For example, here are some permissions defined
by Android:
</p>
@@ -418,26 +430,26 @@
</p>
<p>
-If an application needs access to a feature protected by a permission,
-it must declare that it requires that permission with a
-<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>
-element in the manifest. Then, when the application is installed on
-the device, the installer determines whether or not to grant the requested
-permission by checking the authorities that signed the application's
-certificates and, in some cases, asking the user.
-If the permission is granted, the application is able to use the protected
-features. If not, its attempts to access those features will simply fail
-without any notification to the user.
+If an application needs access to a feature protected by a permission,
+it must declare that it requires that permission with a
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>
+element in the manifest. Then, when the application is installed on
+the device, the installer determines whether or not to grant the requested
+permission by checking the authorities that signed the application's
+certificates and, in some cases, asking the user.
+If the permission is granted, the application is able to use the protected
+features. If not, its attempts to access those features will simply fail
+without any notification to the user.
</p>
<p>
-An application can also protect its own components (activities, services,
-broadcast receivers, and content providers) with permissions. It can employ
-any of the permissions defined by Android (listed in
-{@link android.Manifest.permission android.Manifest.permission}) or declared
-by other applications. Or it can define its own. A new permission is declared
-with the
-<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
+An application can also protect its own components (activities, services,
+broadcast receivers, and content providers) with permissions. It can employ
+any of the permissions defined by Android (listed in
+{@link android.Manifest.permission android.Manifest.permission}) or declared
+by other applications. Or it can define its own. A new permission is declared
+with the
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
element. For example, an activity could be protected as follows:
</p>
@@ -457,43 +469,43 @@
</pre>
<p>
-Note that, in this example, the {@code DEBIT_ACCT} permission is not only
-declared with the
-<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
-element, its use is also requested with the
-<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>
-element. Its use must be requested in order for other components of the
-application to launch the protected activity, even though the protection
-is imposed by the application itself.
+Note that, in this example, the {@code DEBIT_ACCT} permission is not only
+declared with the
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
+element, its use is also requested with the
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>
+element. Its use must be requested in order for other components of the
+application to launch the protected activity, even though the protection
+is imposed by the application itself.
</p>
<p>
-If, in the same example, the {@code permission} attribute was set to a
-permission declared elsewhere
-(such as {@code android.permission.CALL_EMERGENCY_NUMBERS}, it would not
-have been necessary to declare it again with a
-<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
-element. However, it would still have been necessary to request its use with
-<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>.
+If, in the same example, the {@code permission} attribute was set to a
+permission declared elsewhere
+(such as {@code android.permission.CALL_EMERGENCY_NUMBERS}, it would not
+have been necessary to declare it again with a
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
+element. However, it would still have been necessary to request its use with
+<code><a href="{@docRoot}guide/topics/manifest/uses-permission-element.html"><uses-permission></a></code>.
</p>
<p>
-The
-<code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html"><permission-tree></a></code>
-element declares a namespace for a group of permissions that will be defined in
-code. And
+The
+<code><a href="{@docRoot}guide/topics/manifest/permission-tree-element.html"><permission-tree></a></code>
+element declares a namespace for a group of permissions that will be defined in
+code. And
<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html"><permission-group></a></code>
-defines a label for a set of permissions (both those declared in the manifest with
-<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
-elements and those declared elsewhere). It affects only how the permissions are
-grouped when presented to the user. The
+defines a label for a set of permissions (both those declared in the manifest with
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
+elements and those declared elsewhere). It affects only how the permissions are
+grouped when presented to the user. The
<code><a href="{@docRoot}guide/topics/manifest/permission-group-element.html"><permission-group></a></code>
-element does not specify which permissions belong to the group;
+element does not specify which permissions belong to the group;
it just gives the group a name. A permission is placed in the group
by assigning the group name to the
-<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
-element's
-<code><a href="{@docRoot}guide/topics/manifest/permission-element.html#pgroup">permissionGroup</a></code>
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html"><permission></a></code>
+element's
+<code><a href="{@docRoot}guide/topics/manifest/permission-element.html#pgroup">permissionGroup</a></code>
attribute.
</p>
@@ -501,17 +513,17 @@
<h3 id="libs">Libraries</h3>
<p>
-Every application is linked against the default Android library, which
-includes the basic packages for building applications (with common classes
-such as Activity, Service, Intent, View, Button, Application, ContentProvider,
+Every application is linked against the default Android library, which
+includes the basic packages for building applications (with common classes
+such as Activity, Service, Intent, View, Button, Application, ContentProvider,
and so on).
</p>
<p>
-However, some packages reside in their own libraries. If your application
-uses code from any of these packages, it must explicitly asked to be linked
-against them. The manifest must contain a separate
-<code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html"><uses-library></a></code>
-element to name each of the libraries. (The library name can be found in the
+However, some packages reside in their own libraries. If your application
+uses code from any of these packages, it must explicitly asked to be linked
+against them. The manifest must contain a separate
+<code><a href="{@docRoot}guide/topics/manifest/uses-library-element.html"><uses-library></a></code>
+element to name each of the libraries. (The library name can be found in the
documentation for the package.)
</p>
diff --git a/docs/html/jd_collections.js b/docs/html/jd_collections.js
index 4909206d..aa0620a 100644
--- a/docs/html/jd_collections.js
+++ b/docs/html/jd_collections.js
@@ -1881,7 +1881,7 @@
"work/overview.html",
"work/guide.html",
"https://www.google.com/work/android/developers/applyDevHub/",
- "work/app-restrictions.html",
+ "work/managed-configurations.html",
"work/cosu.html",
"work/managed-profiles.html"
]
@@ -1893,7 +1893,7 @@
"https://www.google.com/work/android/",
"https://developers.google.com/android/work/build-dpc",
"https://www.youtube.com/watch?v=jQWB_-o1kz4&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX",
- "https://www.youtube.com/watch?v=39NkpWkaH8M&index=2&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX",
+ "https://www.youtube.com/watch?v=Za0OQo8DRM4",
"https://www.youtube.com/watch?v=dH41OutAMNM&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX"
]
},
@@ -1901,7 +1901,7 @@
"title": "",
"resources": [
"work/managed-profiles.html",
- "work/app-restrictions.html",
+ "work/managed-configurations.html",
"work/cosu.html",
"https://www.youtube.com/watch?v=39NkpWkaH8M&index=2&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX",
"samples/AppRestrictionSchema/index.html",
diff --git a/docs/html/jd_extras.js b/docs/html/jd_extras.js
index 546fcfe..e5347d9 100644
--- a/docs/html/jd_extras.js
+++ b/docs/html/jd_extras.js
@@ -3379,6 +3379,18 @@
"type":"youtube"
},
{
+ "title":"Your Apps at Work",
+ "titleFriendly":"",
+ "summary":"In this Google I/O 2016 session we’ll give you details for making your app more attractive to businesses.",
+ "url":"https://www.youtube.com/watch?v=Za0OQo8DRM4",
+ "group":"",
+ "keywords": ["work", "enterprise", "emm"],
+ "tags": [],
+ "image":"https://i1.ytimg.com/vi/Za0OQo8DRM4/maxresdefault.jpg",
+ "lang":"en",
+ "type":"youtube"
+ },
+ {
"title":"Discover YouTube cards",
"titleFriendly":"",
"summary":"Find out more about YouTube cards, the options available, and how to use them to get the most from your YouTube content.",
diff --git a/docs/html/jd_extras_en.js b/docs/html/jd_extras_en.js
index 3aab5bd..6295e0e 100644
--- a/docs/html/jd_extras_en.js
+++ b/docs/html/jd_extras_en.js
@@ -3266,10 +3266,10 @@
"type":"guide"
},
{
- "title":"Set up App Restrictions",
+ "title":"Set up Managed Configurations",
"titleFriendly":"",
- "summary": "Learn how to implement app restrictions and configuration settings that can be changed by other apps on the same device.",
- "url":"https://developer.android.com/work/app-restrictions.html",
+ "summary": "Learn how to implement managed configurations that can be changed by other apps on the same device.",
+ "url":"https://developer.android.com/work/managed-restrictions.html",
"group":"",
"keywords": ["work", "enterprise", "emm"],
"tags": [],
@@ -3398,6 +3398,18 @@
"type":"youtube"
},
{
+ "title":"Your Apps at Work",
+ "titleFriendly":"",
+ "summary":"In this Google I/O 2016 session we’ll give you details for making your app more attractive to businesses.",
+ "url":"https://www.youtube.com/watch?v=Za0OQo8DRM4",
+ "group":"",
+ "keywords": ["work", "enterprise", "emm"],
+ "tags": [],
+ "image":"https://i1.ytimg.com/vi/Za0OQo8DRM4/maxresdefault.jpg",
+ "lang":"en",
+ "type":"youtube"
+ },
+ {
"title":"Discover YouTube cards",
"category":"google",
"summary":"Find out more about YouTube cards, the options available, and how to use them to get the most from your YouTube content.",
@@ -5390,7 +5402,7 @@
"work/overview.html",
"work/guide.html",
"https://www.google.com/work/android/developers/applyDevHub/",
- "work/app-restrictions.html",
+ "work/managed-configurations.html",
"work/cosu.html",
"work/managed-profiles.html"
]
@@ -5402,7 +5414,7 @@
"https://www.google.com/work/android/",
"https://developers.google.com/android/work/build-dpc",
"https://www.youtube.com/watch?v=jQWB_-o1kz4&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX",
- "https://www.youtube.com/watch?v=39NkpWkaH8M&index=2&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX",
+ "https://www.youtube.com/watch?v=Za0OQo8DRM4",
"https://www.youtube.com/watch?v=dH41OutAMNM&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX"
]
},
@@ -5410,7 +5422,7 @@
"title": "",
"resources": [
"work/managed-profiles.html",
- "work/app-restrictions.html",
+ "work/managed-configurations.html",
"work/cosu.html",
"https://www.youtube.com/watch?v=39NkpWkaH8M&index=2&list=PLOU2XLYxmsIKAK2Bhv19H2THwF-22O5WX",
"samples/AppRestrictionSchema/index.html",
diff --git a/docs/html/preview/api-overview.jd b/docs/html/preview/api-overview.jd
index ab2b5ba..d457d5c 100644
--- a/docs/html/preview/api-overview.jd
+++ b/docs/html/preview/api-overview.jd
@@ -119,10 +119,10 @@
</li>
<li>
- <strong>Message style customization</strong>: You can customize more of the
- user interface labels associated with your notifications using the
- <code>MessageStyle</code> class. You can configure the message, conversation
- title, and content view.
+ <strong>Messaging style customization</strong>: You can customize more of
+ the user interface labels associated with your notifications using the
+ <code>MessagingStyle</code> class. You can configure the message,
+ conversation title, and content view.
</li>
<li>
diff --git a/docs/html/preview/features/afw.jd b/docs/html/preview/features/afw.jd
index 9b94c07..17cd58e 100644
--- a/docs/html/preview/features/afw.jd
+++ b/docs/html/preview/features/afw.jd
@@ -47,7 +47,7 @@
<li><a href="#ui-policy">System UI Policy Transparency
</a></li>
- <li><a href="#restrictions-mgmt">App Restrictions Management Enhancements
+ <li><a href="#managed-configurations">Managed Configurations Enhancements
</a></li>
<li><a href="#location-off">Location Off Switch
@@ -401,11 +401,11 @@
</li>
</ul>
-<h2 id="restrictions-mgmt">App Restrictions Management Enhancements</h2>
+<h2 id="managed-configurations">Managed Configurations Enhancements</h2>
<p>
- The device or profile owner can enable another application to manage app
- restrictions via the new
+ The device or profile owner can enable another application to manage
+ configurations via the new
<code>DevicePolicyManager.setApplicationRestrictionsManagingPackage()</code>
method. The nominated application can check whether this permission has been
granted by calling
@@ -413,7 +413,7 @@
</p>
<p>
- An application nominated to manage app restrictions can call {@link
+ An application nominated to manage configurations can call {@link
android.app.admin.DevicePolicyManager#setApplicationRestrictions
setApplicationRestrictions()} and {@link
android.app.admin.DevicePolicyManager#getApplicationRestrictions
diff --git a/docs/html/preview/features/notification-updates.jd b/docs/html/preview/features/notification-updates.jd
index 0163337..af449cb 100644
--- a/docs/html/preview/features/notification-updates.jd
+++ b/docs/html/preview/features/notification-updates.jd
@@ -16,7 +16,7 @@
<li><a href="#direct">Direct Reply</a></li>
<li><a href="#bundle">Bundled Notifications</a></li>
<li><a href="#custom">Custom Views</a></li>
- <li><a href="#style">Message Style</a></li>
+ <li><a href="#style">Messaging Style</a></li>
</ol>
</div>
@@ -378,14 +378,14 @@
<h2 id="style">Messaging Style</h2>
<p>
Android N introduces a new API for customizing the style of a notification.
- Using the <code>MessageStyle</code> class, you can change several of the
+ Using the <code>MessagingStyle</code> class, you can change several of the
labels displayed on the notification, including the conversation title,
additional messages, and the content view for the notification.
</p>
<p>
The following code snippet demonstrates how to customize a notification's
- style using the <code>MessageStyle</code> class.
+ style using the <code>MessagingStyle</code> class.
</p>
<pre>
diff --git a/docs/html/wear/preview/features/notifications.jd b/docs/html/wear/preview/features/notifications.jd
index 75f9fee..c84a470 100644
--- a/docs/html/wear/preview/features/notifications.jd
+++ b/docs/html/wear/preview/features/notifications.jd
@@ -194,9 +194,10 @@
<ol>
<li>Use <a href="{@docRoot}preview/features/notification-updates.html#style">{@code Notification.MessagingStyle}</a>.
</li>
- <li>Call the method
- <a href="{@docRoot}wear/preview/start.html#get_the_preview_reference_documentation">{@code setAllowGeneratedReplies()}</a>
- for the notification action.</li>
+ <li>Call the method {@code setAllowGeneratedReplies()} for the notification action.
+ For more information, see the downloadable
+ <a href="{@docRoot}preview/setup-sdk.html#docs-dl">API reference</a>.
+ </li>
<li>Ensure that the notification action has a
<a href="{@docRoot}reference/android/app/RemoteInput.html">{@code RemoteInput}</a>
(where the responses will reside).
diff --git a/docs/html/work/_book.yaml b/docs/html/work/_book.yaml
index 82571f3..1482a4e 100644
--- a/docs/html/work/_book.yaml
+++ b/docs/html/work/_book.yaml
@@ -1,18 +1,132 @@
toc:
- title: Android for Work Home
path: /work/index.html
+ path_attributes:
+ - name: es-lang
+ value: Página principal de Android for Work
+ - name: in-lang
+ value: Beranda Android for Work
+ - name: ja-lang
+ value: Android for Work ホーム
+ - name: ko-lang
+ value: Android for Work 홈
+ - name: pt-br-lang
+ value: Página inicial do Android for Work
+ - name: ru-lang
+ value: Главная – Android for Work
+ - name: vi-lang
+ value: Trang chủ Android for Work
+ - name: zh-cn-lang
+ value: Android for Work 首页
+ - name: zh-tw-lang
+ value: Android for Work 首頁
- title: Overview
path: /work/overview.html
+ path_attributes:
+ - name: es-lang
+ value: Información general
+ - name: in-lang
+ value: Ringkasan
+ - name: ja-lang
+ value: 概要
+ - name: ko-lang
+ value: 개요
+ - name: pt-br-lang
+ value: Visão geral
+ - name: ru-lang
+ value: Обзор
+ - name: vi-lang
+ value: Tổng quan
+ - name: zh-cn-lang
+ value: 概览
+ - name: zh-tw-lang
+ value: 總覽
- title: Developer Guide
path: /work/guide.html
+ path_attributes:
+ - name: es-lang
+ value: Guía para desarrolladores
+ - name: in-lang
+ value: Panduan Pengembang
+ - name: ja-lang
+ value: デベロッパー ガイド
+ - name: ko-lang
+ value: 개발자 가이드
+ - name: pt-br-lang
+ value: Guia do desenvolvedor
+ - name: ru-lang
+ value: Руководство для разработчиков
+ - name: vi-lang
+ value: Hướng dẫn cho nhà phát triển
+ - name: zh-cn-lang
+ value: 开发者指南
+ - name: zh-tw-lang
+ value: 開發人員指南
- title: Set up Managed Profiles
path: /work/managed-profiles.html
+ path_attributes:
+ - name: es-lang
+ value: Configurar perfiles administrados
+ - name: in-lang
+ value: Menyiapkan Profil Terkelola
+ - name: ja-lang
+ value: 管理対象プロファイルの設定
+ - name: ko-lang
+ value: 관리 프로필 설정
+ - name: pt-br-lang
+ value: Configurar perfis gerenciados
+ - name: ru-lang
+ value: Настройка управляемых профилей
+ - name: vi-lang
+ value: Thiết lập hồ sơ được quản lý
+ - name: zh-cn-lang
+ value: 设置托管配置文件
+ - name: zh-tw-lang
+ value: 設定受管理的設定檔
-- title: Set up App Restrictions
- path: /work/app-restrictions.html
+- title: Set up Managed Configurations
+ path: /work/managed-configurations.html
+ path_attributes:
+ - name: es-lang
+ value: Configurar ajustes administrados
+ - name: in-lang
+ value: Menyiapkan Konfigurasi Terkelola
+ - name: ja-lang
+ value: 管理対象構成の設定
+ - name: ko-lang
+ value: 관리 구성 설정
+ - name: pt-br-lang
+ value: Definir configurações gerenciadas
+ - name: ru-lang
+ value: Настройка управляемых конфигураций
+ - name: vi-lang
+ value: Thiết lập cấu hình được quản lý
+ - name: zh-cn-lang
+ value: 设置托管配置
+ - name: zh-tw-lang
+ value: 設置受管理的設定
- title: Set up Single-Purpose Devices
path: /work/cosu.html
+ path_attributes:
+ - name: es-lang
+ value: Configurar dispositivos con una sola finalidad
+ - name: in-lang
+ value: Menyiapkan Perangkat Tujuan Tunggal
+ - name: ja-lang
+ value: 用途に特化した端末の設定
+ - name: ko-lang
+ value: 단일 목적 기기 설정
+ - name: pt-br-lang
+ value: Configurar dispositivos com uma finalidade específica
+ - name: ru-lang
+ value: Настройка одноцелевых устройств
+ - name: vi-lang
+ value: Thiết lập thiết bị chuyên dùng
+ - name: zh-cn-lang
+ value: 设置单一用途设备
+ - name: zh-tw-lang
+ value: 設定單一用途的裝置
diff --git a/docs/html/work/app-restrictions.jd b/docs/html/work/app-restrictions.jd
deleted file mode 100644
index 4122988b..0000000
--- a/docs/html/work/app-restrictions.jd
+++ /dev/null
@@ -1,352 +0,0 @@
-page.title=Set up App Restrictions
-page.metaDescription=Learn how to implement app restrictions and configuration settings that can be changed by other apps on the same device.
-page.image=images/work/cards/briefcase_600px.png
-
-@jd:body
-
-<div id="qv-wrapper">
- <div id="qv">
- <h2>In this document</h2>
- <ol>
- <li><a href="#define_restrictions">Define App Restrictions</a></li>
- <li><a href="#check_restrictions">Check App Restrictions</a></li>
- <li><a href="#listen">Listen for App Restriction Changes</a></li>
- </ol>
- </div>
-</div>
-
-<p>If you are developing apps for the enterprise market, you may need to satisfy
-particular requirements set by a company's policies. Application restrictions
-allow the enterprise administrator to remotely specify settings for apps.
-This capability is particularly useful for enterprise-approved apps deployed to
-a managed profile.</p>
-
-<p>For example, an enterprise might require that approved apps allow the
-enterprise administrator to:</p>
-
-<ul>
- <li>Whitelist or blacklist URLs for a web browser</li>
- <li>Configure whether an app is allowed to sync content via cellular, or just
- by Wi-Fi</li>
- <li>Configure the app's email settings</li>
-</ul>
-
-<p>
- This guide shows how to implement these configuration settings in your app.
-</p>
-
-<p class="note">
- <strong>Note:</strong> For historical reasons, these configuration settings are known as
- <em>restrictions,</em> and are implemented with files and classes that use this
- term (such as {@link android.content.RestrictionsManager}). However, these
- restrictions can actually implement a wide range of configuration options,
- not just restrictions on app functionality.
-</p>
-
-<h2 id="overview">
- Remote Configuration Overview
-</h2>
-
-<p>
- Apps define the restrictions and configuration options that can be remotely
- set by an administrator. These restrictions are
- arbitrary configuration settings that can be changed by a restrictions
- provider. If your app is running on an enterprise device's managed
- profile, the enterprise administrator can change your app's restrictions.
-</p>
-
-<p>
- The restrictions provider is another app running on the same device.
- This app is typically controlled by the enterprise administrator. The
- enterprise administrator communicates restriction changes to the restrictions
- provider app. That app, in turn, changes the restrictions on your app.
-</p>
-
-<p>
- To provide externally configurable restrictions:
-</p>
-
-<ul>
- <li>Declare the restrictions in your app manifest. Doing so allows the
- enterprise administrator to read the app's restrictions through Google
- Play APIs.
- </li>
-
- <li>Whenever the app resumes, use the {@link
- android.content.RestrictionsManager} object to check the current
- restrictions, and change your app's UI and behavior to conform with those
- restrictions.
- </li>
-
- <li>Listen for the
- {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
- ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. When you receive this
- broadcast, check the {@link android.content.RestrictionsManager} to see what
- the current restrictions are, and make any necessary changes to your app's
- behavior.
- </li>
-</ul>
-
-<h2 id="define_restrictions">
- Define App Restrictions
-</h2>
-
-<p>
- Your app can support any restrictions you want to define. You declare the
- app's restrictions in a <em>restrictions file</em>, and declare the
- restrictions file in the manifest. Creating a restrictions file allows other
- apps to examine the restrictions your app provides. Enterprise Mobility
- Management (EMM) partners can read your app's restrictions by using Google
- Play APIs.
-</p>
-
-<p>
- To define your app's remote configuration options, put the following element
- in your manifest's
- <a href="{@docRoot}guide/topics/manifest/application-element.html">
- <code><application></code></a> element:
-</p>
-
-<pre><meta-data android:name="android.content.APP_RESTRICTIONS"
- android:resource="@xml/app_restrictions" />
-</pre>
-
-<p>
- Create a file named <code>app_restrictions.xml</code> in your app's
- <code>res/xml</code> directory. The structure of that file is described in
- the reference for {@link android.content.RestrictionsManager}. The file has a
- single top-level <code><restrictions></code> element, which contains
- one <code><restriction></code> child element for every configuration
- option the app has.
-</p>
-
-<p class="note">
- <strong>Note:</strong> Do not create localized versions of the restrictions
- file. Your app is only allowed to have a single restrictions file,
- so restrictions will be consistent for your app in all locales.
-</p>
-
-<p>
- In an enterprise environment, an EMM will typically use the restrictions
- schema to generate a remote console for IT administrators, so the
- administrators can remotely configure your application.
-</p>
-
-<p>
- For example, suppose your app can be remotely configured to allow or forbid
- it to download data over a cellular connection. Your app could have a
- <code><restriction></code> element like this:
-</p>
-
-<pre>
-<?xml version="1.0" encoding="utf-8"?>
-<restrictions xmlns:android="http://schemas.android.com/apk/res/android" >
-
- <restriction
- android:key="downloadOnCellular"
- android:title="App is allowed to download data via cellular"
- android:restrictionType="bool"
- android:description="If 'false', app can only download data via Wi-Fi"
- android:defaultValue="true" />
-
-</restrictions>
-</pre>
-
-<p>
- The supported types for the <code>android:restrictionType</code> element are
- documented in the reference for {@link android.content.RestrictionsManager}.
-</p>
-
-<p>
- You use each restriction's <code>android:key</code> attribute to read its
- value from a restrictions bundle. For this reason, each restriction must have
- a unique key string, and the string <em>cannot</em> be localized. It must be
- specified with a string literal.
-</p>
-
-<p class="note">
- <strong>Note:</strong> In a production app, <code>android:title</code> and
- <code>android:description</code> should be drawn from a localized resource
- file, as described in <a href=
- "{@docRoot}guide/topics/resources/localization.html">Localizing with
- Resources</a>.
-</p>
-
-<p>
- The restrictions provider can query the app to find details on the app's
- available restrictions, including their description text. Restrictions
- providers and enterprise administrators can change your app's restrictions at
- any time, even when the app is not running.
-</p>
-
-<h2 id="check_restrictions">
- Check App Restrictions
-</h2>
-
-<p>
- Your app is not automatically notified when other apps change its restriction
- settings. Instead, you need to check what the restrictions are when your app
- starts or resumes, and listen for a system intent to find out if the
- restrictions change while your app is running.
-</p>
-
-<p>
- To find out the current restriction settings, your app uses a {@link
- android.content.RestrictionsManager} object. Your app should check for the
- current restrictions at the following times:
-</p>
-
-<ul>
- <li>When the app starts or resumes, in its
- {@link android.app.Activity#onResume onResume()} method
- </li>
-
- <li>When the app is notified of a restriction change, as described in
- <a href="#listen">Listen for Device Configuration
- Changes</a>
- </li>
-</ul>
-
-<p>
- To get a {@link android.content.RestrictionsManager} object, get the current
- activity with {@link android.app.Fragment#getActivity getActivity()}, then
- call that activity's {@link android.app.Activity#getSystemService
- Activity.getSystemService()} method:
-</p>
-
-<pre>RestrictionsManager myRestrictionsMgr =
- (RestrictionsManager) getActivity()
- .getSystemService(Context.RESTRICTIONS_SERVICE);</pre>
-
-<p>
- Once you have a {@link android.content.RestrictionsManager}, you can get the current restrictions
- settings by calling its
- {@link android.content.RestrictionsManager#getApplicationRestrictions
- getApplicationRestrictions()} method:
-</p>
-
-<pre>Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();</pre>
-
-<p class="note">
- <strong>Note:</strong> For convenience, you can also fetch the current
- restrictions with a {@link android.os.UserManager}, by calling {@link
- android.os.UserManager#getApplicationRestrictions
- UserManager.getApplicationRestrictions()}. This method behaves exactly the
- same as {@link android.content.RestrictionsManager#getApplicationRestrictions
- RestrictionsManager.getApplicationRestrictions()}.
-</p>
-
-<p>
- The {@link android.content.RestrictionsManager#getApplicationRestrictions
- getApplicationRestrictions()} method requires reading from data storage, so
- it should be done sparingly. Do not call this method every time you need to
- know the current restrictions. Instead, you should call it once when your app
- starts or resumes, and cache the fetched restrictions bundle. Then listen for
- the {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
- ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent to find out if restrictions
- change while your app is active, as described in <a href="#listen">Listen for
- Device Configuration Changes</a>.
-</p>
-
-<h3 id="read_restrictions">
- Reading and applying restrictions
-</h3>
-
-<p>
- The {@link android.content.RestrictionsManager#getApplicationRestrictions
- getApplicationRestrictions()} method returns a {@link android.os.Bundle}
- containing a key-value pair for each restriction that has been set. The
- values are all of type <code>Boolean</code>, <code>int</code>,
- <code>String</code>, and <code>String[]</code>. Once you have the
- restrictions {@link android.os.Bundle}, you can check the current
- restrictions settings with the standard {@link android.os.Bundle} methods for
- those data types, such as {@link android.os.Bundle#getBoolean getBoolean()}
- or
- {@link android.os.Bundle#getString getString()}.
-</p>
-
-<p class="note">
- <strong>Note:</strong> The restrictions {@link android.os.Bundle} contains
- one item for every restriction that has been explicitly set by a restrictions
- provider. However, you <em>cannot</em> assume that a restriction will be
- present in the bundle just because you defined a default value in the
- restrictions XML file.
-</p>
-
-<p>
- It is up to your app to take appropriate action based on the current
- restrictions settings. For example, if your app has a restriction specifying
- whether it can download data over a cellular connection, and you find that
- the restriction is set to <code>false</code>, you would have to disable data
- download except when the device has a Wi-Fi connection, as shown in the
- following example code:
-</p>
-
-<pre>
-boolean appCanUseCellular;
-
-if appRestrictions.containsKey("downloadOnCellular") {
- appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular");
-} else {
- // here, cellularDefault is a boolean set with the restriction's
- // default value
- appCanUseCellular = cellularDefault;
-}
-
-if (!appCanUseCellular) {
- // ...turn off app's cellular-download functionality
- // ...show appropriate notices to user
-}</pre>
-
-<h2 id="listen">
- Listen for App Restriction Changes
-</h2>
-
-<p>
- Whenever an app's restrictions are changed, the system fires the
- {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
- ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. Your app has to listen for
- this intent so you can change the app's behavior when the restriction settings
- change.</p>
-
-<p class="note">
- <strong>Note:</strong> The {@link
- android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
- ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent is sent only to listeners
- that are dynamically registered, <em>not</em> to listeners that are declared
- in the app manifest.
-</p>
-<p>
- The following code shows how to dynamically register a broadcast receiver for
- this intent:
-</p>
-
-<pre>IntentFilter restrictionsFilter =
- new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
-
-BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() {
- @Override public void onReceive(Context context, Intent intent) {
-
- // Get the current restrictions bundle
- Bundle <code>appRestrictions</code> =
-
- myRestrictionsMgr.getApplicationRestrictions();
-
- // Check current restrictions settings, change your app's UI and
- // functionality as necessary.
-
- }
-
-};
-
-registerReceiver(restrictionsReceiver, restrictionsFilter);
-</pre>
-<p class="note">
- <strong>Note:</strong> Ordinarily, your app does not need to be notified
- about restriction changes when it is paused. Instead, you should unregister
- your broadcast receiver when the app is paused. When the app resumes, you
- first check for the current restrictions (as discussed in <a href=
- "#check_restrictions">Check Device Restrictions</a>), then register your
- broadcast receiver to make sure you're notified about restriction changes
- that happen while the app is active.
-</p>
diff --git a/docs/html/work/cosu.jd b/docs/html/work/cosu.jd
index 3058365..dfecf00 100644
--- a/docs/html/work/cosu.jd
+++ b/docs/html/work/cosu.jd
@@ -128,7 +128,7 @@
<p>
Additional COSU management features launched with Marshmallow make it easier to
develop and deploy Android devices as a single-use device. If you want to
-enforce server-side app restrictions or server-side profile policy controls,
+enforce server-side managed configurations or server-side profile policy controls,
you need to use an EMM or make your application a DPC. Follow the instructions
below as you create your application.
</p>
@@ -343,7 +343,7 @@
</li>
<li>
-Set default user restrictions via
+Set default user restriction for managed configurations via
{@link android.app.admin.DevicePolicyManager#addUserRestriction addUserRestriction()}
</li>
@@ -398,7 +398,7 @@
}
private void setDefaultCosuPolicies(boolean active) {
- // set user restrictions
+ // set managed configurations
setUserRestriction(DISALLOW_SAFE_BOOT, active);
setUserRestriction(DISALLOW_FACTORY_RESET, active);
setUserRestriction(DISALLOW_ADD_USER, active);
diff --git a/docs/html/work/guide.jd b/docs/html/work/guide.jd
index a93bfa5..30b895b 100644
--- a/docs/html/work/guide.jd
+++ b/docs/html/work/guide.jd
@@ -10,7 +10,7 @@
<h2>In this document</h2>
<ul>
<li><a href="#managed-profiles">Managed Profiles</a></li>
- <li><a href="#app-restrictions">Implementing App Restrictions</a></li>
+ <li><a href="#managed-configurations">Implementing Managed Configurations</a></li>
<li><a href="#cosu">COSU Devices</a></li>
<li><a href="#sso">Set up Single Sign-on with Chrome Custom Tabs</a></li>
<li><a href="#testing">Test Your App</a></li>
@@ -32,7 +32,7 @@
app so it functions best on an Android device with a work profile.
</li>
<li>
- <a href="#app-restrictions">Managed configuration using app restrictions</a>—Modify
+ <a href="#managed-configurations">Managed configurations</a>—Modify
your app to allow IT administrators the option to specify custom
settings for your apps.
</li>
@@ -191,10 +191,10 @@
<a href="#testing">Test your app with Android for Work</a>.
</p>
-<h2 id="app-restrictions">Implementing App Restrictions</h2>
+<h2 id="managed-configurations">Implementing Managed Configurations</h2>
<p>
- App restrictions are a set of instructions that IT administrators
+ Managed configurations are a set of instructions that IT administrators
can use to manage their users’ mobile devices in a specific way.
These instructions are universal and work across any EMM, allowing
administrators to remotely configure applications on their users’
@@ -204,7 +204,7 @@
<p>
If you’re developing apps for business or government, you may need
to satisfy your industry’s specific set of requirements. Using
- application restrictions, the IT administrator can remotely specify
+ managed configurations, the IT administrator can remotely specify
settings and enforce policies for their users’ Android apps; for
example:
</p>
@@ -217,26 +217,26 @@
<li>Manage bookmarks</li>
</ul>
-<h3>Best practices for implementing app restrictions</h3>
+<h3>Best practices for implementing managed configurations</h3>
<p>
- The <a href="{@docRoot}work/app-restrictions.html">Set up App Restrictions</a>
+ The <a href="{@docRoot}work/managed-configurations.html">Set up Managed Configurations</a>
guide is the key source for information on how to build and deploy
- app restrictions. After you’ve reviewed this documentation, see
+ managed configurations. After you’ve reviewed this documentation, see
recommendations below for additional guidance.
</p>
<h4>When first launching the app</h4>
<p>
- As soon as you launch an application, you can see if app
- restrictions are already set for this app in <code>onStart()</code> or
+ As soon as you launch an application, you can see if managed
+ configurations are already set for this app in <code>onStart()</code> or
<code>onResume()</code>. Additionally, you can find out if your
application is managed or unmanaged. For example, if
<a href="{@docRoot}reference/android/content/RestrictionsManager.html#getApplicationRestrictions()"
><code>getApplicationRestrictions()</code></a> returns:
<ul>
<li><strong>A set of application-specific restrictions</strong>—You
- can configure the app restrictions silently (without requiring
+ can configure the managed configurations silently (without requiring
user input).</li>
<li><strong>An empty bundle</strong>—Your application acts like
it’s unmanaged (for example, how the app behaves in a personal
@@ -250,12 +250,12 @@
</ul>
</p>
-<h4>Listen for changes to app restrictions</h4>
+<h4>Listen for changes to managed configurations</h4>
<p>
- IT administrators can change app restrictions and what policies they
- want to enforce on their users at any time. Because of this, we
- recommend you ensure that your app can accept new restrictions as
- follows:
+ IT administrators can change managed configurations and what
+ policies they want to enforce on their users at any time. Because of
+ this, we recommend you ensure that your app can accept new
+ restrictions for your managed configuration as follows:
</p>
<ul>
@@ -318,7 +318,7 @@
</ol>
<p>
- A solution to both problems is to authenticate users using Chrome
+ A solution to both problems is to authenticate users using browser
Custom Tabs, instead of WebView. This ensures that authentication:
</p>
<ul>
@@ -335,19 +335,23 @@
<h3>Requirements</h3>
<p>
- Chrome Custom Tabs are supported using Platform APIs from API level
- 23 (Android 6.0), and support libraries back to API level 4 (Android
- 1.6). To implement Chrome Custom Tabs, you need to use a supported
- browser, such as Chrome 45 or later.
+ <a href="https://developer.android.com/topic/libraries/support-library/features.html#custom-tabs"
+ >Custom Tabs</a> are supported back to API level 15 (Android 4.0.3).
+ To use Custom Tabs you need a supported browser, such as Chrome.
+ Chrome 45 and later implement this feature as
+ <a href="https://developer.chrome.com/multidevice/android/customtabs">Chrome Custom Tabs</a>.
</p>
-<h3>How do I implement Chrome Custom Tabs?</h3>
+<h3>How do I implement SSO with Custom Tabs?</h3>
<p>
- Google, in conjunction with the OpenID Foundation, has published an
- open source library on GitHub. To set up Chrome Custom Tabs for SSO,
- see the <a href="https://github.com/openid/AppAuth-Android"
- >documentation and sample code on GitHub</a>.
+ Google has open sourced an OAuth client library that uses Custom
+ Tabs, contributing it to the OpenID Connect working group of the
+ OpenID Foundation. To set up Custom Tabs for SSO with the
+ AppAuth library, see the <a href="https://github.com/openid/AppAuth-Android"
+ >documentation and sample code on GitHub</a>, or try
+ <a href="https://codelabs.developers.google.com/codelabs/appauth-android-codelab/"
+ >the codelab</a>.
</p>
<h2 id="testing">Test your App with Android for Work</h2>
@@ -467,7 +471,7 @@
<li>Follow the onscreen instructions to set up your target device.</li>
<li>Once you’ve completed provisioning the device owner, you can test your app on that device. You
should specifically test how
- <a href="{@docRoot}work/app-restrictions.html">app restrictions</a>,
+ <a href="{@docRoot}work/managed-configurations.html">managed configurations</a>,
<a href="{@docRoot}work/managed-profiles.html#sharing_files">URIs</a>, and
<a href="{@docRoot}work/managed-profiles.html#prevent_failed_intents">intents</a>
work on that device.</li>
@@ -484,7 +488,7 @@
<ul>
<li>App distribution through Play</li>
- <li>Server-side app restriction configuration</li>
+ <li>Server-side managed configuration</li>
<li>Server-side profile policy control</li>
</ul>
@@ -510,7 +514,7 @@
<ol>
<li>Set up work devices.</li>
<li>Distribute your application.</li>
- <li>Set application restrictions.</li>
+ <li>Set managed configuration.</li>
<li>Set device policies.</li>
</ol>
</ol>
diff --git a/docs/html/work/managed-configurations.jd b/docs/html/work/managed-configurations.jd
new file mode 100644
index 0000000..dc3ef0d
--- /dev/null
+++ b/docs/html/work/managed-configurations.jd
@@ -0,0 +1,355 @@
+page.title=Set up Managed Configurations
+page.metaDescription=Learn how to implement managed configurations that can be changed by other apps on the same device.
+page.image=images/work/cards/briefcase_600px.png
+
+@jd:body
+
+<div id="qv-wrapper">
+ <div id="qv">
+ <h2>In this document</h2>
+ <ol>
+ <li><a href="#define-configuration">Define Managed Configurations</a></li>
+ <li><a href="#check-configuration">Check Managed Configurations</a></li>
+ <li><a href="#listen-configuration">Listen for Managed Configuration Changes</a></li>
+ </ol>
+ </div>
+</div>
+
+<p>
+ If you are developing apps for the enterprise market, you may need
+ to satisfy particular requirements set by a company's policies.
+ Managed configurations, previously known as <em>application restrictions</em>,
+ allow the enterprise administrator to remotely specify settings for
+ apps. This capability is particularly useful for enterprise-approved
+ apps deployed to a managed profile.
+</p>
+
+<p>For example, an enterprise might require that approved apps allow the
+enterprise administrator to:</p>
+
+<ul>
+ <li>Whitelist or blacklist URLs for a web browser</li>
+ <li>Configure whether an app is allowed to sync content via cellular, or just
+ by Wi-Fi</li>
+ <li>Configure the app's email settings</li>
+</ul>
+
+<p>
+ This guide shows how to implement these configuration settings in your app.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> For historical reasons, these configuration settings are known as
+ <em>restrictions,</em> and are implemented with files and classes that use this
+ term (such as {@link android.content.RestrictionsManager}). However, these
+ restrictions can actually implement a wide range of configuration options,
+ not just restrictions on app functionality.
+</p>
+
+<h2 id="overview">
+ Remote Configuration Overview
+</h2>
+
+<p>
+ Apps define the managed configuration options that can be remotely
+ set by an administrator. These are arbitrary settings that can be
+ changed by a managed configuration provider. If your app is running on an
+ enterprise device's managed profile, the enterprise administrator
+ can change your app's managed configuration.
+</p>
+
+<p>
+ The managed configurations provider is another app running on the same device.
+ This app is typically controlled by the enterprise administrator. The
+ enterprise administrator communicates configuration changes to the managed
+ configuration provider app. That app, in turn, changes the configurations on your app.
+</p>
+
+<p>
+ To provide externally managed configurations:
+</p>
+
+<ul>
+ <li>Declare the managed configurations in your app manifest. Doing
+ so allows the enterprise administrator to read the app's
+ configurations through Google Play APIs.
+ </li>
+
+ <li>Whenever the app resumes, use the {@link
+ android.content.RestrictionsManager} object to check the current
+ managed configurations, and change your app's UI and behavior to
+ conform with those configurations.
+ </li>
+
+ <li>Listen for the
+ {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
+ ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. When you receive this
+ broadcast, check the {@link android.content.RestrictionsManager} to see what
+ the current managed configurations are, and make any necessary changes to your
+ app's behavior.
+ </li>
+</ul>
+
+<h2 id="define-configuration">
+ Define Managed Configurations
+</h2>
+
+<p>
+ Your app can support any managed configuration you want to define. You declare the
+ app's managed configurations in a <em>managed configurations file</em>, and declare the
+ configurations file in the manifest. Creating a configurations file allows other
+ apps to examine the managed configurations your app provides. Enterprise Mobility
+ Management (EMM) partners can read your app's configurations by using Google
+ Play APIs.
+</p>
+
+<p>
+ To define your app's remote configuration options, put the following element
+ in your manifest's
+ <a href="{@docRoot}guide/topics/manifest/application-element.html">
+ <code><application></code></a> element:
+</p>
+
+<pre><meta-data android:name="android.content.APP_RESTRICTIONS"
+ android:resource="@xml/app_restrictions" />
+</pre>
+
+<p>
+ Create a file named <code>app_restrictions.xml</code> in your app's
+ <code>res/xml</code> directory. The structure of that file is described in
+ the reference for {@link android.content.RestrictionsManager}. The file has a
+ single top-level <code><restrictions></code> element, which contains
+ one <code><restriction></code> child element for every configuration
+ option the app has.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> Do not create localized versions of the
+ managed configuration file. Your app is only allowed to have a
+ single managed configurations file, so configurations will be
+ consistent for your app in all locales.
+</p>
+
+<p>
+ In an enterprise environment, an EMM will typically use the managed
+ configuration schema to generate a remote console for IT
+ administrators, so the administrators can remotely configure your
+ application.
+</p>
+
+<p>
+ For example, suppose your app can be remotely configured to allow or forbid
+ it to download data over a cellular connection. Your app could have a
+ <code><restriction></code> element like this:
+</p>
+
+<pre>
+<?xml version="1.0" encoding="utf-8"?>
+<restrictions xmlns:android="http://schemas.android.com/apk/res/android" >
+
+ <restriction
+ android:key="downloadOnCellular"
+ android:title="App is allowed to download data via cellular"
+ android:restrictionType="bool"
+ android:description="If 'false', app can only download data via Wi-Fi"
+ android:defaultValue="true" />
+
+</restrictions>
+</pre>
+
+<p>
+ The supported types for the <code>android:restrictionType</code> element are
+ documented in the reference for {@link android.content.RestrictionsManager}.
+</p>
+
+<p>
+ You use each configuration's <code>android:key</code> attribute to
+ read its value from a managed configuration bundle. For this reason,
+ each configuration must have a unique key string, and the string
+ <em>cannot</em> be localized. It must be specified with a string literal.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> In a production app, <code>android:title</code> and
+ <code>android:description</code> should be drawn from a localized resource
+ file, as described in <a href=
+ "{@docRoot}guide/topics/resources/localization.html">Localizing with
+ Resources</a>.
+</p>
+
+<p>
+ The managed configuration provider can query the app to find details
+ on the app's available configurations, including their description
+ text. Configurations providers and enterprise administrators can
+ change your app's managed configurations at any time, even when the
+ app is not running.
+</p>
+
+<h2 id="check-configuration">
+ Check Managed Configurations
+</h2>
+
+<p>
+ Your app is not automatically notified when other apps change its
+ configuration settings. Instead, you need to check what the managed
+ configurations are when your app starts or resumes, and listen for a
+ system intent to find out if the configurations change while your
+ app is running.
+</p>
+
+<p>
+ To find out the current configuration settings, your app uses a
+ {@link android.content.RestrictionsManager} object. Your app should
+ check for the current managed configurations at the following times:
+</p>
+
+<ul>
+ <li>When the app starts or resumes, in its
+ {@link android.app.Activity#onResume onResume()} method
+ </li>
+
+ <li>When the app is notified of a configuration change, as described in
+ <a href="#listen-configuration">Listen for Managed Configuration
+ Changes</a>
+ </li>
+</ul>
+
+<p>
+ To get a {@link android.content.RestrictionsManager} object, get the current
+ activity with {@link android.app.Fragment#getActivity getActivity()}, then
+ call that activity's {@link android.app.Activity#getSystemService
+ Activity.getSystemService()} method:
+</p>
+
+<pre>RestrictionsManager myRestrictionsMgr =
+ (RestrictionsManager) getActivity()
+ .getSystemService(Context.RESTRICTIONS_SERVICE);</pre>
+
+<p>
+ Once you have a {@link android.content.RestrictionsManager}, you can get the
+ current configuration settings by calling its
+ {@link android.content.RestrictionsManager#getApplicationRestrictions
+ getApplicationRestrictions()} method:
+</p>
+
+<pre>Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();</pre>
+
+<p class="note">
+ <strong>Note:</strong> For convenience, you can also fetch the current
+ configurations with a {@link android.os.UserManager}, by calling
+ {@link android.os.UserManager#getApplicationRestrictions
+ UserManager.getApplicationRestrictions()}. This method behaves exactly the
+ same as {@link android.content.RestrictionsManager#getApplicationRestrictions
+ RestrictionsManager.getApplicationRestrictions()}.
+</p>
+
+<p>
+ The {@link android.content.RestrictionsManager#getApplicationRestrictions
+ getApplicationRestrictions()} method requires reading from data storage, so
+ it should be done sparingly. Do not call this method every time you need to
+ know the current configuration. Instead, you should call it once when your app
+ starts or resumes, and cache the fetched managed configurations bundle. Then listen
+ for the {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
+ ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent to find out if the configuration
+ change while your app is active, as described in
+ <a href="#listen-configuration">Listen for Managed Configuration Changes</a>.
+</p>
+
+<h3 id="read-configurations">
+ Reading and applying managed configurations
+</h3>
+
+<p>
+ The {@link android.content.RestrictionsManager#getApplicationRestrictions
+ getApplicationRestrictions()} method returns a {@link android.os.Bundle}
+ containing a key-value pair for each configuration that has been set. The
+ values are all of type <code>Boolean</code>, <code>int</code>,
+ <code>String</code>, and <code>String[]</code>. Once you have the
+ managed configurations {@link android.os.Bundle}, you can check the current
+ configuration settings with the standard {@link android.os.Bundle} methods for
+ those data types, such as {@link android.os.Bundle#getBoolean getBoolean()}
+ or
+ {@link android.os.Bundle#getString getString()}.
+</p>
+
+<p class="note">
+ <strong>Note:</strong> The managed configurations {@link android.os.Bundle}
+ contains one item for every configuration that has been explicitly set by a
+ managed configurations provider. However, you <em>cannot</em> assume that a
+ configuration will be present in the bundle just because you defined a default
+ value in the managed configurations XML file.
+</p>
+
+<p>
+ It is up to your app to take appropriate action based on the current
+ managed configuration settings. For example, if your app has a
+ configuration specifying whether it can download data over a
+ cellular connection, and you find that the configuration is set to
+ <code>false</code>, you would have to disable data download except when
+ the device has a Wi-Fi connection, as shown in the following example code:
+</p>
+
+<pre>
+boolean appCanUseCellular;
+
+if appRestrictions.containsKey("downloadOnCellular") {
+ appCanUseCellular = appRestrictions.getBoolean("downloadOnCellular");
+} else {
+ // here, cellularDefault is a boolean set with the restriction's
+ // default value
+ appCanUseCellular = cellularDefault;
+}
+
+if (!appCanUseCellular) {
+ // ...turn off app's cellular-download functionality
+ // ...show appropriate notices to user
+}</pre>
+
+<h2 id="listen-configuration">
+ Listen for Managed Configuration Changes
+</h2>
+
+<p>
+ Whenever an app's managed configurations are changed, the system fires the
+ {@link android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
+ ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent. Your app has to listen for
+ this intent so you can change the app's behavior when the configuration settings
+ change.</p>
+
+<p class="note">
+ <strong>Note:</strong> The {@link
+ android.content.Intent#ACTION_APPLICATION_RESTRICTIONS_CHANGED
+ ACTION_APPLICATION_RESTRICTIONS_CHANGED} intent is sent only to listeners
+ that are dynamically registered, <em>not</em> to listeners that are declared
+ in the app manifest.
+</p>
+<p>
+ The following code shows how to dynamically register a broadcast receiver for
+ this intent:
+</p>
+
+<pre>IntentFilter restrictionsFilter =
+ new IntentFilter(Intent.ACTION_APPLICATION_RESTRICTIONS_CHANGED);
+
+BroadcastReceiver restrictionsReceiver = new BroadcastReceiver() {
+ @Override public void onReceive(Context context, Intent intent) {
+
+ // Get the current configuration bundle
+ Bundle appRestrictions = myRestrictionsMgr.getApplicationRestrictions();
+
+ // Check current configuration settings, change your app's UI and
+ // functionality as necessary.
+ }
+};
+
+registerReceiver(restrictionsReceiver, restrictionsFilter);
+</pre>
+<p class="note">
+ <strong>Note:</strong> Ordinarily, your app does not need to be notified
+ about configuration changes when it is paused. Instead, you should unregister
+ your broadcast receiver when the app is paused. When the app resumes, you
+ first check for the current managed configurations (as discussed in
+ <a href="#check-configuration">Check Managed Configurations</a>), then register
+ your broadcast receiver to make sure you're notified about configuration changes
+ that happen while the app is active.
+</p>
diff --git a/docs/html/work/work_toc.cs b/docs/html/work/work_toc.cs
deleted file mode 100644
index 10658c2..0000000
--- a/docs/html/work/work_toc.cs
+++ /dev/null
@@ -1,44 +0,0 @@
-<ul id="nav">
-
- <li class="nav-section">
- <div class="nav-section-header empty">
- <a href="<?cs var:toroot ?>work/index.html">
- Android for Work Home</a>
- </div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty">
- <a href="<?cs var:toroot ?>work/overview.html">
- Overview</a>
- </div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty">
- <a href="<?cs var:toroot ?>work/guide.html">
- Developer Guide</a>
- </div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty">
- <a href="<?cs var:toroot ?>work/managed-profiles.html">
- Set up Managed Profiles</a></div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty">
- <a href="<?cs var:toroot ?>work/app-restrictions.html">
- Set up App Restrictions</a>
- </div>
- </li>
-
- <li class="nav-section">
- <div class="nav-section-header empty">
- <a href="<?cs var:toroot ?>work/cosu.html">
- Set up Single-Purpose Devices</a>
- </div>
- </li>
-
-</ul>
diff --git a/libs/hwui/BakedOpDispatcher.cpp b/libs/hwui/BakedOpDispatcher.cpp
index 59c1065..8b3f172 100644
--- a/libs/hwui/BakedOpDispatcher.cpp
+++ b/libs/hwui/BakedOpDispatcher.cpp
@@ -805,27 +805,21 @@
// Note that we don't use op->paint in this function - it's never set on a LayerOp
OffscreenBuffer* buffer = *op.layerHandle;
- if (CC_UNLIKELY(!buffer)) {
- // Layer was not allocated, which can occur if there were no draw ops inside. We draw the
- // equivalent by drawing a rect with the same layer properties (alpha/xfer/filter).
- int color = SkColorSetA(SK_ColorTRANSPARENT, op.alpha * 255);
- renderRectForLayer(renderer, op, state,
- color, op.mode, op.colorFilter);
- } else {
- float layerAlpha = op.alpha * state.alpha;
- Glop glop;
- GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
- .setRoundRectClipState(state.roundRectClipState)
- .setMeshTexturedIndexedVbo(buffer->vbo, buffer->elementCount)
- .setFillLayer(buffer->texture, op.colorFilter, layerAlpha, op.mode, Blend::ModeOrderSwap::NoSwap)
- .setTransform(state.computedState.transform, TransformFlags::None)
- .setModelViewOffsetRectSnap(op.unmappedBounds.left, op.unmappedBounds.top,
- Rect(op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight()))
- .build();
- renderer.renderGlop(state, glop);
- }
+ if (CC_UNLIKELY(!buffer)) return;
- if (buffer && !buffer->hasRenderedSinceRepaint) {
+ float layerAlpha = op.alpha * state.alpha;
+ Glop glop;
+ GlopBuilder(renderer.renderState(), renderer.caches(), &glop)
+ .setRoundRectClipState(state.roundRectClipState)
+ .setMeshTexturedIndexedVbo(buffer->vbo, buffer->elementCount)
+ .setFillLayer(buffer->texture, op.colorFilter, layerAlpha, op.mode, Blend::ModeOrderSwap::NoSwap)
+ .setTransform(state.computedState.transform, TransformFlags::None)
+ .setModelViewOffsetRectSnap(op.unmappedBounds.left, op.unmappedBounds.top,
+ Rect(op.unmappedBounds.getWidth(), op.unmappedBounds.getHeight()))
+ .build();
+ renderer.renderGlop(state, glop);
+
+ if (!buffer->hasRenderedSinceRepaint) {
buffer->hasRenderedSinceRepaint = true;
if (CC_UNLIKELY(Properties::debugLayersUpdates)) {
// render debug layer highlight
diff --git a/libs/hwui/BakedOpRenderer.cpp b/libs/hwui/BakedOpRenderer.cpp
index eed0126..ea2e15b 100644
--- a/libs/hwui/BakedOpRenderer.cpp
+++ b/libs/hwui/BakedOpRenderer.cpp
@@ -96,15 +96,15 @@
}
OffscreenBuffer* BakedOpRenderer::copyToLayer(const Rect& area) {
- OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState,
- area.getWidth(), area.getHeight());
- if (!area.isEmpty()) {
+ const uint32_t width = area.getWidth();
+ const uint32_t height = area.getHeight();
+ OffscreenBuffer* buffer = mRenderState.layerPool().get(mRenderState, width, height);
+ if (!area.isEmpty() && width != 0 && height != 0) {
mCaches.textureState().activateTexture(0);
mCaches.textureState().bindTexture(buffer->texture.id());
glCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0,
- area.left, mRenderTarget.viewportHeight - area.bottom,
- area.getWidth(), area.getHeight());
+ area.left, mRenderTarget.viewportHeight - area.bottom, width, height);
}
return buffer;
}
diff --git a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
index 01d3d70..6b7b721 100644
--- a/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
+++ b/libs/hwui/tests/unit/BakedOpDispatcherTests.cpp
@@ -53,7 +53,7 @@
typedef void (*TestBakedOpReceiver)(BakedOpRenderer&, const BakedOpState&);
static void testUnmergedGlopDispatch(renderthread::RenderThread& renderThread, RecordedOp* op,
- std::function<void(const Glop& glop)> glopVerifier) {
+ std::function<void(const Glop& glop)> glopVerifier, int expectedGlopCount = 1) {
// Create op, and wrap with basic state.
LinearAllocator allocator;
auto snapshot = TestUtils::makeSnapshot(Matrix4::identity(), Rect(100, 100));
@@ -61,8 +61,8 @@
ASSERT_NE(nullptr, state);
int glopCount = 0;
- auto glopReceiver = [&glopVerifier, &glopCount] (const Glop& glop) {
- ASSERT_EQ(glopCount++, 0) << "Only one Glop expected";
+ auto glopReceiver = [&glopVerifier, &glopCount, &expectedGlopCount] (const Glop& glop) {
+ ASSERT_LE(glopCount++, expectedGlopCount) << expectedGlopCount << "glop(s) expected";
glopVerifier(glop);
};
ValidatingBakedOpRenderer renderer(renderThread.renderState(), glopReceiver);
@@ -75,7 +75,8 @@
static TestBakedOpReceiver unmergedReceivers[] = BUILD_RENDERABLE_OP_LUT(X);
#undef X
unmergedReceivers[op->opId](renderer, *state);
- ASSERT_EQ(1, glopCount) << "Exactly one Glop expected";
+ ASSERT_EQ(expectedGlopCount, glopCount) << "Exactly " << expectedGlopCount
+ << "Glop(s) expected";
}
RENDERTHREAD_TEST(BakedOpDispatcher, pathTexture_positionOvalArc) {
@@ -119,12 +120,8 @@
OffscreenBuffer* buffer = nullptr; // no providing a buffer, should hit rect fallback case
LayerOp op(Rect(10, 10), Matrix4::identity(), nullptr, &layerPaint, &buffer);
testUnmergedGlopDispatch(renderThread, &op, [&renderThread] (const Glop& glop) {
- // rect glop is dispatched with paint props applied
- EXPECT_EQ(renderThread.renderState().meshState().getUnitQuadVBO(),
- glop.mesh.vertices.bufferObject) << "Unit quad should be drawn";
- EXPECT_EQ(nullptr, glop.fill.texture.texture) << "Should be no texture when layer is null";
- EXPECT_FLOAT_EQ(128 / 255.0f, glop.fill.color.a) << "Rect quad should use op alpha";
- });
+ ADD_FAILURE() << "Nothing should happen";
+ }, 0);
}
static int getGlopTransformFlags(renderthread::RenderThread& renderThread, RecordedOp* op) {
diff --git a/media/java/android/media/MediaCodecInfo.java b/media/java/android/media/MediaCodecInfo.java
index 349d67e..45d0cc0 100644
--- a/media/java/android/media/MediaCodecInfo.java
+++ b/media/java/android/media/MediaCodecInfo.java
@@ -591,7 +591,12 @@
}
}
levelCaps = createFromProfileLevel(mMime, profile, maxLevel);
- if (levelCaps != null && !levelCaps.isFormatSupported(format)) {
+ // remove profile from this format otherwise levelCaps.isFormatSupported will
+ // get into this same conditon and loop forever.
+ Map<String, Object> mapWithoutProfile = new HashMap<>(map);
+ mapWithoutProfile.remove(MediaFormat.KEY_PROFILE);
+ MediaFormat formatWithoutProfile = new MediaFormat(mapWithoutProfile);
+ if (levelCaps != null && !levelCaps.isFormatSupported(formatWithoutProfile)) {
return false;
}
}
@@ -646,6 +651,27 @@
continue;
}
}
+
+ // MPEG4 levels are not completely ordered:
+ // Level1 support only implies Level0 (and not Level0b) support
+ if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_MPEG4)) {
+ if (pl.level != level && pl.level == CodecProfileLevel.MPEG4Level1
+ && level > CodecProfileLevel.MPEG4Level0) {
+ continue;
+ }
+ }
+
+ // HEVC levels incorporate both tiers and levels. Verify tier support.
+ if (mMime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
+ boolean supportsHighTier =
+ (pl.level & CodecProfileLevel.HEVCHighTierLevels) != 0;
+ boolean checkingHighTier = (level & CodecProfileLevel.HEVCHighTierLevels) != 0;
+ // high tier levels are only supported by other high tier levels
+ if (checkingHighTier && !supportsHighTier) {
+ continue;
+ }
+ }
+
if (pl.level >= level) {
// if we recognize the listed profile/level, we must also recognize the
// profile/level arguments.
@@ -745,6 +771,9 @@
* Retrieve the codec capabilities for a certain {@code mime type}, {@code
* profile} and {@code level}. If the type, or profile-level combination
* is not understood by the framework, it returns null.
+ * <p class=note> In {@link android.os.Build.VERSION_CODES#M}, calling this
+ * method without calling any method of the {@link MediaCodecList} class beforehand
+ * results in a {@link NullPointerException}.</p>
*/
public static CodecCapabilities createFromProfileLevel(
String mime, int profile, int level) {
@@ -1124,6 +1153,8 @@
private int mHeightAlignment;
private int mSmallerDimensionUpperLimit;
+ private boolean mAllowMbOverride; // allow XML to override calculated limits
+
/**
* Returns the range of supported bitrates in bits/second.
*/
@@ -1688,7 +1719,7 @@
Long.MAX_VALUE, blockSize.getWidth(), blockSize.getHeight(),
alignment.getWidth(), alignment.getHeight());
- if ((mParent.mError & ERROR_UNSUPPORTED) != 0) {
+ if ((mParent.mError & ERROR_UNSUPPORTED) != 0 || mAllowMbOverride) {
// codec supports profiles that we don't know.
// Use supplied values clipped to platform limits
if (widths != null) {
@@ -1720,7 +1751,12 @@
mFrameRateRange = FRAME_RATE_RANGE.intersect(frameRates);
}
if (bitRates != null) {
- mBitrateRange = BITRATE_RANGE.intersect(bitRates);
+ // only allow bitrate override if unsupported profiles were encountered
+ if ((mParent.mError & ERROR_UNSUPPORTED) != 0) {
+ mBitrateRange = BITRATE_RANGE.intersect(bitRates);
+ } else {
+ mBitrateRange = mBitrateRange.intersect(bitRates);
+ }
}
} else {
// no unsupported profile/levels, so restrict values to known limits
@@ -1875,6 +1911,19 @@
int maxBlocks, long maxBlocksPerSecond,
int blockWidth, int blockHeight,
int widthAlignment, int heightAlignment) {
+ applyMacroBlockLimits(
+ 1 /* minHorizontalBlocks */, 1 /* minVerticalBlocks */,
+ maxHorizontalBlocks, maxVerticalBlocks,
+ maxBlocks, maxBlocksPerSecond,
+ blockWidth, blockHeight, widthAlignment, heightAlignment);
+ }
+
+ private void applyMacroBlockLimits(
+ int minHorizontalBlocks, int minVerticalBlocks,
+ int maxHorizontalBlocks, int maxVerticalBlocks,
+ int maxBlocks, long maxBlocksPerSecond,
+ int blockWidth, int blockHeight,
+ int widthAlignment, int heightAlignment) {
applyAlignment(widthAlignment, heightAlignment);
applyBlockLimits(
blockWidth, blockHeight, Range.create(1, maxBlocks),
@@ -1884,10 +1933,12 @@
new Rational(maxHorizontalBlocks, 1)));
mHorizontalBlockRange =
mHorizontalBlockRange.intersect(
- 1, maxHorizontalBlocks / (mBlockWidth / blockWidth));
+ Utils.divUp(minHorizontalBlocks, (mBlockWidth / blockWidth)),
+ maxHorizontalBlocks / (mBlockWidth / blockWidth));
mVerticalBlockRange =
mVerticalBlockRange.intersect(
- 1, maxVerticalBlocks / (mBlockHeight / blockHeight));
+ Utils.divUp(minVerticalBlocks, (mBlockHeight / blockHeight)),
+ maxVerticalBlocks / (mBlockHeight / blockHeight));
}
private void applyLevelLimits() {
@@ -1997,7 +2048,7 @@
case CodecProfileLevel.MPEG2ProfileSimple:
switch (profileLevel.level) {
case CodecProfileLevel.MPEG2LevelML:
- FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 15000; break;
+ FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 15000; break;
default:
Log.w(TAG, "Unrecognized profile/level "
+ profileLevel.profile + "/"
@@ -2010,7 +2061,7 @@
case CodecProfileLevel.MPEG2LevelLL:
FR = 30; W = 22; H = 18; MBPS = 11880; FS = 396; BR = 4000; break;
case CodecProfileLevel.MPEG2LevelML:
- FR = 30; W = 45; H = 36; MBPS = 48600; FS = 1620; BR = 15000; break;
+ FR = 30; W = 45; H = 36; MBPS = 40500; FS = 1620; BR = 15000; break;
case CodecProfileLevel.MPEG2LevelH14:
FR = 60; W = 90; H = 68; MBPS = 183600; FS = 6120; BR = 60000; break;
case CodecProfileLevel.MPEG2LevelHL:
@@ -2060,16 +2111,19 @@
maxBps = 64000;
for (CodecProfileLevel profileLevel: profileLevels) {
int MBPS = 0, FS = 0, BR = 0, FR = 0, W = 0, H = 0;
+ boolean strict = false; // true: W, H and FR are individual max limits
boolean supported = true;
switch (profileLevel.profile) {
case CodecProfileLevel.MPEG4ProfileSimple:
switch (profileLevel.level) {
case CodecProfileLevel.MPEG4Level0:
+ strict = true;
FR = 15; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 64; break;
case CodecProfileLevel.MPEG4Level1:
FR = 30; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 64; break;
case CodecProfileLevel.MPEG4Level0b:
- FR = 30; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 128; break;
+ strict = true;
+ FR = 15; W = 11; H = 9; MBPS = 1485; FS = 99; BR = 128; break;
case CodecProfileLevel.MPEG4Level2:
FR = 30; W = 22; H = 18; MBPS = 5940; FS = 396; BR = 128; break;
case CodecProfileLevel.MPEG4Level3:
@@ -2117,11 +2171,16 @@
case CodecProfileLevel.MPEG4ProfileCore: // 1-2
case CodecProfileLevel.MPEG4ProfileAdvancedCore: // 1-4
case CodecProfileLevel.MPEG4ProfileSimpleScalable: // 0-2
- case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3
case CodecProfileLevel.MPEG4ProfileHybrid: // 1-2
+
+ // Studio profiles are not supported by our codecs.
+
+ // Only profiles that can decode simple object types are considered.
+ // The following profiles are not able to.
case CodecProfileLevel.MPEG4ProfileBasicAnimated: // 1-2
case CodecProfileLevel.MPEG4ProfileScalableTexture: // 1
case CodecProfileLevel.MPEG4ProfileSimpleFace: // 1-2
+ case CodecProfileLevel.MPEG4ProfileAdvancedScalable: // 1-3
case CodecProfileLevel.MPEG4ProfileSimpleFBA: // 1-2
Log.i(TAG, "Unsupported profile "
+ profileLevel.profile + " for " + mime);
@@ -2139,9 +2198,17 @@
maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
maxBlocks = Math.max(FS, maxBlocks);
maxBps = Math.max(BR * 1000, maxBps);
- maxWidth = Math.max(W, maxWidth);
- maxHeight = Math.max(H, maxHeight);
- maxRate = Math.max(FR, maxRate);
+ if (strict) {
+ maxWidth = Math.max(W, maxWidth);
+ maxHeight = Math.max(H, maxHeight);
+ maxRate = Math.max(FR, maxRate);
+ } else {
+ // assuming max 60 fps frame rate and 1:2 aspect ratio
+ int maxDim = (int)Math.sqrt(FS * 2);
+ maxWidth = Math.max(maxDim, maxWidth);
+ maxHeight = Math.max(maxDim, maxHeight);
+ maxRate = Math.max(Math.max(FR, 60), maxRate);
+ }
}
applyMacroBlockLimits(maxWidth, maxHeight,
maxBlocks, maxBlocksPerSecond,
@@ -2150,34 +2217,47 @@
mFrameRateRange = mFrameRateRange.intersect(12, maxRate);
} else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_H263)) {
int maxWidth = 11, maxHeight = 9, maxRate = 15;
+ int minWidth = maxWidth, minHeight = maxHeight;
+ int minAlignment = 16;
maxBlocks = 99;
maxBlocksPerSecond = 1485;
maxBps = 64000;
for (CodecProfileLevel profileLevel: profileLevels) {
- int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0;
+ int MBPS = 0, BR = 0, FR = 0, W = 0, H = 0, minW = minWidth, minH = minHeight;
+ boolean strict = false; // true: support only sQCIF, QCIF (maybe CIF)
switch (profileLevel.level) {
case CodecProfileLevel.H263Level10:
+ strict = true; // only supports sQCIF & QCIF
FR = 15; W = 11; H = 9; BR = 1; MBPS = W * H * FR; break;
case CodecProfileLevel.H263Level20:
- // only supports CIF, 0..QCIF
- FR = 30; W = 22; H = 18; BR = 2; MBPS = W * H * FR; break;
+ strict = true; // only supports sQCIF, QCIF & CIF
+ FR = 30; W = 22; H = 18; BR = 2; MBPS = W * H * 15; break;
case CodecProfileLevel.H263Level30:
- // only supports CIF, 0..QCIF
+ strict = true; // only supports sQCIF, QCIF & CIF
FR = 30; W = 22; H = 18; BR = 6; MBPS = W * H * FR; break;
case CodecProfileLevel.H263Level40:
- // only supports CIF, 0..QCIF
+ strict = true; // only supports sQCIF, QCIF & CIF
FR = 30; W = 22; H = 18; BR = 32; MBPS = W * H * FR; break;
case CodecProfileLevel.H263Level45:
// only implies level 10 support
- FR = 30; W = 11; H = 9; BR = 2; MBPS = W * H * FR; break;
+ strict = profileLevel.profile == CodecProfileLevel.H263ProfileBaseline
+ || profileLevel.profile ==
+ CodecProfileLevel.H263ProfileBackwardCompatible;
+ if (!strict) {
+ minW = 1; minH = 1; minAlignment = 4;
+ }
+ FR = 15; W = 11; H = 9; BR = 2; MBPS = W * H * FR; break;
case CodecProfileLevel.H263Level50:
// only supports 50fps for H > 15
+ minW = 1; minH = 1; minAlignment = 4;
FR = 60; W = 22; H = 18; BR = 64; MBPS = W * H * 50; break;
case CodecProfileLevel.H263Level60:
// only supports 50fps for H > 15
+ minW = 1; minH = 1; minAlignment = 4;
FR = 60; W = 45; H = 18; BR = 128; MBPS = W * H * 50; break;
case CodecProfileLevel.H263Level70:
// only supports 50fps for H > 30
+ minW = 1; minH = 1; minAlignment = 4;
FR = 60; W = 45; H = 36; BR = 256; MBPS = W * H * 50; break;
default:
Log.w(TAG, "Unrecognized profile/level " + profileLevel.profile
@@ -2200,6 +2280,18 @@
+ profileLevel.profile + " for " + mime);
errors |= ERROR_UNRECOGNIZED;
}
+ if (strict) {
+ // Strict levels define sub-QCIF min size and enumerated sizes. We cannot
+ // express support for "only sQCIF & QCIF (& CIF)" using VideoCapabilities
+ // but we can express "only QCIF (& CIF)", so set minimume size at QCIF.
+ // minW = 8; minH = 6;
+ minW = 11; minH = 9;
+ } else {
+ // any support for non-strict levels (including unrecognized profiles or
+ // levels) allow custom frame size support beyond supported limits
+ // (other than bitrate)
+ mAllowMbOverride = true;
+ }
errors &= ~ERROR_NONE_SUPPORTED;
maxBlocksPerSecond = Math.max(MBPS, maxBlocksPerSecond);
maxBlocks = Math.max(W * H, maxBlocks);
@@ -2207,11 +2299,21 @@
maxWidth = Math.max(W, maxWidth);
maxHeight = Math.max(H, maxHeight);
maxRate = Math.max(FR, maxRate);
+ minWidth = Math.min(minW, minWidth);
+ minHeight = Math.min(minH, minHeight);
}
- applyMacroBlockLimits(maxWidth, maxHeight,
+ // unless we encountered custom frame size support, limit size to QCIF and CIF
+ // using aspect ratio.
+ if (!mAllowMbOverride) {
+ mBlockAspectRatioRange =
+ Range.create(new Rational(11, 9), new Rational(11, 9));
+ }
+ applyMacroBlockLimits(
+ minWidth, minHeight,
+ maxWidth, maxHeight,
maxBlocks, maxBlocksPerSecond,
16 /* blockWidth */, 16 /* blockHeight */,
- 1 /* widthAlignment */, 1 /* heightAlignment */);
+ minAlignment /* widthAlignment */, minAlignment /* heightAlignment */);
mFrameRateRange = Range.create(1, maxRate);
} else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_VP8)) {
maxBlocks = Integer.MAX_VALUE;
@@ -2299,6 +2401,8 @@
case CodecProfileLevel.VP9Profile1:
case CodecProfileLevel.VP9Profile2:
case CodecProfileLevel.VP9Profile3:
+ case CodecProfileLevel.VP9Profile2HDR:
+ case CodecProfileLevel.VP9Profile3HDR:
break;
default:
Log.w(TAG, "Unrecognized profile "
@@ -2323,7 +2427,8 @@
blockSize, blockSize,
1 /* widthAlignment */, 1 /* heightAlignment */);
} else if (mime.equalsIgnoreCase(MediaFormat.MIMETYPE_VIDEO_HEVC)) {
- maxBlocks = 36864;
+ // CTBs are at least 8x8 so use 8x8 block size
+ maxBlocks = 36864 >> 6; // 192x192 pixels == 576 8x8 blocks
maxBlocksPerSecond = maxBlocks * 15;
maxBps = 128000;
for (CodecProfileLevel profileLevel: profileLevels) {
@@ -2331,6 +2436,10 @@
int FS = 0;
int BR = 0;
switch (profileLevel.level) {
+ /* The HEVC spec talks only in a very convoluted manner about the
+ existence of levels 1-3.1 for High tier, which could also be
+ understood as 'decoders and encoders should treat these levels
+ as if they were Main tier', so we do that. */
case CodecProfileLevel.HEVCMainTierLevel1:
case CodecProfileLevel.HEVCHighTierLevel1:
FR = 15; FS = 36864; BR = 128; break;
@@ -2401,6 +2510,7 @@
else DPB = 6;
*/
+ FS >>= 6; // convert pixels to blocks
errors &= ~ERROR_NONE_SUPPORTED;
maxBlocksPerSecond = Math.max((int)(FR * FS), maxBlocksPerSecond);
maxBlocks = Math.max(FS, maxBlocks);
@@ -2408,11 +2518,6 @@
}
int maxLengthInBlocks = (int)(Math.sqrt(maxBlocks * 8));
- // CTBs are at least 8x8
- maxBlocks = Utils.divUp(maxBlocks, 8 * 8);
- maxBlocksPerSecond = Utils.divUp(maxBlocksPerSecond, 8 * 8);
- maxLengthInBlocks = Utils.divUp(maxLengthInBlocks, 8);
-
applyMacroBlockLimits(
maxLengthInBlocks, maxLengthInBlocks,
maxBlocks, maxBlocksPerSecond,
@@ -2826,6 +2931,12 @@
public static final int HEVCMainTierLevel62 = 0x1000000;
public static final int HEVCHighTierLevel62 = 0x2000000;
+ private static final int HEVCHighTierLevels =
+ HEVCHighTierLevel1 | HEVCHighTierLevel2 | HEVCHighTierLevel21 | HEVCHighTierLevel3 |
+ HEVCHighTierLevel31 | HEVCHighTierLevel4 | HEVCHighTierLevel41 | HEVCHighTierLevel5 |
+ HEVCHighTierLevel51 | HEVCHighTierLevel52 | HEVCHighTierLevel6 | HEVCHighTierLevel61 |
+ HEVCHighTierLevel62;
+
// from OMX_VIDEO_DOLBYVISIONPROFILETYPE
public static final int DolbyVisionProfileDvavPer = 0x1;
public static final int DolbyVisionProfileDvavPen = 0x2;
diff --git a/media/java/android/media/MediaCodecList.java b/media/java/android/media/MediaCodecList.java
index cd7b3d3..42ce511 100644
--- a/media/java/android/media/MediaCodecList.java
+++ b/media/java/android/media/MediaCodecList.java
@@ -63,6 +63,11 @@
}
/* package private */ static final Map<String, Object> getGlobalSettings() {
+ synchronized (sInitLock) {
+ if (sGlobalSettings == null) {
+ sGlobalSettings = native_getGlobalSettings();
+ }
+ }
return sGlobalSettings;
}
@@ -74,7 +79,6 @@
private static final void initCodecList() {
synchronized (sInitLock) {
if (sRegularCodecInfos == null) {
- sGlobalSettings = native_getGlobalSettings();
int count = native_getCodecCount();
ArrayList<MediaCodecInfo> regulars = new ArrayList<MediaCodecInfo>();
ArrayList<MediaCodecInfo> all = new ArrayList<MediaCodecInfo>();
diff --git a/media/java/android/media/MediaPlayer.java b/media/java/android/media/MediaPlayer.java
index cee7d60..3f6081b 100644
--- a/media/java/android/media/MediaPlayer.java
+++ b/media/java/android/media/MediaPlayer.java
@@ -2276,6 +2276,8 @@
Log.w(TAG, "addSubtitleSource called with null InputStream");
}
+ getMediaTimeProvider();
+
// process each subtitle in its own thread
final HandlerThread thread = new HandlerThread("SubtitleReadThread",
Process.THREAD_PRIORITY_BACKGROUND + Process.THREAD_PRIORITY_MORE_FAVORABLE);
@@ -2302,7 +2304,12 @@
synchronized (mIndexTrackPairs) {
mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
}
- track.onData(contents.getBytes(), true /* eos */, ~0 /* runID: keep forever */);
+ Handler h = mTimeProvider.mEventHandler;
+ int what = TimeProvider.NOTIFY;
+ int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+ Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, contents.getBytes());
+ Message m = h.obtainMessage(what, arg1, 0, trackData);
+ h.sendMessage(m);
return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
}
@@ -2501,6 +2508,8 @@
mIndexTrackPairs.add(Pair.<Integer, SubtitleTrack>create(null, track));
}
+ getMediaTimeProvider();
+
final FileDescriptor fd3 = fd2;
final long offset2 = offset;
final long length2 = length;
@@ -2526,7 +2535,12 @@
total += bytes;
}
}
- track.onData(bos.toByteArray(), true /* eos */, ~0 /* runID: keep forever */);
+ Handler h = mTimeProvider.mEventHandler;
+ int what = TimeProvider.NOTIFY;
+ int arg1 = TimeProvider.NOTIFY_TRACK_DATA;
+ Pair<SubtitleTrack, byte[]> trackData = Pair.create(track, bos.toByteArray());
+ Message m = h.obtainMessage(what, arg1, 0, trackData);
+ h.sendMessage(m);
return MEDIA_INFO_EXTERNAL_METADATA_UPDATE;
} catch (Exception e) {
Log.e(TAG, e.getMessage(), e);
@@ -3528,6 +3542,7 @@
private static final int REFRESH_AND_NOTIFY_TIME = 1;
private static final int NOTIFY_STOP = 2;
private static final int NOTIFY_SEEK = 3;
+ private static final int NOTIFY_TRACK_DATA = 4;
private HandlerThread mHandlerThread;
/** @hide */
@@ -3667,6 +3682,12 @@
}
}
+ private synchronized void notifyTrackData(Pair<SubtitleTrack, byte[]> trackData) {
+ SubtitleTrack track = trackData.first;
+ byte[] data = trackData.second;
+ track.onData(data, true /* eos */, ~0 /* runID: keep forever */);
+ }
+
private synchronized void notifyStop() {
for (MediaTimeProvider.OnMediaTimeListener listener: mListeners) {
if (listener == null) {
@@ -3899,6 +3920,9 @@
case NOTIFY_SEEK:
notifySeek();
break;
+ case NOTIFY_TRACK_DATA:
+ notifyTrackData((Pair<SubtitleTrack, byte[]>)msg.obj);
+ break;
}
}
}
diff --git a/media/java/android/media/tv/TvContract.java b/media/java/android/media/tv/TvContract.java
index 3a3460b..20706fd 100644
--- a/media/java/android/media/tv/TvContract.java
+++ b/media/java/android/media/tv/TvContract.java
@@ -372,76 +372,175 @@
/** The MIME type of a single TV channel. */
public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/channel";
- /** A generic channel type. */
+ /**
+ * A generic channel type.
+ *
+ * Use this if the current channel is streaming-based or its broadcast system type does not
+ * fit under any other types. This is the default channel type.
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_OTHER = "TYPE_OTHER";
- /** The channel type for NTSC. */
+ /**
+ * The channel type for NTSC.
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_NTSC = "TYPE_NTSC";
- /** The channel type for PAL. */
+ /**
+ * The channel type for PAL.
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_PAL = "TYPE_PAL";
- /** The channel type for SECAM. */
+ /**
+ * The channel type for SECAM.
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_SECAM = "TYPE_SECAM";
- /** The channel type for DVB-T (terrestrial). */
+ /**
+ * The channel type for DVB-T (terrestrial).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_DVB_T = "TYPE_DVB_T";
- /** The channel type for DVB-T2 (terrestrial). */
+ /**
+ * The channel type for DVB-T2 (terrestrial).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_DVB_T2 = "TYPE_DVB_T2";
- /** The channel type for DVB-S (satellite). */
+ /**
+ * The channel type for DVB-S (satellite).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_DVB_S = "TYPE_DVB_S";
- /** The channel type for DVB-S2 (satellite). */
+ /**
+ * The channel type for DVB-S2 (satellite).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_DVB_S2 = "TYPE_DVB_S2";
- /** The channel type for DVB-C (cable). */
+ /**
+ * The channel type for DVB-C (cable).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_DVB_C = "TYPE_DVB_C";
- /** The channel type for DVB-C2 (cable). */
+ /**
+ * The channel type for DVB-C2 (cable).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_DVB_C2 = "TYPE_DVB_C2";
- /** The channel type for DVB-H (handheld). */
+ /**
+ * The channel type for DVB-H (handheld).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_DVB_H = "TYPE_DVB_H";
- /** The channel type for DVB-SH (satellite). */
+ /**
+ * The channel type for DVB-SH (satellite).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_DVB_SH = "TYPE_DVB_SH";
- /** The channel type for ATSC (terrestrial). */
+ /**
+ * The channel type for ATSC (terrestrial).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_ATSC_T = "TYPE_ATSC_T";
- /** The channel type for ATSC (cable). */
+ /**
+ * The channel type for ATSC (cable).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_ATSC_C = "TYPE_ATSC_C";
- /** The channel type for ATSC-M/H (mobile/handheld). */
+ /**
+ * The channel type for ATSC-M/H (mobile/handheld).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_ATSC_M_H = "TYPE_ATSC_M_H";
- /** The channel type for ISDB-T (terrestrial). */
+ /**
+ * The channel type for ISDB-T (terrestrial).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_ISDB_T = "TYPE_ISDB_T";
- /** The channel type for ISDB-Tb (Brazil). */
+ /**
+ * The channel type for ISDB-Tb (Brazil).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_ISDB_TB = "TYPE_ISDB_TB";
- /** The channel type for ISDB-S (satellite). */
+ /**
+ * The channel type for ISDB-S (satellite).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_ISDB_S = "TYPE_ISDB_S";
- /** The channel type for ISDB-C (cable). */
+ /**
+ * The channel type for ISDB-C (cable).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_ISDB_C = "TYPE_ISDB_C";
- /** The channel type for 1seg (handheld). */
+ /**
+ * The channel type for 1seg (handheld).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_1SEG = "TYPE_1SEG";
- /** The channel type for DTMB (terrestrial). */
+ /**
+ * The channel type for DTMB (terrestrial).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_DTMB = "TYPE_DTMB";
- /** The channel type for CMMB (handheld). */
+ /**
+ * The channel type for CMMB (handheld).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_CMMB = "TYPE_CMMB";
- /** The channel type for T-DMB (terrestrial). */
+ /**
+ * The channel type for T-DMB (terrestrial).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_T_DMB = "TYPE_T_DMB";
- /** The channel type for S-DMB (satellite). */
+ /**
+ * The channel type for S-DMB (satellite).
+ *
+ * @see #COLUMN_TYPE
+ */
public static final String TYPE_S_DMB = "TYPE_S_DMB";
/** A generic service type. */
@@ -540,16 +639,35 @@
public static final String COLUMN_INPUT_ID = "input_id";
/**
- * The predefined type of this TV channel.
+ * The broadcast system type of this TV channel.
*
- * <p>This is primarily used to indicate which broadcast standard (e.g. ATSC, DVB or ISDB)
- * the current channel conforms to. The value should match to one of the followings:
- * {@link #TYPE_OTHER}, {@link #TYPE_DVB_T}, {@link #TYPE_DVB_T2}, {@link #TYPE_DVB_S},
- * {@link #TYPE_DVB_S2}, {@link #TYPE_DVB_C}, {@link #TYPE_DVB_C2}, {@link #TYPE_DVB_H},
- * {@link #TYPE_DVB_SH}, {@link #TYPE_ATSC_T}, {@link #TYPE_ATSC_C},
- * {@link #TYPE_ATSC_M_H}, {@link #TYPE_ISDB_T}, {@link #TYPE_ISDB_TB},
- * {@link #TYPE_ISDB_S}, {@link #TYPE_ISDB_C}, {@link #TYPE_1SEG}, {@link #TYPE_DTMB},
- * {@link #TYPE_CMMB}, {@link #TYPE_T_DMB}, {@link #TYPE_S_DMB}
+ * <p>This is used to indicate the broadcast standard (e.g. ATSC, DVB or ISDB) the current
+ * channel conforms to. Use {@link #TYPE_OTHER} for streaming-based channels, which is the
+ * default channel type. The value should match to one of the followings:
+ * {@link #TYPE_1SEG},
+ * {@link #TYPE_ATSC_C},
+ * {@link #TYPE_ATSC_M_H},
+ * {@link #TYPE_ATSC_T},
+ * {@link #TYPE_CMMB},
+ * {@link #TYPE_DTMB},
+ * {@link #TYPE_DVB_C},
+ * {@link #TYPE_DVB_C2},
+ * {@link #TYPE_DVB_H},
+ * {@link #TYPE_DVB_S},
+ * {@link #TYPE_DVB_S2},
+ * {@link #TYPE_DVB_SH},
+ * {@link #TYPE_DVB_T},
+ * {@link #TYPE_DVB_T2},
+ * {@link #TYPE_ISDB_C},
+ * {@link #TYPE_ISDB_S},
+ * {@link #TYPE_ISDB_T},
+ * {@link #TYPE_ISDB_TB},
+ * {@link #TYPE_NTSC},
+ * {@link #TYPE_OTHER},
+ * {@link #TYPE_PAL},
+ * {@link #TYPE_SECAM},
+ * {@link #TYPE_S_DMB}, and
+ * {@link #TYPE_T_DMB}.
*
* <p>This is a required field.
*
diff --git a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
index c8719f3..8d6e07e 100644
--- a/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
+++ b/packages/Keyguard/src/com/android/keyguard/KeyguardPinBasedInputView.java
@@ -239,8 +239,7 @@
@Override
public boolean onKey(View v, int keyCode, KeyEvent event) {
if (event.getAction() == KeyEvent.ACTION_DOWN) {
- onKeyDown(keyCode, event);
- return true;
+ return onKeyDown(keyCode, event);
}
return false;
}
diff --git a/packages/PrintRecommendationService/res/values/donottranslate.xml b/packages/PrintRecommendationService/res/values/donottranslate.xml
index 86027cd..e9b97a3 100644
--- a/packages/PrintRecommendationService/res/values/donottranslate.xml
+++ b/packages/PrintRecommendationService/res/values/donottranslate.xml
@@ -32,12 +32,20 @@
<item>Hewlett Packard</item>
</string-array>
+ <!-- Samsung plugin -->
<string-array name="known_print_vendor_info_for_samsung" translatable="false">
<item>com.sec.app.samsungprintservice</item>
<item>Samsung Electronics</item>
<item>Samsung</item>
</string-array>
+ <!-- Xerox plugin -->
+ <string-array name="known_print_vendor_info_for_xerox" translatable="false">
+ <item>com.xerox.printservice</item>
+ <item>Xerox</item>
+ <item>Xerox</item>
+ </string-array>
+
<array name="known_print_plugin_vendors" translatable="false">
<item>@array/known_print_vendor_info_for_mopria</item>
<item>@array/known_print_vendor_info_for_hp</item>
diff --git a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
index 108ea66..52889ce 100644
--- a/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
+++ b/packages/PrintRecommendationService/res/xml/vendorconfigs.xml
@@ -43,14 +43,6 @@
</vendor>
<vendor>
- <name>@string/plugin_vendor_xerox</name>
- <package>com.xerox.printservice</package>
- <mdns-names>
- <mdns-name>Xerox</mdns-name>
- </mdns-names>
- </vendor>
-
- <vendor>
<name>@string/plugin_vendor_epson</name>
<package>com.epson.mobilephone.android.epsonprintserviceplugin</package>
<mdns-names>
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
index d95654f..ac60a88 100644
--- a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/RecommendationServiceImpl.java
@@ -26,6 +26,7 @@
import com.android.printservice.recommendation.plugin.mdnsFilter.VendorConfig;
import com.android.printservice.recommendation.plugin.mopria.MopriaRecommendationPlugin;
import com.android.printservice.recommendation.plugin.samsung.SamsungRecommendationPlugin;
+import com.android.printservice.recommendation.plugin.xerox.XeroxPrintServiceRecommendationPlugin;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
@@ -83,6 +84,14 @@
" plugin", e);
}
+ try {
+ mPlugins.add(new RemotePrintServicePlugin(
+ new XeroxPrintServiceRecommendationPlugin(this), this, false));
+ } catch (Exception e) {
+ Log.e(LOG_TAG, "Could not initiate " + getString(R.string.plugin_vendor_xerox) +
+ " plugin", e);
+ }
+
final int numPlugins = mPlugins.size();
for (int i = 0; i < numPlugins; i++) {
try {
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/MDnsUtils.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/MDnsUtils.java
new file mode 100755
index 0000000..7a2d0d8
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/MDnsUtils.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.printservice.recommendation.plugin.xerox;
+
+import android.net.nsd.NsdServiceInfo;
+import android.text.TextUtils;
+
+import java.nio.charset.StandardCharsets;
+import java.util.Locale;
+import java.util.Map;
+
+class MDnsUtils {
+ public static final String ATTRIBUTE__TY = "ty";
+ public static final String ATTRIBUTE__PRODUCT = "product";
+ public static final String ATTRIBUTE__USB_MFG = "usb_MFG";
+ public static final String ATTRIBUTE__USB_MDL = "usb_MDL";
+ public static final String ATTRIBUTE__MFG = "mfg";
+ public static final String EXCLUDE_FUJI = "fuji";
+ public static final String PDL_ATTRIBUTE = "pdl";
+
+ public static boolean isVendorPrinter(NsdServiceInfo networkDevice, String[] vendorValues) {
+
+ Map<String, byte[]> attributes = networkDevice.getAttributes();
+ String product = getString(attributes.get(ATTRIBUTE__PRODUCT));
+ String ty = getString(attributes.get(ATTRIBUTE__TY));
+ String usbMfg = getString(attributes.get(ATTRIBUTE__USB_MFG));
+ String usbMdl = getString(attributes.get(ATTRIBUTE__USB_MDL));
+ String mfg = getString(attributes.get(ATTRIBUTE__MFG));
+ return containsVendor(product, vendorValues) || containsVendor(ty, vendorValues) || containsVendor(usbMfg, vendorValues) || containsVendor(mfg, vendorValues) && !(containsString(ty, EXCLUDE_FUJI) || containsString(product, EXCLUDE_FUJI) || containsString(usbMdl, EXCLUDE_FUJI));
+
+ }
+
+ public static String getVendor(NsdServiceInfo networkDevice) {
+ String vendor;
+
+ Map<String, byte[]> attributes = networkDevice.getAttributes();
+ vendor = getString(attributes.get(ATTRIBUTE__MFG));
+ if (!TextUtils.isEmpty(vendor)) return vendor;
+ vendor = getString(attributes.get(ATTRIBUTE__USB_MFG));
+ if (!TextUtils.isEmpty(vendor)) return vendor;
+
+ return null;
+ }
+
+ public static boolean checkPDLSupport(NsdServiceInfo networkDevice, String[] pdlFormats) {
+ if (pdlFormats == null) return false;
+
+ String pdls = MDnsUtils.getString(networkDevice.getAttributes().get(PDL_ATTRIBUTE));
+ if (pdls != null) {
+ for (String pdl : pdlFormats) {
+ if (pdls.contains(pdl)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ private static boolean containsVendor(String container, String[] vendorValues) {
+ if ((container == null) || (vendorValues == null)) return false;
+ for (String value : vendorValues) {
+ if (containsString(container, value)
+ || containsString(container.toLowerCase(Locale.US), value.toLowerCase(Locale.US))
+ || containsString(container.toUpperCase(Locale.US), value.toUpperCase(Locale.US)))
+ return true;
+ }
+ return false;
+ }
+
+ private static String getString(byte[] value) {
+ if (value != null) return new String(value, StandardCharsets.UTF_8);
+ return null;
+ }
+
+ private static boolean containsString(String container, String contained) {
+ return (container != null) && (contained != null) && (container.equalsIgnoreCase(contained) || container.contains(contained + " "));
+ }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/PrinterHashMap.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/PrinterHashMap.java
new file mode 100755
index 0000000..b88c7c725
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/PrinterHashMap.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.printservice.recommendation.plugin.xerox;
+
+import android.net.nsd.NsdServiceInfo;
+
+import java.util.HashMap;
+
+final class PrinterHashMap extends HashMap<String, NsdServiceInfo> {
+ public static String getKey(NsdServiceInfo serviceInfo) {
+ return serviceInfo.getServiceName();
+ }
+
+ public NsdServiceInfo addPrinter(NsdServiceInfo device) {
+ return put(getKey(device), device);
+ }
+
+ public NsdServiceInfo removePrinter(NsdServiceInfo device) {
+ return remove(getKey(device));
+ }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java
new file mode 100755
index 0000000..f64eed4
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/ServiceResolver.java
@@ -0,0 +1,199 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.printservice.recommendation.plugin.xerox;
+
+import android.content.Context;
+import android.net.nsd.NsdManager;
+import android.net.nsd.NsdServiceInfo;
+import android.text.TextUtils;
+import com.android.printservice.recommendation.util.DiscoveryListenerMultiplexer;
+import com.android.printservice.recommendation.util.NsdResolveQueue;
+
+import java.util.ArrayList;
+import java.util.LinkedList;
+import java.util.List;
+
+class ServiceResolver {
+
+ private final NsdManager mNSDManager;
+ private final String[] mServiceType;
+ private final Observer mObserver;
+ private final VendorInfo mVendorInfo;
+ private final String[] mPDLs;
+ private final PrinterHashMap mPrinterHashMap = new PrinterHashMap();
+ private final List<NsdManager.DiscoveryListener> mListeners = new ArrayList<>();
+ private final NsdResolveQueue mNsdResolveQueue;
+
+ public interface Observer {
+ void dataSetChanged();
+ }
+
+ public ServiceResolver(Context context, Observer observer, VendorInfo vendorInfo, String[] serviceTypes, String[] pdls) {
+ mNsdResolveQueue = NsdResolveQueue.getInstance();
+ mObserver = observer;
+ mServiceType = serviceTypes;
+ mNSDManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
+ mVendorInfo = vendorInfo;
+ mPDLs = pdls;
+ }
+
+ public void start() {
+ stop();
+ for (final String service : mServiceType) {
+ NsdManager.DiscoveryListener listener = new NsdManager.DiscoveryListener() {
+ @Override
+ public void onStartDiscoveryFailed(String s, int i) {
+
+ }
+
+ @Override
+ public void onStopDiscoveryFailed(String s, int i) {
+
+ }
+
+ @Override
+ public void onDiscoveryStarted(String s) {
+
+ }
+
+ @Override
+ public void onDiscoveryStopped(String s) {
+
+ }
+
+ @Override
+ public void onServiceFound(NsdServiceInfo nsdServiceInfo) {
+ queueRequest(nsdServiceInfo);
+ }
+
+ @Override
+ public void onServiceLost(NsdServiceInfo nsdServiceInfo) {
+ removeRequest(nsdServiceInfo);
+ printerRemoved(nsdServiceInfo);
+ }
+ };
+ DiscoveryListenerMultiplexer.addListener(mNSDManager, service, listener);
+ mListeners.add(listener);
+ }
+ }
+
+ public void stop() {
+ for (NsdManager.DiscoveryListener listener : mListeners) {
+ DiscoveryListenerMultiplexer.removeListener(mNSDManager, listener);
+ }
+ mListeners.clear();
+ clearRequests();
+ }
+
+ //Resolving nsd services
+ private final LinkedList<NsdServiceInfo> mQueue = new LinkedList<>();
+ private final Object mLock = new Object();
+ private NsdServiceInfo mCurrentRequest = null;
+
+ private void queueRequest(NsdServiceInfo serviceInfo) {
+ synchronized (mLock) {
+ if (mQueue.contains(serviceInfo)) return;
+ mQueue.add(serviceInfo);
+ makeNextRequest();
+ }
+ }
+
+ private void removeRequest(NsdServiceInfo serviceInfo) {
+ synchronized (mLock) {
+ mQueue.remove(serviceInfo);
+ if ((mCurrentRequest != null) && serviceInfo.equals(mCurrentRequest))
+ mCurrentRequest = null;
+ }
+ }
+
+ private void clearRequests() {
+ synchronized (mLock) {
+ mQueue.clear();
+ }
+ }
+
+ private void makeNextRequest() {
+ synchronized (mLock) {
+ if (mCurrentRequest != null) return;
+ if (mQueue.isEmpty()) return;
+ mCurrentRequest = mQueue.removeFirst();
+ mNsdResolveQueue.resolve(mNSDManager, mCurrentRequest, new NsdManager.ResolveListener() {
+ @Override
+ public void onResolveFailed(NsdServiceInfo nsdServiceInfo, int i) {
+ synchronized (mLock) {
+ if (mCurrentRequest != null) mQueue.add(mCurrentRequest);
+ makeNextRequest();
+ }
+ }
+
+ @Override
+ public void onServiceResolved(NsdServiceInfo nsdServiceInfo) {
+ synchronized (mLock) {
+ if (mCurrentRequest != null) {
+ printerFound(nsdServiceInfo);
+ mCurrentRequest = null;
+ }
+ makeNextRequest();
+ }
+ }
+ });
+
+ }
+ }
+
+ private void printerFound(NsdServiceInfo nsdServiceInfo) {
+ if (nsdServiceInfo == null) return;
+ if (TextUtils.isEmpty(PrinterHashMap.getKey(nsdServiceInfo))) return;
+ String vendor = MDnsUtils.getVendor(nsdServiceInfo);
+ if (vendor == null) vendor = "";
+
+ for (String vendorValues : mVendorInfo.mDNSValues) {
+ if (vendor.equalsIgnoreCase(vendorValues)) {
+ vendor = mVendorInfo.mVendorID;
+ break;
+ }
+ }
+
+ if ((vendor != mVendorInfo.mVendorID) &&
+ MDnsUtils.isVendorPrinter(nsdServiceInfo, mVendorInfo.mDNSValues)) {
+ vendor = mVendorInfo.mVendorID;
+ }
+
+ if (!(vendor == mVendorInfo.mVendorID)) {
+ return;
+ }
+
+ if (!MDnsUtils.checkPDLSupport(nsdServiceInfo, mPDLs)) {
+ return;
+ }
+
+ if ((mPrinterHashMap.addPrinter(nsdServiceInfo) == null)) {
+ mObserver.dataSetChanged();
+ }
+
+ }
+
+ private void printerRemoved(NsdServiceInfo nsdServiceInfo) {
+ if ((mPrinterHashMap.removePrinter(nsdServiceInfo) != null)) {
+ mObserver.dataSetChanged();
+ }
+ }
+
+ public int getCount() {
+ return mPrinterHashMap.size();
+ }
+
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/VendorInfo.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/VendorInfo.java
new file mode 100755
index 0000000..20967a7
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/VendorInfo.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.printservice.recommendation.plugin.xerox;
+
+import android.content.res.Resources;
+
+import java.util.Arrays;
+
+final class VendorInfo {
+
+ public final String mPackageName;
+ public final String mVendorID;
+ public final String[] mDNSValues;
+ public final int mID;
+
+ public VendorInfo(Resources resources, int vendor_info_id) {
+ mID = vendor_info_id;
+ String[] data = resources.getStringArray(vendor_info_id);
+ if ((data == null) || (data.length < 2)) {
+ data = new String[]{null, null};
+ }
+ mPackageName = data[0];
+ mVendorID = data[1];
+ mDNSValues = (data.length > 2) ? Arrays.copyOfRange(data, 2, data.length) : new String[]{};
+ }
+}
diff --git a/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/XeroxPrintServiceRecommendationPlugin.java b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/XeroxPrintServiceRecommendationPlugin.java
new file mode 100755
index 0000000..3fb9ca2
--- /dev/null
+++ b/packages/PrintRecommendationService/src/com/android/printservice/recommendation/plugin/xerox/XeroxPrintServiceRecommendationPlugin.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.printservice.recommendation.plugin.xerox;
+
+import android.content.Context;
+import android.net.nsd.NsdManager;
+import android.annotation.NonNull;
+import com.android.printservice.recommendation.PrintServicePlugin;
+
+import com.android.printservice.recommendation.R;
+
+public class XeroxPrintServiceRecommendationPlugin implements PrintServicePlugin, ServiceResolver.Observer {
+
+ protected final Object mLock = new Object();
+ protected PrinterDiscoveryCallback mDiscoveryCallback = null;
+ protected final ServiceResolver mServiceResolver;
+ protected final NsdManager mNSDManager;
+ protected final VendorInfo mVendorInfo;
+ private final int mVendorStringID = R.string.plugin_vendor_xerox;
+ private final String PDL__PDF = "application/pdf";
+ private final String[] mServices = new String[]{"_ipp._tcp"};
+
+ public XeroxPrintServiceRecommendationPlugin(Context context) {
+ mNSDManager = (NsdManager) context.getSystemService(Context.NSD_SERVICE);
+ mVendorInfo = new VendorInfo(context.getResources(), R.array.known_print_vendor_info_for_xerox);
+ mServiceResolver = new ServiceResolver(context, this, mVendorInfo, mServices, new String[]{PDL__PDF});
+ }
+
+ @Override
+ public int getName() {
+ return mVendorStringID;
+ }
+
+ @NonNull
+ @Override
+ public CharSequence getPackageName() {
+ return mVendorInfo.mPackageName;
+ }
+
+ @Override
+ public void start(@NonNull PrinterDiscoveryCallback callback) throws Exception {
+ synchronized (mLock) {
+ mDiscoveryCallback = callback;
+ mServiceResolver.start();
+ }
+ }
+
+ @Override
+ public void stop() throws Exception {
+ synchronized (mLock) {
+ mDiscoveryCallback = null;
+ mServiceResolver.stop();
+ }
+ }
+
+ @Override
+ public void dataSetChanged() {
+ synchronized (mLock) {
+ if (mDiscoveryCallback != null) mDiscoveryCallback.onChanged(getCount());
+ }
+ }
+
+ public int getCount() {
+ return mServiceResolver.getCount();
+ }
+}
diff --git a/packages/PrintSpooler/res/layout/print_activity_controls.xml b/packages/PrintSpooler/res/layout/print_activity_controls.xml
index 248d0c0..69d4f91 100644
--- a/packages/PrintSpooler/res/layout/print_activity_controls.xml
+++ b/packages/PrintSpooler/res/layout/print_activity_controls.xml
@@ -239,7 +239,7 @@
android:singleLine="true"
android:ellipsize="end"
android:visibility="visible"
- android:inputType="number"
+ android:inputType="textNoSuggestions"
android:digits="0123456789 ,-">
</com.android.printspooler.widget.CustomErrorEditText>
diff --git a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
index 0feda92..c74c6a7 100644
--- a/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
+++ b/packages/PrintSpooler/src/com/android/printspooler/renderer/PdfManipulationService.java
@@ -277,18 +277,12 @@
Rect cropBox = new Rect();
Matrix transform = new Matrix();
- final boolean contentPortrait = attributes.getMediaSize().isPortrait();
-
final boolean layoutDirectionRtl = getResources().getConfiguration()
.getLayoutDirection() == View.LAYOUT_DIRECTION_RTL;
// We do not want to rotate the media box, so take into account orientation.
- final int dstWidthPts = contentPortrait
- ? pointsFromMils(attributes.getMediaSize().getWidthMils())
- : pointsFromMils(attributes.getMediaSize().getHeightMils());
- final int dstHeightPts = contentPortrait
- ? pointsFromMils(attributes.getMediaSize().getHeightMils())
- : pointsFromMils(attributes.getMediaSize().getWidthMils());
+ final int dstWidthPts = pointsFromMils(attributes.getMediaSize().getWidthMils());
+ final int dstHeightPts = pointsFromMils(attributes.getMediaSize().getHeightMils());
final boolean scaleForPrinting = mEditor.shouldScaleForPrinting();
@@ -310,24 +304,12 @@
// Make sure content is top-left after media box resize.
transform.setTranslate(0, srcHeightPts - dstHeightPts);
- // Rotate the content if in landscape.
- if (!contentPortrait) {
- transform.postRotate(270);
- transform.postTranslate(0, dstHeightPts);
- }
-
// Scale the content if document allows it.
final float scale;
if (scaleForPrinting) {
- if (contentPortrait) {
- scale = Math.min((float) dstWidthPts / srcWidthPts,
- (float) dstHeightPts / srcHeightPts);
- transform.postScale(scale, scale);
- } else {
- scale = Math.min((float) dstWidthPts / srcHeightPts,
- (float) dstHeightPts / srcWidthPts);
- transform.postScale(scale, scale, mediaBox.left, mediaBox.bottom);
- }
+ scale = Math.min((float) dstWidthPts / srcWidthPts,
+ (float) dstHeightPts / srcHeightPts);
+ transform.postScale(scale, scale);
} else {
scale = 1.0f;
}
@@ -344,10 +326,8 @@
// If in RTL mode put the content in the logical top-right corner.
if (layoutDirectionRtl) {
- final float dx = contentPortrait
- ? dstWidthPts - (int) (srcWidthPts * scale + 0.5f) : 0;
- final float dy = contentPortrait
- ? 0 : - (dstHeightPts - (int) (srcWidthPts * scale + 0.5f));
+ final float dx = dstWidthPts - (int) (srcWidthPts * scale + 0.5f);
+ final float dy = 0;
transform.postTranslate(dx, dy);
}
diff --git a/packages/SettingsLib/res/values-da/strings.xml b/packages/SettingsLib/res/values-da/strings.xml
index 4df39d2..8f8d7a6 100644
--- a/packages/SettingsLib/res/values-da/strings.xml
+++ b/packages/SettingsLib/res/values-da/strings.xml
@@ -237,7 +237,7 @@
<string name="force_msaa" msgid="7920323238677284387">"Tving 4x MSAA"</string>
<string name="force_msaa_summary" msgid="9123553203895817537">"Aktivér 4x MSAA i apps med OpenGL ES 2.0"</string>
<string name="show_non_rect_clip" msgid="505954950474595172">"Fejlfind på ikke-rektangulære klippehandlinger"</string>
- <string name="track_frame_time" msgid="6146354853663863443">"GPU-gengivelse for profil"</string>
+ <string name="track_frame_time" msgid="6146354853663863443">"GPU-profilgengivelse"</string>
<string name="window_animation_scale_title" msgid="6162587588166114700">"Animationsskala for vindue"</string>
<string name="transition_animation_scale_title" msgid="387527540523595875">"Overgangsanimationsskala"</string>
<string name="animator_duration_scale_title" msgid="3406722410819934083">"Animatorvarighedsskala"</string>
diff --git a/packages/SettingsLib/res/values-hr/strings.xml b/packages/SettingsLib/res/values-hr/strings.xml
index 148065e..974af2c 100644
--- a/packages/SettingsLib/res/values-hr/strings.xml
+++ b/packages/SettingsLib/res/values-hr/strings.xml
@@ -282,7 +282,7 @@
<string name="select_webview_provider_toast_text" msgid="5466970498308266359">"Taj izbor više nije važeći. Pokušajte ponovo."</string>
<string name="convert_to_file_encryption" msgid="3060156730651061223">"Pretvori u enkripciju datoteka"</string>
<string name="convert_to_file_encryption_enabled" msgid="2861258671151428346">"Pretvori…"</string>
- <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Enkripcija datoteka već je izvršena"</string>
+ <string name="convert_to_file_encryption_done" msgid="7859766358000523953">"Datoteke su već šifrirane"</string>
<string name="title_convert_fbe" msgid="1263622876196444453">"Pretvaranje u enkripciju datoteka"</string>
<string name="convert_to_fbe_warning" msgid="6139067817148865527">"Pretvorite podatkovnu particiju u enkripciju datoteka.\n Upozorenje! Time će se izbrisati svi vaši podaci.\n Značajka je u alfa verziji i možda neće funkcionirati pravilno.\n Pritisnite \"Izbriši i pretvori...\" da biste nastavili."</string>
<string name="button_convert_fbe" msgid="5152671181309826405">"Izbriši i pretvori…"</string>
diff --git a/packages/SettingsLib/res/values-hu/strings.xml b/packages/SettingsLib/res/values-hu/strings.xml
index d8af0d4..059a8bb 100644
--- a/packages/SettingsLib/res/values-hu/strings.xml
+++ b/packages/SettingsLib/res/values-hu/strings.xml
@@ -226,7 +226,7 @@
<string name="enable_opengl_traces_title" msgid="6790444011053219871">"OpenGL nyomon követése"</string>
<string name="usb_audio_disable_routing" msgid="8114498436003102671">"Hangátirányítás tiltása"</string>
<string name="usb_audio_disable_routing_summary" msgid="980282760277312264">"Hangátirányítás tiltása az USB-s hangeszközöknél"</string>
- <string name="debug_layout" msgid="5981361776594526155">"Elrendezéshatár mutatása"</string>
+ <string name="debug_layout" msgid="5981361776594526155">"Elrendezéshatárok"</string>
<string name="debug_layout_summary" msgid="2001775315258637682">"Kliphatárok, margók stb. megjelenítése."</string>
<string name="force_rtl_layout_all_locales" msgid="2259906643093138978">"Elrendezés jobbról balra"</string>
<string name="force_rtl_layout_all_locales_summary" msgid="9192797796616132534">"Elrendezés jobbról balra minden nyelvnél"</string>
@@ -237,7 +237,7 @@
<string name="force_msaa" msgid="7920323238677284387">"4x MSAA kényszerítése"</string>
<string name="force_msaa_summary" msgid="9123553203895817537">"A 4x MSAA engedélyezése az OpenGL ES 2.0-nál"</string>
<string name="show_non_rect_clip" msgid="505954950474595172">"Nem négyzetes kivágási műveletek hibakeresése"</string>
- <string name="track_frame_time" msgid="6146354853663863443">"Profil GPU-renderelésről"</string>
+ <string name="track_frame_time" msgid="6146354853663863443">"GPU-renderelési profil"</string>
<string name="window_animation_scale_title" msgid="6162587588166114700">"Ablakanimáció tempója"</string>
<string name="transition_animation_scale_title" msgid="387527540523595875">"Áttűnési animáció tempója"</string>
<string name="animator_duration_scale_title" msgid="3406722410819934083">"Animáció tempója"</string>
diff --git a/packages/SettingsLib/res/values-kn-rIN/strings.xml b/packages/SettingsLib/res/values-kn-rIN/strings.xml
index 170a928..9b322c8 100644
--- a/packages/SettingsLib/res/values-kn-rIN/strings.xml
+++ b/packages/SettingsLib/res/values-kn-rIN/strings.xml
@@ -166,7 +166,7 @@
<string name="wifi_display_certification" msgid="8611569543791307533">"ವೈರ್ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣ"</string>
<string name="wifi_verbose_logging" msgid="4203729756047242344">"Wi‑Fi ವೆರ್ಬೋಸ್ ಲಾಗಿಂಗ್ ಸಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="wifi_aggressive_handover" msgid="9194078645887480917">"ಸೆಲ್ಯುಲರ್ ಹಸ್ತಾಂತರಿಸಲು ಆಕ್ರಮಣಕಾರಿ Wi‑Fi"</string>
- <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"Wi-Fi ರೋಮ್ ಸ್ಕ್ಯಾನ್ಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸಿ"</string>
+ <string name="wifi_allow_scan_with_traffic" msgid="3601853081178265786">"ವೈ-ಫೈ ರೋಮ್ ಸ್ಕ್ಯಾನ್ಗಳನ್ನು ಯಾವಾಗಲೂ ಅನುಮತಿಸಿ"</string>
<string name="mobile_data_always_on" msgid="7745605759775320362">"ಸೆಲ್ಯುಲರ್ ಡೇಟಾ ಯಾವಾಗಲೂ ಸಕ್ರಿಯ"</string>
<string name="bluetooth_disable_absolute_volume" msgid="2660673801947898809">"ಸಂಪೂರ್ಣ ವಾಲ್ಯೂಮ್ ನಿಷ್ಕ್ರಿಯಗೊಳಿಸಿ"</string>
<string name="wifi_display_certification_summary" msgid="1155182309166746973">"ವೈರ್ಲೆಸ್ ಪ್ರದರ್ಶನ ಪ್ರಮಾಣೀಕರಣಕ್ಕಾಗಿ ಆಯ್ಕೆಗಳನ್ನು ತೋರಿಸು"</string>
@@ -181,7 +181,7 @@
<string name="allow_mock_location_summary" msgid="317615105156345626">"ಅಣಕು ಸ್ಥಾನಗಳನ್ನು ಅನುಮತಿಸು"</string>
<string name="debug_view_attributes" msgid="6485448367803310384">"ವೀಕ್ಷಣೆ ಆಟ್ರಿಬ್ಯೂಟ್ ಪರಿಶೀಲನೆ"</string>
<string name="legacy_dhcp_client_summary" msgid="163383566317652040">"ಹೊಸ Android DHCP ಕ್ಲೈಂಟ್ ಬದಲಾಗಿ Lollipop ನಿಂದ DHCP ಕ್ಲೈಂಟ್ ಬಳಸಿ."</string>
- <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"Wi-Fi ಸಕ್ರಿಯವಾಗಿರುವಾಗಲೂ, ಯಾವಾಗಲೂ ಮೊಬೈಲ್ ಡೇಟಾ ಸಕ್ರಿಯವಾಗಿರಿಸಿ (ವೇಗವಾಗಿ ನೆಟ್ವರ್ಕ್ ಬದಲಾಯಿಸಲು)."</string>
+ <string name="mobile_data_always_on_summary" msgid="8149773901431697910">"ವೈ-ಫೈ ಸಕ್ರಿಯವಾಗಿರುವಾಗಲೂ, ಯಾವಾಗಲೂ ಮೊಬೈಲ್ ಡೇಟಾ ಸಕ್ರಿಯವಾಗಿರಿಸಿ (ವೇಗವಾಗಿ ನೆಟ್ವರ್ಕ್ ಬದಲಾಯಿಸಲು)."</string>
<string name="adb_warning_title" msgid="6234463310896563253">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯನ್ನು ಅನುಮತಿಸುವುದೇ?"</string>
<string name="adb_warning_message" msgid="7316799925425402244">"USB ಡೀಬಗ್ ಮಾಡುವಿಕೆಯು ಅಭಿವೃದ್ಧಿ ಉದ್ದೇಶಗಳಿಗೆ ಮಾತ್ರ ಆಗಿದೆ. ನಿಮ್ಮ ಕಂಪ್ಯೂಟರ್ ಮತ್ತು ನಿಮ್ಮ ಸಾಧನದ ನಡುವೆ ಡೇಟಾವನ್ನು ನಕಲಿಸಲು, ಅಧಿಸೂಚನೆ ಇಲ್ಲದೆ ನಿಮ್ಮ ಸಾಧನದಲ್ಲಿ ಅಪ್ಲಿಕೇಶನ್ಗಳನ್ನು ಸ್ಥಾಪಿಸಲು ಮತ್ತು ಲಾಗ್ ಡೇಟಾ ಓದಲು ಅದನ್ನು ಬಳಸಿ."</string>
<string name="adb_keys_warning_message" msgid="5659849457135841625">"ನೀವು ಹಿಂದೆ ಅಧಿಕೃತಗೊಳಿಸಿದ ಎಲ್ಲ ಕಂಪ್ಯೂಟರ್ಗಳಿಂದ USB ಡೀಬಗ್ಗೆ ಪ್ರವೇಶವನ್ನು ರದ್ದುಗೊಳಿಸುವುದೇ?"</string>
diff --git a/packages/SettingsLib/res/values-uz-rUZ/strings.xml b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
index 7d41acb..13fdb05 100644
--- a/packages/SettingsLib/res/values-uz-rUZ/strings.xml
+++ b/packages/SettingsLib/res/values-uz-rUZ/strings.xml
@@ -152,7 +152,7 @@
<string name="bugreport_in_power" msgid="7923901846375587241">"Xatoliklar hisoboti"</string>
<string name="bugreport_in_power_summary" msgid="1778455732762984579">"Menyuda xatoliklar hisobotini yuborish tugmasi ko‘rsatilsin"</string>
<string name="keep_screen_on" msgid="1146389631208760344">"Ekranning yoniq turishi"</string>
- <string name="keep_screen_on_summary" msgid="2173114350754293009">"Qurilmani quvvatlash vaqtida ekran doim yoniq turadi"</string>
+ <string name="keep_screen_on_summary" msgid="2173114350754293009">"Qurilma quvvat olayotganda ekran doim yoniq turadi"</string>
<string name="bt_hci_snoop_log" msgid="3340699311158865670">"Bluetooth HCI amallari translatsiyasi jurnali"</string>
<string name="bt_hci_snoop_log_summary" msgid="730247028210113851">"Barcha Bluetooth HCI paketlarini bitta faylga saqlash"</string>
<string name="oem_unlock_enable" msgid="6040763321967327691">"Zavod qulfini yechish"</string>
diff --git a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
index 8e43bff..2265d42 100644
--- a/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
+++ b/packages/SettingsLib/src/com/android/settingslib/RestrictedLockUtils.java
@@ -701,8 +701,8 @@
if (userId != other.userId) {
return false;
}
- if ((component == null && other == null) ||
- (component != null && component.equals(other))) {
+ if ((component == null && other.component == null) ||
+ (component != null && component.equals(other.component))) {
return true;
}
return false;
diff --git a/packages/SystemUI/res/layout/keyguard_status_bar.xml b/packages/SystemUI/res/layout/keyguard_status_bar.xml
index b5f917a..a2dfc0d 100644
--- a/packages/SystemUI/res/layout/keyguard_status_bar.xml
+++ b/packages/SystemUI/res/layout/keyguard_status_bar.xml
@@ -27,7 +27,7 @@
<com.android.systemui.statusbar.phone.MultiUserSwitch android:id="@+id/multi_user_switch"
android:layout_width="@dimen/multi_user_switch_width_keyguard"
- android:layout_height="@dimen/status_bar_header_height_keyguard"
+ android:layout_height="match_parent"
android:layout_alignParentEnd="true"
android:background="@drawable/ripple_drawable"
android:layout_marginEnd="@dimen/multi_user_switch_keyguard_margin">
@@ -43,7 +43,7 @@
android:layout_height="@dimen/status_bar_header_height"
android:layout_toStartOf="@id/multi_user_switch"
android:layout_alignWithParentIfMissing="true"
- android:layout_marginStart="16dp"
+ android:layout_marginStart="@dimen/system_icons_super_container_margin_start"
android:paddingEnd="@dimen/system_icons_keyguard_padding_end">
<FrameLayout android:id="@+id/system_icons_container"
android:layout_width="wrap_content"
@@ -67,7 +67,7 @@
<com.android.keyguard.CarrierText
android:id="@+id/keyguard_carrier_text"
android:layout_width="match_parent"
- android:layout_height="@dimen/status_bar_header_height_keyguard"
+ android:layout_height="match_parent"
android:layout_marginStart="@dimen/keyguard_carrier_text_margin"
android:layout_toStartOf="@id/system_icons_super_container"
android:gravity="center_vertical"
diff --git a/packages/SystemUI/res/layout/zen_mode_button.xml b/packages/SystemUI/res/layout/zen_mode_button.xml
new file mode 100644
index 0000000..f25131b
--- /dev/null
+++ b/packages/SystemUI/res/layout/zen_mode_button.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+ Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<RadioButton
+ xmlns:android="http://schemas.android.com/apk/res/android"
+ android:id="@android:id/checkbox"
+ android:layout_width="40dp"
+ android:layout_marginStart="7dp"
+ android:layout_marginEnd="4dp"
+ android:layout_height="48dp"
+ android:layout_alignParentStart="true"
+ android:gravity="center"
+ android:paddingTop="10dp"
+ android:paddingBottom="10dp">
+
+</RadioButton>
\ No newline at end of file
diff --git a/packages/SystemUI/res/layout/zen_mode_condition.xml b/packages/SystemUI/res/layout/zen_mode_condition.xml
index 53f3908..ca4f727 100644
--- a/packages/SystemUI/res/layout/zen_mode_condition.xml
+++ b/packages/SystemUI/res/layout/zen_mode_condition.xml
@@ -18,18 +18,10 @@
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:clipChildren="false"
- android:layout_marginBottom="@dimen/zen_mode_condition_detail_item_spacing"
android:layout_marginStart="1dp"
- android:layout_marginEnd="0dp" >
-
- <RadioButton
- android:id="@android:id/checkbox"
- android:layout_width="40dp"
- android:layout_marginStart="7dp"
- android:layout_marginEnd="4dp"
- android:layout_height="48dp"
- android:layout_alignParentStart="true"
- android:gravity="center" />
+ android:layout_marginEnd="0dp"
+ android:layout_weight="1"
+ android:gravity="center_vertical" >
<LinearLayout
android:id="@android:id/content"
diff --git a/packages/SystemUI/res/layout/zen_mode_panel.xml b/packages/SystemUI/res/layout/zen_mode_panel.xml
index 43ab4bb..906b867 100644
--- a/packages/SystemUI/res/layout/zen_mode_panel.xml
+++ b/packages/SystemUI/res/layout/zen_mode_panel.xml
@@ -94,9 +94,18 @@
android:layout_marginTop="8dp"
android:layout_marginEnd="4dp"
android:layout_marginStart="4dp"
- android:orientation="vertical"
- android:paddingBottom="@dimen/zen_mode_condition_detail_bottom_padding" />
-
+ android:paddingBottom="@dimen/zen_mode_condition_detail_bottom_padding"
+ android:orientation="horizontal" >
+ <RadioGroup
+ android:id="@+id/zen_radio_buttons"
+ android:layout_width="wrap_content"
+ android:layout_height="wrap_content" />
+ <LinearLayout
+ android:id="@+id/zen_radio_buttons_content"
+ android:layout_width="fill_parent"
+ android:layout_height="fill_parent"
+ android:orientation="vertical"/>
+ </LinearLayout>
<TextView
android:id="@+id/zen_alarm_warning"
diff --git a/packages/SystemUI/res/values-af/strings.xml b/packages/SystemUI/res/values-af/strings.xml
index 9c5c9ec..4f40c63 100644
--- a/packages/SystemUI/res/values-af/strings.xml
+++ b/packages/SystemUI/res/values-af/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Liggingversoeke aktief"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Verwyder alle kennisgewings."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Kennisgewingsinstellings"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>-instellings"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Die skerm sal outomaties draai."</string>
diff --git a/packages/SystemUI/res/values-am/strings.xml b/packages/SystemUI/res/values-am/strings.xml
index 4489416..6900bb7 100644
--- a/packages/SystemUI/res/values-am/strings.xml
+++ b/packages/SystemUI/res/values-am/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"የአካባቢ ጥያቄዎች ነቅተዋል"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ሁሉንም ማሳወቂያዎች አጽዳ"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"የማሳወቂያ ቅንብሮች"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"የ<xliff:g id="APP_NAME">%s</xliff:g> ቅንብሮች"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ማያ ገጽ በራስ ሰር ይዞራል።"</string>
diff --git a/packages/SystemUI/res/values-ar/strings.xml b/packages/SystemUI/res/values-ar/strings.xml
index 88e3d90..edda177 100644
--- a/packages/SystemUI/res/values-ar/strings.xml
+++ b/packages/SystemUI/res/values-ar/strings.xml
@@ -249,6 +249,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"طلبات الموقع نشطة"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"محو جميع الإشعارات."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"و<xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"إعدادات الإشعارات"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"إعدادات <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"سيتم تدوير الشاشة تلقائيًا."</string>
diff --git a/packages/SystemUI/res/values-az-rAZ/strings.xml b/packages/SystemUI/res/values-az-rAZ/strings.xml
index 683651d..57f6bfd 100644
--- a/packages/SystemUI/res/values-az-rAZ/strings.xml
+++ b/packages/SystemUI/res/values-az-rAZ/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Məkan sorğuları arxivi"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Bütün bildirişləri sil."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildiriş ayarları"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ayarları"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik döndəriləcək."</string>
diff --git a/packages/SystemUI/res/values-bg/strings.xml b/packages/SystemUI/res/values-bg/strings.xml
index 41f3bbd..0962c2a 100644
--- a/packages/SystemUI/res/values-bg/strings.xml
+++ b/packages/SystemUI/res/values-bg/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Активни заявки за местоположение"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Изчистване на всички известия."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Настройки за известия"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Настройки за <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранът ще се завърта автоматично."</string>
diff --git a/packages/SystemUI/res/values-bn-rBD/strings.xml b/packages/SystemUI/res/values-bn-rBD/strings.xml
index 7053030..71039e5 100644
--- a/packages/SystemUI/res/values-bn-rBD/strings.xml
+++ b/packages/SystemUI/res/values-bn-rBD/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"অবস্থান অনুরোধ সক্রিয় রয়েছে"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"সমস্ত বিজ্ঞপ্তি সাফ করুন৷"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>টি"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"বিজ্ঞপ্তির সেটিংস"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> সেটিংস"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"স্ক্রীন স্বয়ংক্রিয়ভাবে ঘুরে যাবে৷"</string>
@@ -514,7 +515,7 @@
<string name="night_mode_disclaimer" msgid="598914896926759578">"Android OS এর মূল অংশগুলিতে গাঢ় থিম প্রয়োগ করা হয়েছে যেটা সাধারণত একটি হালকা থিমে প্রদর্শিত হয়, যেমন সেটিংস৷"</string>
<string name="color_apply" msgid="9212602012641034283">"প্রয়োগ করুন"</string>
<string name="color_revert_title" msgid="4746666545480534663">"সেটিংস নিশ্চিত করুন"</string>
- <string name="color_revert_message" msgid="9116001069397996691">"কিছু রঙের সেটিংস এই ডিভাইসকে ব্যবহারের অযোগ্য করে দিতে পারে৷ এই রঙের সেটিংস নিশ্চিত করতে ওকে এ ক্লিক করুন, অন্যথায় ১০ সেকেন্ড পরে এই সেটিংস পুনরায় সেট হবে৷"</string>
+ <string name="color_revert_message" msgid="9116001069397996691">"কিছু রঙের সেটিংস এই ডিভাইসকে ব্যবহারের অযোগ্য করে দিতে পারে৷ এই রঙের সেটিংস নিশ্চিত করতে ঠিক আছে এ ক্লিক করুন, অন্যথায় ১০ সেকেন্ড পরে এই সেটিংস পুনরায় সেট হবে৷"</string>
<string name="battery_panel_title" msgid="7944156115535366613">"ব্যাটারির ব্যবহার"</string>
<string name="battery_detail_charging_summary" msgid="1279095653533044008">"চার্জ করার সময় ব্যাটারি সেভার উপলব্ধ নয়"</string>
<string name="battery_detail_switch_title" msgid="6285872470260795421">"ব্যাটারি সেভার"</string>
diff --git a/packages/SystemUI/res/values-ca/strings.xml b/packages/SystemUI/res/values-ca/strings.xml
index cb765fb1..e90257c 100644
--- a/packages/SystemUI/res/values-ca/strings.xml
+++ b/packages/SystemUI/res/values-ca/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Sol·licituds d\'ubicació actives"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Esborra totes les notificacions."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuració de les notificacions"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuració de l\'aplicació <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girarà automàticament."</string>
diff --git a/packages/SystemUI/res/values-cs/strings.xml b/packages/SystemUI/res/values-cs/strings.xml
index 2f1db1b..b23fad0 100644
--- a/packages/SystemUI/res/values-cs/strings.xml
+++ b/packages/SystemUI/res/values-cs/strings.xml
@@ -249,6 +249,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktivní žádosti o polohu"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazat všechna oznámení."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"a ještě <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Nastavení oznámení"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Nastavení aplikace <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka se automaticky otočí."</string>
diff --git a/packages/SystemUI/res/values-da/strings.xml b/packages/SystemUI/res/values-da/strings.xml
index 7d3ca4f..9c483b2 100644
--- a/packages/SystemUI/res/values-da/strings.xml
+++ b/packages/SystemUI/res/values-da/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktive placeringsanmodninger"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ryd alle underretninger."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> mere"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Underretningsindstillinger"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Indstillinger for <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skærmen roterer automatisk."</string>
diff --git a/packages/SystemUI/res/values-de/strings.xml b/packages/SystemUI/res/values-de/strings.xml
index f213312..f1ef1c0 100644
--- a/packages/SystemUI/res/values-de/strings.xml
+++ b/packages/SystemUI/res/values-de/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Standortanfragen aktiv"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle Benachrichtigungen löschen"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Benachrichtigungseinstellungen"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Einstellungen von <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Bildschirm wird automatisch gedreht."</string>
@@ -594,7 +595,7 @@
<string name="clipboard_description" msgid="3819919243940546364">"Elemente können direkt in die Zwischenablage gezogen werden. Ebenso können sie direkt aus der Zwischenablage gezogen werden, sofern diese geöffnet ist."</string>
<string name="accessibility_key" msgid="5701989859305675896">"Benutzerdefinierte Navigationsschaltfläche"</string>
<string name="keycode" msgid="7335281375728356499">"Keycode"</string>
- <string name="keycode_description" msgid="1403795192716828949">"Mit den Keycode-Schaltflächen können der Navigationsleiste Tasten hinzugefügt werden. Wird eine Keycode-Schaltfläche ausgewählt, führt sie die Aktion der entsprechenden Taste aus. Wählen Sie zuerst die Taste für die Schaltfläche aus und anschließend ein Bild, das auf der Schaltfläche erscheinen soll."</string>
+ <string name="keycode_description" msgid="1403795192716828949">"Mit den Keycode-Schaltflächen kann man der Navigationsleiste Tasten hinzufügen. Wird eine Keycode-Schaltfläche ausgewählt, führt sie die Aktion der entsprechenden Taste aus. Wähle zuerst die Taste für die Schaltfläche aus und dann ein Bild, das auf der Schaltfläche erscheinen soll."</string>
<string name="select_keycode" msgid="7413765103381924584">"Taste auswählen"</string>
<string name="preview" msgid="9077832302472282938">"Vorschau"</string>
<string name="drag_to_add_tiles" msgid="7058945779098711293">"Zum Hinzufügen von Kacheln ziehen"</string>
diff --git a/packages/SystemUI/res/values-el/strings.xml b/packages/SystemUI/res/values-el/strings.xml
index cd61816..92e443f 100644
--- a/packages/SystemUI/res/values-el/strings.xml
+++ b/packages/SystemUI/res/values-el/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Τα αιτήματα τοποθεσίας έχουν ενεργοποιηθεί"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Εκκαθάριση όλων των ειδοποιήσεων."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ρυθμίσεις ειδοποιήσεων"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Ρυθμίσεις <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Θα γίνεται αυτόματη περιστροφή της οθόνης."</string>
diff --git a/packages/SystemUI/res/values-en-rAU/strings.xml b/packages/SystemUI/res/values-en-rAU/strings.xml
index 803c7a2..bc1c378 100644
--- a/packages/SystemUI/res/values-en-rAU/strings.xml
+++ b/packages/SystemUI/res/values-en-rAU/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Location requests active"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+<xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Notification settings"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> settings"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
@@ -316,7 +317,7 @@
<string name="recents_empty_message" msgid="808480104164008572">"No recent items"</string>
<string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"You\'ve cleared everything"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
- <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen-pinning"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
@@ -498,7 +499,7 @@
<string name="notification_importance_high" msgid="1729480727023990427">"Always peek. No full screen interruption."</string>
<string name="notification_importance_max" msgid="2508384624461849111">"Always peek, and allow full screen interruption."</string>
<string name="notification_more_settings" msgid="816306283396553571">"More settings"</string>
- <string name="notification_done" msgid="5279426047273930175">"Finished"</string>
+ <string name="notification_done" msgid="5279426047273930175">"Done"</string>
<string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> notification controls"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Colour and appearance"</string>
<string name="night_mode" msgid="3540405868248625488">"Night mode"</string>
@@ -597,7 +598,7 @@
<string name="preview" msgid="9077832302472282938">"Preview"</string>
<string name="drag_to_add_tiles" msgid="7058945779098711293">"Drag to add tiles"</string>
<string name="drag_to_remove_tiles" msgid="3361212377437088062">"Drag here to remove"</string>
- <string name="qs_edit" msgid="2232596095725105230">"(edit)"</string>
+ <string name="qs_edit" msgid="2232596095725105230">"Edit"</string>
<string name="tuner_time" msgid="6572217313285536011">"Time"</string>
<string-array name="clock_options">
<item msgid="5965318737560463480">"Show hours, minutes and seconds"</item>
diff --git a/packages/SystemUI/res/values-en-rGB/strings.xml b/packages/SystemUI/res/values-en-rGB/strings.xml
index 803c7a2..bc1c378 100644
--- a/packages/SystemUI/res/values-en-rGB/strings.xml
+++ b/packages/SystemUI/res/values-en-rGB/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Location requests active"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+<xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Notification settings"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> settings"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
@@ -316,7 +317,7 @@
<string name="recents_empty_message" msgid="808480104164008572">"No recent items"</string>
<string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"You\'ve cleared everything"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
- <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen-pinning"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
@@ -498,7 +499,7 @@
<string name="notification_importance_high" msgid="1729480727023990427">"Always peek. No full screen interruption."</string>
<string name="notification_importance_max" msgid="2508384624461849111">"Always peek, and allow full screen interruption."</string>
<string name="notification_more_settings" msgid="816306283396553571">"More settings"</string>
- <string name="notification_done" msgid="5279426047273930175">"Finished"</string>
+ <string name="notification_done" msgid="5279426047273930175">"Done"</string>
<string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> notification controls"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Colour and appearance"</string>
<string name="night_mode" msgid="3540405868248625488">"Night mode"</string>
@@ -597,7 +598,7 @@
<string name="preview" msgid="9077832302472282938">"Preview"</string>
<string name="drag_to_add_tiles" msgid="7058945779098711293">"Drag to add tiles"</string>
<string name="drag_to_remove_tiles" msgid="3361212377437088062">"Drag here to remove"</string>
- <string name="qs_edit" msgid="2232596095725105230">"(edit)"</string>
+ <string name="qs_edit" msgid="2232596095725105230">"Edit"</string>
<string name="tuner_time" msgid="6572217313285536011">"Time"</string>
<string-array name="clock_options">
<item msgid="5965318737560463480">"Show hours, minutes and seconds"</item>
diff --git a/packages/SystemUI/res/values-en-rIN/strings.xml b/packages/SystemUI/res/values-en-rIN/strings.xml
index 803c7a2..bc1c378 100644
--- a/packages/SystemUI/res/values-en-rIN/strings.xml
+++ b/packages/SystemUI/res/values-en-rIN/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Location requests active"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Clear all notifications."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+<xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Notification settings"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> settings"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Screen will rotate automatically."</string>
@@ -316,7 +317,7 @@
<string name="recents_empty_message" msgid="808480104164008572">"No recent items"</string>
<string name="recents_empty_message_dismissed_all" msgid="2791312568666558651">"You\'ve cleared everything"</string>
<string name="recents_app_info_button_label" msgid="2890317189376000030">"Application Info"</string>
- <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen pinning"</string>
+ <string name="recents_lock_to_app_button_label" msgid="6942899049072506044">"screen-pinning"</string>
<string name="recents_search_bar_label" msgid="8074997400187836677">"search"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"Could not start <xliff:g id="APP">%s</xliff:g>."</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> is disabled in safe-mode."</string>
@@ -498,7 +499,7 @@
<string name="notification_importance_high" msgid="1729480727023990427">"Always peek. No full screen interruption."</string>
<string name="notification_importance_max" msgid="2508384624461849111">"Always peek, and allow full screen interruption."</string>
<string name="notification_more_settings" msgid="816306283396553571">"More settings"</string>
- <string name="notification_done" msgid="5279426047273930175">"Finished"</string>
+ <string name="notification_done" msgid="5279426047273930175">"Done"</string>
<string name="notification_gear_accessibility" msgid="94429150213089611">"<xliff:g id="APP_NAME">%1$s</xliff:g> notification controls"</string>
<string name="color_and_appearance" msgid="1254323855964993144">"Colour and appearance"</string>
<string name="night_mode" msgid="3540405868248625488">"Night mode"</string>
@@ -597,7 +598,7 @@
<string name="preview" msgid="9077832302472282938">"Preview"</string>
<string name="drag_to_add_tiles" msgid="7058945779098711293">"Drag to add tiles"</string>
<string name="drag_to_remove_tiles" msgid="3361212377437088062">"Drag here to remove"</string>
- <string name="qs_edit" msgid="2232596095725105230">"(edit)"</string>
+ <string name="qs_edit" msgid="2232596095725105230">"Edit"</string>
<string name="tuner_time" msgid="6572217313285536011">"Time"</string>
<string-array name="clock_options">
<item msgid="5965318737560463480">"Show hours, minutes and seconds"</item>
diff --git a/packages/SystemUI/res/values-es-rUS/strings.xml b/packages/SystemUI/res/values-es-rUS/strings.xml
index 1bed378..5a4e0e7 100644
--- a/packages/SystemUI/res/values-es-rUS/strings.xml
+++ b/packages/SystemUI/res/values-es-rUS/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas las notificaciones"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> más"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuración de notificaciones"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuración de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
diff --git a/packages/SystemUI/res/values-es/strings.xml b/packages/SystemUI/res/values-es/strings.xml
index da7d872..425076f 100644
--- a/packages/SystemUI/res/values-es/strings.xml
+++ b/packages/SystemUI/res/values-es/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de ubicación activas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Borrar todas las notificaciones"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> más"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ajustes de notificaciones"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Ajustes de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"La pantalla girará automáticamente."</string>
diff --git a/packages/SystemUI/res/values-et-rEE/strings.xml b/packages/SystemUI/res/values-et-rEE/strings.xml
index 72cd8179..8a72dbf 100644
--- a/packages/SystemUI/res/values-et-rEE/strings.xml
+++ b/packages/SystemUI/res/values-et-rEE/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Asukoha taotlused on aktiivsed"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Kustuta kõik teatised."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Märguandeseaded"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Rakenduse <xliff:g id="APP_NAME">%s</xliff:g> seaded"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekraani pööramine toimub automaatselt."</string>
diff --git a/packages/SystemUI/res/values-eu-rES/strings.xml b/packages/SystemUI/res/values-eu-rES/strings.xml
index 84a3606..4d118ab 100644
--- a/packages/SystemUI/res/values-eu-rES/strings.xml
+++ b/packages/SystemUI/res/values-eu-rES/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Aplikazioen kokapen-eskaerak aktibo daude"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Garbitu jakinarazpen guztiak."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Jakinarazpen-ezarpenak"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ezarpenak"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Pantaila automatikoki biratuko da."</string>
diff --git a/packages/SystemUI/res/values-fa/strings.xml b/packages/SystemUI/res/values-fa/strings.xml
index 52c45bb..2f190a9 100644
--- a/packages/SystemUI/res/values-fa/strings.xml
+++ b/packages/SystemUI/res/values-fa/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"درخواستهای موقعیت مکانی فعال است"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"پاک کردن تمام اعلانها"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"تنظیمات اعلان"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"تنظیمات <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"صفحه به صورت خودکار میچرخد."</string>
@@ -340,7 +341,7 @@
<string name="zen_silence_introduction" msgid="3137882381093271568">"این کار «همه» صداها و لرزشها از جمله هشدارها، موسیقی، ویدیوها و بازیها را مسدود میکند."</string>
<string name="keyguard_more_overflow_text" msgid="9195222469041601365">"+<xliff:g id="NUMBER_OF_NOTIFICATIONS">%d</xliff:g>"</string>
<string name="speed_bump_explanation" msgid="1288875699658819755">"اعلانهای کمتر فوری در زیر"</string>
- <string name="notification_tap_again" msgid="7590196980943943842">"برای باز کردن دوباره ضربه بزنید"</string>
+ <string name="notification_tap_again" msgid="7590196980943943842">"دوباره ضربه بزنید تا باز شود"</string>
<string name="keyguard_unlock" msgid="8043466894212841998">"برای باز کردن قفل سریع به بالا بکشید"</string>
<string name="phone_hint" msgid="4872890986869209950">"انگشتتان را از نماد تلفن تند بکشید"</string>
<string name="voice_hint" msgid="8939888732119726665">"برای «دستیار صوتی»، تند بکشید"</string>
@@ -399,15 +400,15 @@
<string name="disable_vpn" msgid="4435534311510272506">"غیرفعال کردن VPN"</string>
<string name="disconnect_vpn" msgid="1324915059568548655">"قطع اتصال VPN"</string>
<string name="monitoring_description_device_owned" msgid="5780988291898461883">"مدیریت دستگاه شما توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g>.\n\nسرپرستتان میتواند تنظیمات، دسترسی شرکت، برنامهها دادههای مرتبط با دستگاهتان و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند. برای دریافت اطلاعات بیشتر، با سرپرستتان تماس بگیرید."</string>
- <string name="monitoring_description_vpn" msgid="4445150119515393526">"شما به برنامهای برای تنظیم اتصال VPN اجازه دادید.\n\n این برنامه میتواند دستگاه و فعالیت شبکهتان را کنترل کند، از جمله ایمیل، برنامه و وبسایتها."</string>
+ <string name="monitoring_description_vpn" msgid="4445150119515393526">"شما به برنامهای برای تنظیم اتصال VPN اجازه دادید.\n\n این برنامه میتواند دستگاه و فعالیت شبکهتان را کنترل کند، از جمله رایانامه، برنامه و وبسایتها."</string>
<string name="monitoring_description_vpn_device_owned" msgid="3090670777499161246">"دستگاهتان توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت میشود.\n\nسرپرستتان میتواند تنظیمات، دسترسی شرکت، برنامهها، دادههای مرتبط با دستگاهتان و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند.\n\nشما به یک VPN وصل هستید که میتواند فعالیت شبکه شما را کنترل کند، از جمله ایمیلها، برنامهها و وبسایتها.\n\nبرای دریافت اطلاعات بیشتر، با سرپرستتان تماس بگیرید."</string>
- <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"نمایه کاری شما توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت میشود.\n\nسرپرستتان میتواند فعالیت شبکهتان از جمله ایمیل، برنامه و وبسایتها را کنترل کند.\n\nبرای دریافت اطلاعات بیشتر با سرپرستتان تماس بگیرید.\n\nهمچنین به یک VPN وصل هستید که میتواند فعالیت شبکه شما را کنترل کند."</string>
+ <string name="monitoring_description_vpn_profile_owned" msgid="2054949132145039290">"نمایه کاری شما توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت میشود.\n\nسرپرستتان میتواند فعالیت شبکهتان از جمله رایانامه، برنامه و وبسایتها را کنترل کند.\n\nبرای دریافت اطلاعات بیشتر با سرپرستتان تماس بگیرید.\n\nهمچنین به یک VPN وصل هستید که میتواند فعالیت شبکه شما را کنترل کند."</string>
<string name="legacy_vpn_name" msgid="6604123105765737830">"VPN"</string>
- <string name="monitoring_description_app" msgid="6259179342284742878">"شما به <xliff:g id="APPLICATION">%1$s</xliff:g> وصل شدهاید، که میتواند فعالیت شبکه شما از جمله ایمیل، برنامه و وبسایتها را کنترل کند."</string>
- <string name="monitoring_description_app_personal" msgid="484599052118316268">"شما به <xliff:g id="APPLICATION">%1$s</xliff:g> وصل شدهاید، که میتواند فعالیت شبکه شخصی شما از جمله ایمیل، برنامه و وبسایتها را کنترل کند."</string>
- <string name="monitoring_description_app_work" msgid="1754325860918060897">"نمایه کاریتان توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت میشود. این به <xliff:g id="APPLICATION">%2$s</xliff:g> وصل است که فعالیت شبکه کاریتان از جمله ایمیل، برنامه و وبسایتها را کنترل میکند.\n\nبرای دریافت اطلاعات بیشتر، با سرپرستتان تماس بگیرید."</string>
- <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"نمایه کاری شما توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت میشود. این به <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> متصل است که میتواند فعالیت شبکه کاریتان از جمله ایمیل، برنامه و وبسایتها را کنترل کند.\n\nشما همچنین به <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> متصل هستید که میتواند فعالیت شبکه شخصیتان را کنترل کند."</string>
- <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"دستگاهتان توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت میشود.\n\nسرپرستتان میتواند تنظیمات، دسترسی شرکت، برنامهها، دادههای مرتبط با دستگاهتان و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند.\n\nشما به <xliff:g id="APPLICATION">%2$s</xliff:g> وصل هستید که میتواند فعالیت شبکه شما را کنترل کند، از جمله ایمیل، برنامه و وبسایتها.\n\nبرای دریافت اطلاعات بیشتر، با سرپرستتان تماس بگیرید."</string>
+ <string name="monitoring_description_app" msgid="6259179342284742878">"شما به <xliff:g id="APPLICATION">%1$s</xliff:g> وصل شدهاید، که میتواند فعالیت شبکه شما از جمله رایانامه، برنامه و وبسایتها را کنترل کند."</string>
+ <string name="monitoring_description_app_personal" msgid="484599052118316268">"شما به <xliff:g id="APPLICATION">%1$s</xliff:g> وصل شدهاید، که میتواند فعالیت شبکه شخصی شما از جمله رایانامه، برنامه و وبسایتها را کنترل کند."</string>
+ <string name="monitoring_description_app_work" msgid="1754325860918060897">"نمایه کاریتان توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت میشود. این به <xliff:g id="APPLICATION">%2$s</xliff:g> وصل است که فعالیت شبکه کاریتان از جمله رایانامه، برنامه و وبسایتها را کنترل میکند.\n\nبرای دریافت اطلاعات بیشتر، با سرپرستتان تماس بگیرید."</string>
+ <string name="monitoring_description_app_personal_work" msgid="4946600443852045903">"نمایه کاری شما توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت میشود. این به <xliff:g id="APPLICATION_WORK">%2$s</xliff:g> متصل است که میتواند فعالیت شبکه کاریتان از جمله رایانامه، برنامه و وبسایتها را کنترل کند.\n\nشما همچنین به <xliff:g id="APPLICATION_PERSONAL">%3$s</xliff:g> متصل هستید که میتواند فعالیت شبکه شخصیتان را کنترل کند."</string>
+ <string name="monitoring_description_vpn_app_device_owned" msgid="4970443827043261703">"دستگاهتان توسط <xliff:g id="ORGANIZATION">%1$s</xliff:g> مدیریت میشود.\n\nسرپرستتان میتواند تنظیمات، دسترسی شرکت، برنامهها، دادههای مرتبط با دستگاهتان و اطلاعات مکان دستگاهتان را کنترل و مدیریت کند.\n\nشما به <xliff:g id="APPLICATION">%2$s</xliff:g> وصل هستید که میتواند فعالیت شبکه شما را کنترل کند، از جمله رایانامه، برنامه و وبسایتها.\n\nبرای دریافت اطلاعات بیشتر، با سرپرستتان تماس بگیرید."</string>
<string name="keyguard_indication_trust_disabled" msgid="7412534203633528135">"دستگاه قفل باقی میماند تا زمانی که قفل آن را به صورت دستی باز کنید"</string>
<string name="hidden_notifications_title" msgid="7139628534207443290">"دریافت سریعتر اعلانها"</string>
<string name="hidden_notifications_text" msgid="2326409389088668981">"قبل از باز کردن قفل آنها را مشاهده کنید"</string>
diff --git a/packages/SystemUI/res/values-fi/strings.xml b/packages/SystemUI/res/values-fi/strings.xml
index 2516fcf..490cbf7 100644
--- a/packages/SystemUI/res/values-fi/strings.xml
+++ b/packages/SystemUI/res/values-fi/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Sijaintipyynnöt aktiiviset"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tyhjennä kaikki ilmoitukset."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ilmoitusasetukset"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Asetukset – <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ruutu kääntyy automaattisesti."</string>
diff --git a/packages/SystemUI/res/values-fr-rCA/strings.xml b/packages/SystemUI/res/values-fr-rCA/strings.xml
index 732abb3..91e1ab4 100644
--- a/packages/SystemUI/res/values-fr-rCA/strings.xml
+++ b/packages/SystemUI/res/values-fr-rCA/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Paramètres de notification"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Paramètres de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
diff --git a/packages/SystemUI/res/values-fr/strings.xml b/packages/SystemUI/res/values-fr/strings.xml
index 00cb2a1..f15edc1 100644
--- a/packages/SystemUI/res/values-fr/strings.xml
+++ b/packages/SystemUI/res/values-fr/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Demandes de localisation actives"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Supprimer toutes les notifications"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> autres"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Paramètres de notification"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Paramètres de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"L\'écran pivote automatiquement."</string>
diff --git a/packages/SystemUI/res/values-gl-rES/strings.xml b/packages/SystemUI/res/values-gl-rES/strings.xml
index ae4a850..5581607 100644
--- a/packages/SystemUI/res/values-gl-rES/strings.xml
+++ b/packages/SystemUI/res/values-gl-rES/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitudes de localización activas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Eliminar todas as notificacións."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configuración das notificacións"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configuración de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A pantalla xirará automaticamente."</string>
diff --git a/packages/SystemUI/res/values-gu-rIN/strings.xml b/packages/SystemUI/res/values-gu-rIN/strings.xml
index 6743e83..971440a 100644
--- a/packages/SystemUI/res/values-gu-rIN/strings.xml
+++ b/packages/SystemUI/res/values-gu-rIN/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"સ્થાન વિનંતીઓ સક્રિય"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"બધા સૂચનો સાફ કરો."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"સૂચનાઓની સેટિંગ્સ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> સેટિંગ્સ"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"સ્ક્રીન આપમેળે ફરશે."</string>
diff --git a/packages/SystemUI/res/values-hi/strings.xml b/packages/SystemUI/res/values-hi/strings.xml
index 5d5db68..f5c32cc 100644
--- a/packages/SystemUI/res/values-hi/strings.xml
+++ b/packages/SystemUI/res/values-hi/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"स्थान अनुरोध सक्रिय"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सभी सूचनाएं साफ़ करें."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"नोटिफिकेशन सेटिंग"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> सेटिंग"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रीन स्वचालित रूप से घूमेगी."</string>
diff --git a/packages/SystemUI/res/values-hr/strings.xml b/packages/SystemUI/res/values-hr/strings.xml
index 6992940..f1ed472 100644
--- a/packages/SystemUI/res/values-hr/strings.xml
+++ b/packages/SystemUI/res/values-hr/strings.xml
@@ -246,6 +246,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Zahtjevi za lokaciju aktivni su"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Brisanje svih obavijesti."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"još <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Postavke obavijesti"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Postavke aplikacije <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon će se automatski zakrenuti."</string>
diff --git a/packages/SystemUI/res/values-hu/strings.xml b/packages/SystemUI/res/values-hu/strings.xml
index 022b76a..4ee0852 100644
--- a/packages/SystemUI/res/values-hu/strings.xml
+++ b/packages/SystemUI/res/values-hu/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktív helylekérések"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Minden értesítés törlése"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Értesítési beállítások"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> beállításai"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A képernyő automatikusan forogni fog."</string>
diff --git a/packages/SystemUI/res/values-hy-rAM/strings.xml b/packages/SystemUI/res/values-hy-rAM/strings.xml
index b7a333b..c39af93 100644
--- a/packages/SystemUI/res/values-hy-rAM/strings.xml
+++ b/packages/SystemUI/res/values-hy-rAM/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Տեղադրության հարցումներն ակտիվ են"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Մաքրել բոլոր ծանուցումները:"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ծանուցման կարգավորումներ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>-ի կարգավորումներ"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Էկրանը ինքնաշխատ կպտտվի:"</string>
diff --git a/packages/SystemUI/res/values-in/strings.xml b/packages/SystemUI/res/values-in/strings.xml
index b9aa766..d632e2e 100644
--- a/packages/SystemUI/res/values-in/strings.xml
+++ b/packages/SystemUI/res/values-in/strings.xml
@@ -187,7 +187,7 @@
<string name="accessibility_quick_settings_wifi" msgid="5518210213118181692">"<xliff:g id="SIGNAL">%1$s</xliff:g>."</string>
<string name="accessibility_quick_settings_wifi_changed_off" msgid="8716484460897819400">"Wi-Fi dinonaktifkan."</string>
<string name="accessibility_quick_settings_wifi_changed_on" msgid="6440117170789528622">"Wi-Fi diaktifkan."</string>
- <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Seluler <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
+ <string name="accessibility_quick_settings_mobile" msgid="4876806564086241341">"Ponsel <xliff:g id="SIGNAL">%1$s</xliff:g>. <xliff:g id="TYPE">%2$s</xliff:g>. <xliff:g id="NETWORK">%3$s</xliff:g>."</string>
<string name="accessibility_quick_settings_battery" msgid="1480931583381408972">"Baterai <xliff:g id="STATE">%s</xliff:g>."</string>
<string name="accessibility_quick_settings_airplane_off" msgid="7786329360056634412">"Mode pesawat nonaktif."</string>
<string name="accessibility_quick_settings_airplane_on" msgid="6406141469157599296">"Mode pesawat aktif."</string>
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Menghapus semua pemberitahuan."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Setelan pemberitahuan"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> setelan"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Layar akan diputar secara otomatis."</string>
@@ -378,7 +379,7 @@
<string name="user_logout_notification_text" msgid="3350262809611876284">"Keluarkan pengguna saat ini"</string>
<string name="user_logout_notification_action" msgid="1195428991423425062">"KELUARKAN PENGGUNA"</string>
<string name="user_add_user_title" msgid="4553596395824132638">"Tambahkan pengguna baru?"</string>
- <string name="user_add_user_message_short" msgid="2161624834066214559">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri.\n\n1Pengguna mana pun dapat memperbarui aplikasi untuk semua pengguna lain."</string>
+ <string name="user_add_user_message_short" msgid="2161624834066214559">"Saat Anda menambahkan pengguna baru, orang tersebut perlu menyiapkan ruangnya sendiri.\n\nPengguna mana pun dapat memperbarui aplikasi untuk semua pengguna lain."</string>
<string name="user_remove_user_title" msgid="4681256956076895559">"Hapus pengguna?"</string>
<string name="user_remove_user_message" msgid="1453218013959498039">"Semua aplikasi dan data pengguna ini akan dihapus."</string>
<string name="user_remove_user_remove" msgid="7479275741742178297">"Hapus"</string>
diff --git a/packages/SystemUI/res/values-is-rIS/strings.xml b/packages/SystemUI/res/values-is-rIS/strings.xml
index 45a07c1..b752ae3 100644
--- a/packages/SystemUI/res/values-is-rIS/strings.xml
+++ b/packages/SystemUI/res/values-is-rIS/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Staðsetningarbeiðnir virkar"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Hreinsa allar tilkynningar."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Tilkynningastillingar"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Stillingar fyrir <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skjárinn snýst sjálfkrafa."</string>
diff --git a/packages/SystemUI/res/values-it/strings.xml b/packages/SystemUI/res/values-it/strings.xml
index f352d50..6b5418e 100644
--- a/packages/SystemUI/res/values-it/strings.xml
+++ b/packages/SystemUI/res/values-it/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Richieste di accesso alla posizione attive"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Cancella tutte le notifiche."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Impostazioni di notifica"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Impostazioni di <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Lo schermo ruoterà automaticamente."</string>
diff --git a/packages/SystemUI/res/values-iw/strings.xml b/packages/SystemUI/res/values-iw/strings.xml
index 087d933..0377d45 100644
--- a/packages/SystemUI/res/values-iw/strings.xml
+++ b/packages/SystemUI/res/values-iw/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"בקשות מיקום פעילות"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"נקה את כל ההתראות."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"הגדרות עבור הודעות"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"הגדרות <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"המסך יסתובב באופן אוטומטי."</string>
diff --git a/packages/SystemUI/res/values-ja/strings.xml b/packages/SystemUI/res/values-ja/strings.xml
index aa27fff..12b7236 100644
--- a/packages/SystemUI/res/values-ja/strings.xml
+++ b/packages/SystemUI/res/values-ja/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"現在地リクエストがアクティブ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"通知をすべて消去。"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"他 <xliff:g id="NUMBER">%s</xliff:g> 件"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知設定"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>の設定"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"画面は自動的に回転します。"</string>
diff --git a/packages/SystemUI/res/values-ka-rGE/strings.xml b/packages/SystemUI/res/values-ka-rGE/strings.xml
index 24fc4a1..aaeae27 100644
--- a/packages/SystemUI/res/values-ka-rGE/strings.xml
+++ b/packages/SystemUI/res/values-ka-rGE/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"მდებარეობის მოთხოვნები აქტიურია"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ყველა შეტყობინების წაშლა"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"შეტყობინების პარამეტრები"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> პარამეტრები"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ეკრანი შეტრიალდება ავტომატურად."</string>
diff --git a/packages/SystemUI/res/values-kk-rKZ/strings.xml b/packages/SystemUI/res/values-kk-rKZ/strings.xml
index c91e8a5..c37ac69 100644
--- a/packages/SystemUI/res/values-kk-rKZ/strings.xml
+++ b/packages/SystemUI/res/values-kk-rKZ/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Орын өтініштері қосылған"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Барлық хабарларды жойыңыз."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Хабарландыру параметрлері"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> параметрлері"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран автоматты түрде бұрылады."</string>
diff --git a/packages/SystemUI/res/values-km-rKH/strings.xml b/packages/SystemUI/res/values-km-rKH/strings.xml
index 57da157..c66c972 100644
--- a/packages/SystemUI/res/values-km-rKH/strings.xml
+++ b/packages/SystemUI/res/values-km-rKH/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"សំណើទីតាំងសកម្ម"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"សម្អាតការជូនដំណឹងទាំងអស់។"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"កំណត់ការជូនដំណឹង"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"ការកំណត់ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"នឹងបង្វិលអេក្រង់ស្វ័យប្រវត្តិ។"</string>
diff --git a/packages/SystemUI/res/values-kn-rIN/strings.xml b/packages/SystemUI/res/values-kn-rIN/strings.xml
index 1c295e6..73ac69f 100644
--- a/packages/SystemUI/res/values-kn-rIN/strings.xml
+++ b/packages/SystemUI/res/values-kn-rIN/strings.xml
@@ -43,7 +43,7 @@
<string name="battery_saver_confirmation_ok" msgid="7507968430447930257">"ಆನ್ ಮಾಡು"</string>
<string name="battery_saver_start_action" msgid="5576697451677486320">"ಬ್ಯಾಟರಿ ಉಳಿತಾಯವನ್ನು ಆನ್ ಮಾಡಿ"</string>
<string name="status_bar_settings_settings_button" msgid="3023889916699270224">"ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
- <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"Wi-Fi"</string>
+ <string name="status_bar_settings_wifi_button" msgid="1733928151698311923">"ವೈ-ಫೈ"</string>
<string name="status_bar_settings_auto_rotation" msgid="3790482541357798421">"ಪರದೆಯನ್ನು ಸ್ವಯಂ-ತಿರುಗಿಸಿ"</string>
<string name="status_bar_settings_mute_label" msgid="554682549917429396">"ಮ್ಯೂಟ್"</string>
<string name="status_bar_settings_auto_brightness_label" msgid="511453614962324674">"ಸ್ವಯಂ"</string>
@@ -147,7 +147,7 @@
<string name="accessibility_data_connection_cdma" msgid="6132648193978823023">"CDMA"</string>
<string name="accessibility_data_connection_roaming" msgid="5977362333466556094">"ರೋಮಿಂಗ್"</string>
<string name="accessibility_data_connection_edge" msgid="4477457051631979278">"ಎಡ್ಜ್"</string>
- <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"Wi-Fi"</string>
+ <string name="accessibility_data_connection_wifi" msgid="2324496756590645221">"ವೈ-ಫೈ"</string>
<string name="accessibility_no_sim" msgid="8274017118472455155">"ಯಾವುದೇ ಸಿಮ್ ಇಲ್ಲ."</string>
<string name="accessibility_cell_data" msgid="7080312242791850520">"ಸೆಲ್ಯುಲರ್ ಡೇಟಾ"</string>
<string name="accessibility_cell_data_on" msgid="4310018593519761767">"ಸೆಲ್ಯುಲರ್ ಡೇಟಾ ಆನ್ ಆಗಿದೆ"</string>
@@ -239,12 +239,13 @@
<string name="data_usage_disabled_dialog" msgid="8453242888903772524">"ಏಕೆಂದರೆ ನಿಮ್ಮ ಹೊಂದಾಣಿಕೆ ಡೇಟಾ ಮೀತಿಯನ್ನು ತಲುಪಿದೆ, ಈ ಆವರ್ತನೆಯ ಉಳಿದ ಭಾಗಕ್ಕೆ ಸಾಧನವು ಡೇಟಾ ಬಳಕೆಯನ್ನು ವಿರಾಮಗೊಳಿಸಿದೆ.\n\nಮುಂದುವರೆಯುವಿಕೆಯು ನಿಮ್ಮ ವಾಹಕದ ಶುಲ್ಕಗಳಿಗೆ ಕಾರಣವಾಗಬಹುದು."</string>
<string name="data_usage_disabled_dialog_enable" msgid="1412395410306390593">"ಮುಂದುವರಿಸು"</string>
<string name="status_bar_settings_signal_meter_disconnected" msgid="1940231521274147771">"ಇಂಟರ್ನೆಟ್ ಸಂಪರ್ಕವಿಲ್ಲ"</string>
- <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"Wi-Fi ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
+ <string name="status_bar_settings_signal_meter_wifi_nossid" msgid="6557486452774597820">"ವೈ-ಫೈ ಸಂಪರ್ಕಗೊಂಡಿದೆ"</string>
<string name="gps_notification_searching_text" msgid="8574247005642736060">"GPS ಗಾಗಿ ಹುಡುಕಲಾಗುತ್ತಿದೆ"</string>
<string name="gps_notification_found_text" msgid="4619274244146446464">"ಸ್ಥಾನವನ್ನು GPS ಮೂಲಕ ಹೊಂದಿಸಲಾಗಿದೆ"</string>
<string name="accessibility_location_active" msgid="2427290146138169014">"ಸ್ಥಾನ ವಿನಂತಿಗಳು ಸಕ್ರಿಯವಾಗಿವೆ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ಎಲ್ಲಾ ಅಧಿಸೂಚನೆಗಳನ್ನು ತೆರವುಗೊಳಿಸು."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"ಅಧಿಸೂಚನೆ ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ಸೆಟ್ಟಿಂಗ್ಗಳು"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ಪರದೆಯು ಸ್ವಯಂಚಾಲಿತವಾಗಿ ತಿರುಗುತ್ತದೆ."</string>
@@ -282,10 +283,10 @@
<string name="quick_settings_user_label" msgid="5238995632130897840">"ನಾನು"</string>
<string name="quick_settings_user_title" msgid="4467690427642392403">"ಬಳಕೆದಾರ"</string>
<string name="quick_settings_user_new_user" msgid="9030521362023479778">"ಹೊಸ ಬಳಕೆದಾರರು"</string>
- <string name="quick_settings_wifi_label" msgid="9135344704899546041">"Wi-Fi"</string>
+ <string name="quick_settings_wifi_label" msgid="9135344704899546041">"ವೈ-ಫೈ"</string>
<string name="quick_settings_wifi_not_connected" msgid="7171904845345573431">"ಸಂಪರ್ಕಗೊಂಡಿಲ್ಲ"</string>
<string name="quick_settings_wifi_no_network" msgid="2221993077220856376">"ನೆಟ್ವರ್ಕ್ ಇಲ್ಲ"</string>
- <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"Wi-Fi ಆಫ್"</string>
+ <string name="quick_settings_wifi_off_label" msgid="7558778100843885864">"ವೈ-ಫೈ ಆಫ್"</string>
<string name="quick_settings_wifi_on_label" msgid="7607810331387031235">"ವೈ-ಫೈ ಆನ್ ಆಗಿದೆ"</string>
<string name="quick_settings_wifi_detail_empty_text" msgid="269990350383909226">"ಯಾವುದೇ ವೈ-ಫೈ ನೆಟ್ವರ್ಕ್ಗಳು ಲಭ್ಯವಿಲ್ಲ"</string>
<string name="quick_settings_cast_title" msgid="7709016546426454729">"ಬಿತ್ತರಿಸುವಿಕೆ"</string>
diff --git a/packages/SystemUI/res/values-ko/strings.xml b/packages/SystemUI/res/values-ko/strings.xml
index 9eba956..790e7ff 100644
--- a/packages/SystemUI/res/values-ko/strings.xml
+++ b/packages/SystemUI/res/values-ko/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"위치 요청 있음"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"모든 알림 지우기"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g>개 더보기"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"알림 설정"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> 설정"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"화면이 자동으로 회전됩니다."</string>
diff --git a/packages/SystemUI/res/values-ky-rKG/strings.xml b/packages/SystemUI/res/values-ky-rKG/strings.xml
index 1dd6636..7b5496e 100644
--- a/packages/SystemUI/res/values-ky-rKG/strings.xml
+++ b/packages/SystemUI/res/values-ky-rKG/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Жайгаштыруу талаптары иштелүүдө"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Бардык эскертмелерди тазалоо."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Эскертме жөндөөлөрү"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> жөндөөлөрү"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран автоматтык түрдө бурулат."</string>
diff --git a/packages/SystemUI/res/values-lo-rLA/strings.xml b/packages/SystemUI/res/values-lo-rLA/strings.xml
index 4fd8485..f09f647 100644
--- a/packages/SystemUI/res/values-lo-rLA/strings.xml
+++ b/packages/SystemUI/res/values-lo-rLA/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"ການຮ້ອງຂໍສະຖານທີ່ທີ່ເຮັດວຽກຢູ່"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ລຶບການແຈ້ງເຕືອນທັງໝົດ."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"ການຕັ້ງຄ່າການແຈ້ງເຕືອນ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"ການຕັ້ງຄ່າ <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ໜ້າຈໍຈະໝຸນໂດຍອັດຕະໂນມັດ."</string>
diff --git a/packages/SystemUI/res/values-lt/strings.xml b/packages/SystemUI/res/values-lt/strings.xml
index 72af899..566073a 100644
--- a/packages/SystemUI/res/values-lt/strings.xml
+++ b/packages/SystemUI/res/values-lt/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Vietovės užklausos aktyvios"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Išvalyti visus pranešimus."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"Dar <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Pranešimų nustatymai"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"„<xliff:g id="APP_NAME">%s</xliff:g>“ nustatymai"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekranas bus sukamas automatiškai."</string>
diff --git a/packages/SystemUI/res/values-lv/strings.xml b/packages/SystemUI/res/values-lv/strings.xml
index 2754268..016c74a 100644
--- a/packages/SystemUI/res/values-lv/strings.xml
+++ b/packages/SystemUI/res/values-lv/strings.xml
@@ -246,6 +246,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktīvi atrašanās vietu pieprasījumi"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Notīrīt visus paziņojumus"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"vēl <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Paziņojumu iestatījumi"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> iestatījumi"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekrāns tiks pagriezts automātiski."</string>
diff --git a/packages/SystemUI/res/values-mk-rMK/strings.xml b/packages/SystemUI/res/values-mk-rMK/strings.xml
index 8f0e3ab..13e2ed8 100644
--- a/packages/SystemUI/res/values-mk-rMK/strings.xml
+++ b/packages/SystemUI/res/values-mk-rMK/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Активни барања за локација"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Исчисти ги сите известувања."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Поставки на известувања"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Поставки на <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екранот ќе ротира автоматски."</string>
diff --git a/packages/SystemUI/res/values-ml-rIN/strings.xml b/packages/SystemUI/res/values-ml-rIN/strings.xml
index 8631fd5..d52ea5f 100644
--- a/packages/SystemUI/res/values-ml-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ml-rIN/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"ലൊക്കേഷൻ അഭ്യർത്ഥനകൾ സജീവമാണ്"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"എല്ലാ വിവരങ്ങളും മായ്ക്കുക."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"അറിയിപ്പ് ക്രമീകരണങ്ങൾ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ക്രമീകരണം"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"സ്ക്രീൻ സ്വയമേവ തിരിയും."</string>
@@ -326,7 +327,7 @@
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"തിരശ്ചീനമായി വേർതിരിക്കുക"</string>
<string name="recents_multistack_add_stack_dialog_split_vertical" msgid="9075292233696180813">"ലംബമായി വേർതിരിക്കുക"</string>
<string name="recents_multistack_add_stack_dialog_split_custom" msgid="4177837597513701943">"ഇഷ്ടാനുസൃതമായി വേർതിരിക്കുക"</string>
- <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ചാർജ്ജുചെയ്തു"</string>
+ <string name="expanded_header_battery_charged" msgid="5945855970267657951">"ചാർജായി"</string>
<string name="expanded_header_battery_charging" msgid="205623198487189724">"ചാർജ്ജുചെയ്യുന്നു"</string>
<string name="expanded_header_battery_charging_with_time" msgid="457559884275395376">"പൂർണ്ണമായും ചാർജ്ജാകുന്നതിന്, <xliff:g id="CHARGING_TIME">%s</xliff:g>"</string>
<string name="expanded_header_battery_not_charging" msgid="4798147152367049732">"ചാർജ്ജുചെയ്യുന്നില്ല"</string>
diff --git a/packages/SystemUI/res/values-mn-rMN/strings.xml b/packages/SystemUI/res/values-mn-rMN/strings.xml
index 278468a..c373b78 100644
--- a/packages/SystemUI/res/values-mn-rMN/strings.xml
+++ b/packages/SystemUI/res/values-mn-rMN/strings.xml
@@ -243,6 +243,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Байршлын хүсэлтүүд идэвхтэй"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Бүх мэдэгдлийг цэвэрлэх."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Мэдэгдлийн тохиргоо"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> тохиргоо"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Дэлгэц автоматаар эргэнэ."</string>
diff --git a/packages/SystemUI/res/values-mr-rIN/strings.xml b/packages/SystemUI/res/values-mr-rIN/strings.xml
index 3aef30b..9d71a2f 100644
--- a/packages/SystemUI/res/values-mr-rIN/strings.xml
+++ b/packages/SystemUI/res/values-mr-rIN/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"स्थान विनंत्या सक्रिय"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सर्व सूचना साफ करा."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"सूचना सेटिंग्ज"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> सेटिंग्ज"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रीन स्वयंचलितपणे फिरेल."</string>
diff --git a/packages/SystemUI/res/values-ms-rMY/strings.xml b/packages/SystemUI/res/values-ms-rMY/strings.xml
index 3c3e7a5..e9abfa3 100644
--- a/packages/SystemUI/res/values-ms-rMY/strings.xml
+++ b/packages/SystemUI/res/values-ms-rMY/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Permintaan lokasi aktif"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Padamkan semua pemberitahuan."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Tetapan pemberitahuan"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> tetapan"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrin akan berputar secara automatik."</string>
diff --git a/packages/SystemUI/res/values-my-rMM/strings.xml b/packages/SystemUI/res/values-my-rMM/strings.xml
index 15a5fbf..62c26d3 100644
--- a/packages/SystemUI/res/values-my-rMM/strings.xml
+++ b/packages/SystemUI/res/values-my-rMM/strings.xml
@@ -20,7 +20,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="7164937344850004466">"စနစ်၏UI"</string>
- <string name="status_bar_clear_all_button" msgid="7774721344716731603">"ရှင်းလင်းရန်"</string>
+ <string name="status_bar_clear_all_button" msgid="7774721344716731603">"ဖယ်ရှားရန်"</string>
<string name="status_bar_recent_remove_item_title" msgid="6026395868129852968">"စာရင်းမှ ဖယ်မည်"</string>
<string name="status_bar_recent_inspect_item_title" msgid="7793624864528818569">"အပ်ပလီကေးရှင်း အချက်အလက်များ"</string>
<string name="status_bar_no_recent_apps" msgid="7374907845131203189">"သင်၏ မကြာမီက မျက်နှာပြင်များ ဒီမှာ ပေါ်လာကြမည်"</string>
@@ -96,7 +96,7 @@
<string name="voice_assist_label" msgid="3956854378310019854">"အသံ အကူအညီအား ဖွင့်ရန်"</string>
<string name="camera_label" msgid="7261107956054836961">"ကင်မရာ ဖွင့်ရန်"</string>
<string name="recents_caption_resize" msgid="3517056471774958200">"အလုပ်သစ်စီစဥ်မှုကို ရွေးပါ။"</string>
- <string name="cancel" msgid="6442560571259935130">"ဖျက်သိမ်းရန်"</string>
+ <string name="cancel" msgid="6442560571259935130">"မလုပ်တော့ပါ"</string>
<string name="accessibility_compatibility_zoom_button" msgid="8461115318742350699">"အံ့ဝင်သောချုံ့ချဲ့ခလုတ်"</string>
<string name="accessibility_compatibility_zoom_example" msgid="4220687294564945780">"ဖန်သားပြင်ပေါ်တွင် အသေးမှအကြီးသို့ချဲ့ခြင်း"</string>
<string name="accessibility_bluetooth_connected" msgid="2707027633242983370">"ဘလူးတုသ်ချိတ်ဆက်ထားမှု"</string>
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"တည်နေရာပြ တောင်းဆိုချက်များ အသက်ဝင်ရန်"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"သတိပေးချက်အားလုံးအား ဖယ်ရှားခြင်း။"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"အကြောင်းကြားချက် ဆက်တင်များ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ဆက်တင်များ"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ဖန်သားပြင်ပေါ်မှာ ပြသမှုက အလိုအလျောက် လှည့်သွားပါမည်"</string>
@@ -320,7 +321,7 @@
<string name="recents_search_bar_label" msgid="8074997400187836677">"ရှာဖွေရန်"</string>
<string name="recents_launch_error_message" msgid="2969287838120550506">"<xliff:g id="APP">%s</xliff:g> ကို မစနိုင်ပါ။"</string>
<string name="recents_launch_disabled_message" msgid="1624523193008871793">"<xliff:g id="APP">%s</xliff:g> ကို ဘေးကင်းလုံခြုံသည့်မုဒ်တွင် ပိတ်ထားပါသည်။"</string>
- <string name="recents_stack_action_button_label" msgid="6593727103310426253">"အားလုံး ရှင်းလင်းပါ"</string>
+ <string name="recents_stack_action_button_label" msgid="6593727103310426253">"အားလုံး ဖယ်ရှားပါ"</string>
<string name="recents_incompatible_app_message" msgid="5075812958564082451">"အက်ပ်သည် မျက်နှာပြင်ခွဲ၍ ပြသခြင်းကို ပံ့ပိုးမထားပါ"</string>
<string name="recents_drag_hint_message" msgid="2649739267073203985">"မျက်နှာပြင် ခွဲခြမ်းပြသခြင်းကို အသုံးပြုရန် ဤနေရာသို့ ပွတ်၍ဆွဲထည့်ပါ"</string>
<string name="recents_multistack_add_stack_dialog_split_horizontal" msgid="8848514474543427332">"ရေပြင်ညီ ပိုင်းမည်"</string>
@@ -387,7 +388,7 @@
<string name="battery_saver_notification_action_text" msgid="109158658238110382">"ဘက်ထရီ ချွေတာမှုကို ပိတ်ထားရန်"</string>
<string name="media_projection_dialog_text" msgid="3071431025448218928">"<xliff:g id="APP_SEEKING_PERMISSION">%s</xliff:g> က သင်၏ မျက်နှာပြင် ပေါ်မှာ ပြသထားသည့် အရာတိုင်းကို စတင် ဖမ်းယူမည်။"</string>
<string name="media_projection_remember_text" msgid="3103510882172746752">"နောက်ထပ် မပြပါနှင့်"</string>
- <string name="clear_all_notifications_text" msgid="814192889771462828">"အားလုံး ရှင်းလင်းရန်"</string>
+ <string name="clear_all_notifications_text" msgid="814192889771462828">"အားလုံး ဖယ်ရှားရန်"</string>
<string name="media_projection_action_text" msgid="8470872969457985954">"ယခု စတင်ပါ"</string>
<string name="empty_shade_text" msgid="708135716272867002">"အကြောင်းကြားချက်များ မရှိ"</string>
<string name="device_owned_footer" msgid="3802752663326030053">"ကိရိယာကို စောင့်ကြပ် နိုင်ပါသည်"</string>
@@ -419,8 +420,8 @@
<string name="accessibility_volume_collapse" msgid="3609549593031810875">"ခေါက်သိမ်းရန်..."</string>
<string name="screen_pinning_title" msgid="3273740381976175811">"မျက်နှာပြင် ပင်ထိုးပြီးပါပြီ"</string>
<string name="screen_pinning_description" msgid="7238941806855968768">"သင်က ပင်မဖြုတ်မချင်း ၎င်းကိုပြသထားပါမည်။ ပင်ဖြုတ်ရန် \'နောက်သို့\' ကိုထိပြီး ဖိထားပါ။"</string>
- <string name="screen_pinning_positive" msgid="3783985798366751226">"အဲဒါ ရပြီ"</string>
- <string name="screen_pinning_negative" msgid="3741602308343880268">"မလို ကျေးဇူးပဲ"</string>
+ <string name="screen_pinning_positive" msgid="3783985798366751226">"အဲဒါ ရပါပြီ"</string>
+ <string name="screen_pinning_negative" msgid="3741602308343880268">"မလိုတော့ပါ"</string>
<string name="quick_settings_reset_confirmation_title" msgid="748792586749897883">"<xliff:g id="TILE_LABEL">%1$s</xliff:g> ဝှက်မည်လား?"</string>
<string name="quick_settings_reset_confirmation_message" msgid="2235970126803317374">"နောက်တစ်ကြိမ်သင် ချိန်ညှိချက်များဖွင့်လျှင် ၎င်းပေါ်လာပါမည်။"</string>
<string name="quick_settings_reset_confirmation_button" msgid="2660339101868367515">"ဖျောက်ထားမည်"</string>
diff --git a/packages/SystemUI/res/values-nb/strings.xml b/packages/SystemUI/res/values-nb/strings.xml
index eb575da..156af78 100644
--- a/packages/SystemUI/res/values-nb/strings.xml
+++ b/packages/SystemUI/res/values-nb/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktive stedsforespørsler"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Fjern alle varslinger."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Varselinnstillinger"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>-innstillinger"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skjermen roterer automatisk."</string>
diff --git a/packages/SystemUI/res/values-ne-rNP/strings.xml b/packages/SystemUI/res/values-ne-rNP/strings.xml
index f473d8e..7ff0ff2 100644
--- a/packages/SystemUI/res/values-ne-rNP/strings.xml
+++ b/packages/SystemUI/res/values-ne-rNP/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"स्थान अनुरोधहरू सक्रिय"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"सबै सूचनाहरू हटाउनुहोस्।"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"अधिसूचना सेटिङ्हरू"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> सेटिङ्हरू"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"स्क्रिन स्वतः घुम्ने छ।"</string>
diff --git a/packages/SystemUI/res/values-nl/strings.xml b/packages/SystemUI/res/values-nl/strings.xml
index 727285e..d5e0c54 100644
--- a/packages/SystemUI/res/values-nl/strings.xml
+++ b/packages/SystemUI/res/values-nl/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Locatieverzoeken actief"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Alle meldingen wissen."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Instellingen voor meldingen"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>-instellingen"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Scherm wordt automatisch geroteerd."</string>
diff --git a/packages/SystemUI/res/values-pa-rIN/strings.xml b/packages/SystemUI/res/values-pa-rIN/strings.xml
index e124fa2..59a92e6 100644
--- a/packages/SystemUI/res/values-pa-rIN/strings.xml
+++ b/packages/SystemUI/res/values-pa-rIN/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"ਨਿਰਧਾਰਿਤ ਸਥਾਨ ਸੇਵਾ ਬੇਨਤੀਆਂ ਸਕਿਰਿਆ"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ਸਾਰੀਆਂ ਸੂਚਨਾਵਾਂ ਹਟਾਓ।"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"ਸੂਚਨਾ ਸੈਟਿੰਗਾਂ"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ਸੈਟਿੰਗਾਂ"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"ਸਕ੍ਰੀਨ ਆਟੋਮੈਟਿਕਲੀ ਰੋਟੇਟ ਕਰੇਗੀ।"</string>
diff --git a/packages/SystemUI/res/values-pl/strings.xml b/packages/SystemUI/res/values-pl/strings.xml
index dd7e4e6..eb13755 100644
--- a/packages/SystemUI/res/values-pl/strings.xml
+++ b/packages/SystemUI/res/values-pl/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Prośby o lokalizację są aktywne"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Usuń wszystkie powiadomienia."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Ustawienia powiadomień"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Ustawienia aplikacji <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran zostanie obrócony automatycznie."</string>
diff --git a/packages/SystemUI/res/values-pt-rBR/strings.xml b/packages/SystemUI/res/values-pt-rBR/strings.xml
index a315cec..16d9ac2 100644
--- a/packages/SystemUI/res/values-pt-rBR/strings.xml
+++ b/packages/SystemUI/res/values-pt-rBR/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"Mais <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configurações de notificação"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configurações de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
diff --git a/packages/SystemUI/res/values-pt-rPT/strings.xml b/packages/SystemUI/res/values-pt-rPT/strings.xml
index 07604b1..489e4d2 100644
--- a/packages/SystemUI/res/values-pt-rPT/strings.xml
+++ b/packages/SystemUI/res/values-pt-rPT/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Pedidos de localização ativos"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Definições de notificação"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Definições do <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"O ecrã será rodado automaticamente."</string>
diff --git a/packages/SystemUI/res/values-pt/strings.xml b/packages/SystemUI/res/values-pt/strings.xml
index a315cec..16d9ac2 100644
--- a/packages/SystemUI/res/values-pt/strings.xml
+++ b/packages/SystemUI/res/values-pt/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitações de localização ativas"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Limpar todas as notificações."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"Mais <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Configurações de notificação"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Configurações de <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"A tela girará automaticamente."</string>
diff --git a/packages/SystemUI/res/values-ro/strings.xml b/packages/SystemUI/res/values-ro/strings.xml
index 9b52ffd..76a0bf1 100644
--- a/packages/SystemUI/res/values-ro/strings.xml
+++ b/packages/SystemUI/res/values-ro/strings.xml
@@ -248,6 +248,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Solicitări locație active"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ștergeți toate notificările."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Setări pentru notificări"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Setări <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ecranul se va roti în mod automat."</string>
diff --git a/packages/SystemUI/res/values-ru/strings.xml b/packages/SystemUI/res/values-ru/strings.xml
index 978684e..180cfbd 100644
--- a/packages/SystemUI/res/values-ru/strings.xml
+++ b/packages/SystemUI/res/values-ru/strings.xml
@@ -249,6 +249,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Есть активные запросы на определение местоположения"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Удалить все уведомления"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Настройки уведомлений"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Настройки приложения \"<xliff:g id="APP_NAME">%s</xliff:g>\""</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Экран будет поворачиваться автоматически."</string>
diff --git a/packages/SystemUI/res/values-si-rLK/strings.xml b/packages/SystemUI/res/values-si-rLK/strings.xml
index c845a38..f76685c 100644
--- a/packages/SystemUI/res/values-si-rLK/strings.xml
+++ b/packages/SystemUI/res/values-si-rLK/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"පිහිටීම් ඉල්ලීම් සක්රියයි"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"සියලු දැනුම්දීම් හිස් කරන්න."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"දැනුම්දීම් සැකසීම්"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> සැකසීම්"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"තිරය ස්වයංක්රීයව කරකැවේ."</string>
diff --git a/packages/SystemUI/res/values-sk/strings.xml b/packages/SystemUI/res/values-sk/strings.xml
index 65e2a92..27441d9 100644
--- a/packages/SystemUI/res/values-sk/strings.xml
+++ b/packages/SystemUI/res/values-sk/strings.xml
@@ -249,6 +249,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Žiadosti o polohu sú aktívne"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Vymazať všetky upozornenia."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Nastavenia upozornení"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Nastavenia aplikácie <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Obrazovka sa automaticky otočí."</string>
diff --git a/packages/SystemUI/res/values-sl/strings.xml b/packages/SystemUI/res/values-sl/strings.xml
index 66334d4..3db3f23 100644
--- a/packages/SystemUI/res/values-sl/strings.xml
+++ b/packages/SystemUI/res/values-sl/strings.xml
@@ -249,6 +249,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktivne zahteve za lokacijo"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Izbriši vsa obvestila."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"in <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Nastavitve obvestil"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Nastavitve aplikacije <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Zaslon se bo samodejno zasukal."</string>
diff --git a/packages/SystemUI/res/values-sq-rAL/strings.xml b/packages/SystemUI/res/values-sq-rAL/strings.xml
index 14f840e..2f83878 100644
--- a/packages/SystemUI/res/values-sq-rAL/strings.xml
+++ b/packages/SystemUI/res/values-sq-rAL/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Kërkesat për vendodhje janë aktive"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Pastro të gjitha njoftimet."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Cilësimet e njoftimeve"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Cilësimet e <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekrani do të rrotullohet automatikisht."</string>
diff --git a/packages/SystemUI/res/values-sr/strings.xml b/packages/SystemUI/res/values-sr/strings.xml
index 437a4d8..37d0627 100644
--- a/packages/SystemUI/res/values-sr/strings.xml
+++ b/packages/SystemUI/res/values-sr/strings.xml
@@ -246,6 +246,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Има активних захтева за локацију"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Обриши сва обавештења."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"и још <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Подешавања обавештења"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Подешавања за <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екран ће се аутоматски ротирати."</string>
diff --git a/packages/SystemUI/res/values-sv/strings.xml b/packages/SystemUI/res/values-sv/strings.xml
index e20986a..59fb237 100644
--- a/packages/SystemUI/res/values-sv/strings.xml
+++ b/packages/SystemUI/res/values-sv/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Det finns aktiva platsbegäranden"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Ta bort alla meddelanden."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> till"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Aviseringsinställningar"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Inställningar för <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skärmen roteras automatiskt."</string>
diff --git a/packages/SystemUI/res/values-sw/strings.xml b/packages/SystemUI/res/values-sw/strings.xml
index 3fe37b9..3303f6a 100644
--- a/packages/SystemUI/res/values-sw/strings.xml
+++ b/packages/SystemUI/res/values-sw/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Maombi ya eneo yanatumika"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Futa arifa zote."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Mipangilio ya arifa"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Mipangilio ya <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Skrini itazunguka kiotomatiki."</string>
diff --git a/packages/SystemUI/res/values-ta-rIN/strings.xml b/packages/SystemUI/res/values-ta-rIN/strings.xml
index d385ce0..fe70b07 100644
--- a/packages/SystemUI/res/values-ta-rIN/strings.xml
+++ b/packages/SystemUI/res/values-ta-rIN/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"இருப்பிடக் கோரிக்கைகள் இயக்கப்பட்டன"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"எல்லா அறிவிப்புகளையும் அழி."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"அறிவிப்பு அமைப்புகள்"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> அமைப்புகள்"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"திரை தானாகச் சுழலும்."</string>
diff --git a/packages/SystemUI/res/values-te-rIN/strings.xml b/packages/SystemUI/res/values-te-rIN/strings.xml
index 5e19564..016c22d 100644
--- a/packages/SystemUI/res/values-te-rIN/strings.xml
+++ b/packages/SystemUI/res/values-te-rIN/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"స్థాన అభ్యర్థనలు సక్రియంగా ఉన్నాయి"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"అన్ని నోటిఫికేషన్లను క్లియర్ చేయండి."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"నోటిఫికేషన్ సెట్టింగ్లు"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> సెట్టింగ్లు"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"స్క్రీన్ స్వయంచాలకంగా తిప్పబడుతుంది."</string>
diff --git a/packages/SystemUI/res/values-th/strings.xml b/packages/SystemUI/res/values-th/strings.xml
index c4b5152..363a8fc 100644
--- a/packages/SystemUI/res/values-th/strings.xml
+++ b/packages/SystemUI/res/values-th/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"คำขอตำแหน่งที่มีการใช้งาน"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"ล้างการแจ้งเตือนทั้งหมด"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"การตั้งค่าการแจ้งเตือน"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"การตั้งค่า <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"หน้าจอจะหมุนโดยอัตโนมัติ"</string>
diff --git a/packages/SystemUI/res/values-tl/strings.xml b/packages/SystemUI/res/values-tl/strings.xml
index d618073..7731a58 100644
--- a/packages/SystemUI/res/values-tl/strings.xml
+++ b/packages/SystemUI/res/values-tl/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Aktibo ang mga kahilingan ng lokasyon"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"I-clear ang lahat ng notification."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Mga setting ng notification"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Mg setting ng <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Awtomatikong iikot ang screen."</string>
diff --git a/packages/SystemUI/res/values-tr/strings.xml b/packages/SystemUI/res/values-tr/strings.xml
index 2763468..980a14c 100644
--- a/packages/SystemUI/res/values-tr/strings.xml
+++ b/packages/SystemUI/res/values-tr/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Konum bilgisi istekleri etkin"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Tüm bildirimleri temizle"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildirim ayarları"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ayarları"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran otomatik olarak dönecektir."</string>
diff --git a/packages/SystemUI/res/values-uk/strings.xml b/packages/SystemUI/res/values-uk/strings.xml
index 9d7cb91..6c4df69 100644
--- a/packages/SystemUI/res/values-uk/strings.xml
+++ b/packages/SystemUI/res/values-uk/strings.xml
@@ -249,6 +249,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Запити про місцезнаходження активні"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Очистити всі сповіщення."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Налаштування сповіщень"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Налаштування додатка <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Екран обертатиметься автоматично."</string>
diff --git a/packages/SystemUI/res/values-ur-rPK/strings.xml b/packages/SystemUI/res/values-ur-rPK/strings.xml
index 682ca3c..49a1e78 100644
--- a/packages/SystemUI/res/values-ur-rPK/strings.xml
+++ b/packages/SystemUI/res/values-ur-rPK/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"مقام کی درخواستیں فعال ہیں"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"سبھی اطلاعات صاف کریں۔"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"<xliff:g id="NUMBER">%s</xliff:g> +"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"اطلاع کی ترتیبات"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> ترتیبات"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"اسکرین خود بخود گردش کرے گی۔"</string>
diff --git a/packages/SystemUI/res/values-uz-rUZ/strings.xml b/packages/SystemUI/res/values-uz-rUZ/strings.xml
index d5156e4..b577bad 100644
--- a/packages/SystemUI/res/values-uz-rUZ/strings.xml
+++ b/packages/SystemUI/res/values-uz-rUZ/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Joylashuv so‘rovlari yoniq"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Barcha eslatmalarni tozalash."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Bildirishnoma sozlamalari"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> sozlamalari"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Ekran avtomatik buriladi."</string>
@@ -278,7 +279,7 @@
<string name="quick_settings_location_off_label" msgid="7464544086507331459">"Joylashuv xizmati o‘chiq"</string>
<string name="quick_settings_media_device_label" msgid="1302906836372603762">"Media qurilma"</string>
<string name="quick_settings_rssi_label" msgid="7725671335550695589">"RSSI"</string>
- <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Favqulodda qo‘ng‘iroqlar"</string>
+ <string name="quick_settings_rssi_emergency_only" msgid="2713774041672886750">"Favqulodda chaqiruvlar"</string>
<string name="quick_settings_settings_label" msgid="5326556592578065401">"Sozlamalar"</string>
<string name="quick_settings_time_label" msgid="4635969182239736408">"Vaqt"</string>
<string name="quick_settings_user_label" msgid="5238995632130897840">"Men"</string>
@@ -535,7 +536,7 @@
<string name="keyboard_key_backspace" msgid="1559580097512385854">"Backspace"</string>
<string name="keyboard_key_media_play_pause" msgid="3861975717393887428">"Ijro/Pauza"</string>
<string name="keyboard_key_media_stop" msgid="2859963958595908962">"To‘xtatish"</string>
- <string name="keyboard_key_media_next" msgid="1894394911630345607">"Keyingi"</string>
+ <string name="keyboard_key_media_next" msgid="1894394911630345607">"Keyingisi"</string>
<string name="keyboard_key_media_previous" msgid="4256072387192967261">"Avvalgi"</string>
<string name="keyboard_key_media_rewind" msgid="2654808213360820186">"Orqaga qaytarish"</string>
<string name="keyboard_key_media_fast_forward" msgid="3849417047738200605">"Oldinga o‘tkazish"</string>
diff --git a/packages/SystemUI/res/values-vi/strings.xml b/packages/SystemUI/res/values-vi/strings.xml
index 9ded699..7638819 100644
--- a/packages/SystemUI/res/values-vi/strings.xml
+++ b/packages/SystemUI/res/values-vi/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Yêu cầu về thông tin vị trí đang hoạt động"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Xóa tất cả thông báo."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Cài đặt thông báo"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"Cài đặt <xliff:g id="APP_NAME">%s</xliff:g>"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Màn hình sẽ xoay tự động."</string>
diff --git a/packages/SystemUI/res/values-zh-rCN/strings.xml b/packages/SystemUI/res/values-zh-rCN/strings.xml
index a11dc0e..b5c6be8 100644
--- a/packages/SystemUI/res/values-zh-rCN/strings.xml
+++ b/packages/SystemUI/res/values-zh-rCN/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"应用发出了有效位置信息请求"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知设置"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>设置"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"屏幕会自动旋转。"</string>
diff --git a/packages/SystemUI/res/values-zh-rHK/strings.xml b/packages/SystemUI/res/values-zh-rHK/strings.xml
index dd7db86..ab9059d 100644
--- a/packages/SystemUI/res/values-zh-rHK/strings.xml
+++ b/packages/SystemUI/res/values-zh-rHK/strings.xml
@@ -247,6 +247,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"位置要求啟動中"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知設定"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>設定"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"螢幕會自動旋轉。"</string>
diff --git a/packages/SystemUI/res/values-zh-rTW/strings.xml b/packages/SystemUI/res/values-zh-rTW/strings.xml
index 7764073..dc6eebd 100644
--- a/packages/SystemUI/res/values-zh-rTW/strings.xml
+++ b/packages/SystemUI/res/values-zh-rTW/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"有位置資訊要求"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"清除所有通知。"</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"通知設定"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g>設定"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"螢幕會自動旋轉。"</string>
diff --git a/packages/SystemUI/res/values-zu/strings.xml b/packages/SystemUI/res/values-zu/strings.xml
index 0fecc0a..aa5be57 100644
--- a/packages/SystemUI/res/values-zu/strings.xml
+++ b/packages/SystemUI/res/values-zu/strings.xml
@@ -245,6 +245,7 @@
<string name="accessibility_location_active" msgid="2427290146138169014">"Izicelo zendawo ziyasebenza"</string>
<string name="accessibility_clear_all" msgid="5235938559247164925">"Susa zonke izaziso."</string>
<string name="notification_group_overflow_indicator" msgid="1863231301642314183">"+ <xliff:g id="NUMBER">%s</xliff:g>"</string>
+ <!-- no translation found for notification_group_overflow_description (4579313201268495404) -->
<string name="status_bar_notification_inspect_item_title" msgid="5668348142410115323">"Izilungiselelo zesaziso"</string>
<string name="status_bar_notification_app_settings_title" msgid="5525260160341558869">"<xliff:g id="APP_NAME">%s</xliff:g> izilungiselelo"</string>
<string name="accessibility_rotation_lock_off" msgid="4062780228931590069">"Isikrini sizophenduka ngokuzenzakalela."</string>
diff --git a/packages/SystemUI/res/values/dimens.xml b/packages/SystemUI/res/values/dimens.xml
index 677dbe5..eef5717 100644
--- a/packages/SystemUI/res/values/dimens.xml
+++ b/packages/SystemUI/res/values/dimens.xml
@@ -138,6 +138,9 @@
<!-- Height of the status bar header bar when on Keyguard -->
<dimen name="status_bar_header_height_keyguard">40dp</dimen>
+ <!-- Margin start of the system icons super container -->
+ <dimen name="system_icons_super_container_margin_start">16dp</dimen>
+
<!-- Width for the notification panel and related windows -->
<dimen name="match_parent">-1px</dimen>
<dimen name="standard_notification_panel_width">416dp</dimen>
diff --git a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
index 53c2233..9a36aca 100644
--- a/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
+++ b/packages/SystemUI/src/com/android/systemui/SystemUIFactory.java
@@ -23,6 +23,9 @@
import com.android.internal.widget.LockPatternUtils;
import com.android.keyguard.ViewMediatorCallback;
+import com.android.systemui.R;
+import com.android.systemui.assist.AssistManager;
+import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.ScrimView;
import com.android.systemui.statusbar.phone.KeyguardBouncer;
import com.android.systemui.statusbar.phone.NotificationIconAreaController;
@@ -115,4 +118,8 @@
public <T> T createInstance(Class<T> classType) {
return null;
}
+
+ public AssistManager createAssistManager(BaseStatusBar bar, Context context) {
+ return new AssistManager(bar, context);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
index a0aeb2f..a5e771f 100644
--- a/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
+++ b/packages/SystemUI/src/com/android/systemui/assist/AssistManager.java
@@ -30,6 +30,7 @@
import com.android.internal.app.AssistUtils;
import com.android.internal.app.IVoiceInteractionSessionShowCallback;
import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.statusbar.BaseStatusBar;
import com.android.systemui.statusbar.CommandQueue;
@@ -103,6 +104,10 @@
}
}
+ protected boolean shouldShowOrb() {
+ return true;
+ }
+
public void startAssist(Bundle args) {
final ComponentName assistComponent = getAssistInfo();
if (assistComponent == null) {
@@ -110,7 +115,7 @@
}
final boolean isService = assistComponent.equals(getVoiceInteractorComponentName());
- if (!isService || !isVoiceSessionRunning()) {
+ if (!isService || (!isVoiceSessionRunning() && shouldShowOrb())) {
showOrb(assistComponent, isService);
mView.postDelayed(mHideRunnable, isService
? TIMEOUT_SERVICE
diff --git a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
index c8e74ec..3bbcf6e 100644
--- a/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
+++ b/packages/SystemUI/src/com/android/systemui/keyguard/KeyguardViewMediator.java
@@ -360,7 +360,7 @@
mSwitchingUser = false;
if (userId != UserHandle.USER_SYSTEM) {
UserInfo info = UserManager.get(mContext).getUserInfo(userId);
- if (info != null && info.isGuest()) {
+ if (info != null && (info.isGuest() || info.isDemo())) {
// If we just switched to a guest, try to dismiss keyguard.
dismiss();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java b/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java
index 15e1c96..c204d94 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/NonInterceptingScrollView.java
@@ -24,8 +24,6 @@
*/
public class NonInterceptingScrollView extends ScrollView {
- private float mInitialY;
-
public NonInterceptingScrollView(Context context, AttributeSet attrs) {
super(context, attrs);
}
@@ -35,14 +33,7 @@
int action = ev.getActionMasked();
switch (action) {
case MotionEvent.ACTION_DOWN:
- mInitialY = ev.getY();
- break;
- case MotionEvent.ACTION_UP:
- case MotionEvent.ACTION_CANCEL:
- requestDisallowInterceptTouchEvent(false);
- break;
- default:
- if (canScrollVertically(ev.getY() > mInitialY ? -1 : 1)) {
+ if (canScrollVertically(1)) {
requestDisallowInterceptTouchEvent(true);
}
break;
diff --git a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
index f07e8fc..cf96457 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/PagedTileLayout.java
@@ -31,6 +31,10 @@
private View mDecorGroup;
private PageListener mPageListener;
+ private int mPosition;
+ private boolean mOffPage;
+ private boolean mListening;
+
public PagedTileLayout(Context context, AttributeSet attrs) {
super(context, attrs);
setAdapter(mAdapter);
@@ -48,6 +52,7 @@
public void onPageScrolled(int position, float positionOffset,
int positionOffsetPixels) {
if (mPageIndicator == null) return;
+ setCurrentPage(position, positionOffset != 0);
mPageIndicator.setLocation(position + positionOffset);
if (mPageListener != null) {
mPageListener.onPageChanged(positionOffsetPixels == 0 &&
@@ -78,6 +83,52 @@
}
@Override
+ public void setListening(boolean listening) {
+ if (mListening == listening) return;
+ mListening = listening;
+ if (mListening) {
+ mPages.get(mPosition).setListening(listening);
+ if (mOffPage) {
+ mPages.get(mPosition + 1).setListening(listening);
+ }
+ } else {
+ // Make sure no pages are listening.
+ for (int i = 0; i < mPages.size(); i++) {
+ mPages.get(i).setListening(false);
+ }
+ }
+ }
+
+ /**
+ * Sets individual pages to listening or not. If offPage it will set
+ * the next page after position to listening as well since we are in between
+ * pages.
+ */
+ private void setCurrentPage(int position, boolean offPage) {
+ if (mPosition == position && mOffPage == offPage) return;
+ if (mListening) {
+ if (mPosition != position) {
+ // Clear out the last pages from listening.
+ mPages.get(mPosition).setListening(false);
+ if (mOffPage) {
+ mPages.get(mPosition + 1).setListening(false);
+ }
+ // Set the new pages to listening
+ mPages.get(position).setListening(true);
+ if (offPage) {
+ mPages.get(position + 1).setListening(true);
+ }
+ } else if (mOffPage != offPage) {
+ // Whether we are showing position + 1 has changed.
+ mPages.get(mPosition + 1).setListening(offPage);
+ }
+ }
+ // Save the current state.
+ mPosition = position;
+ mOffPage = offPage;
+ }
+
+ @Override
public boolean hasOverlappingRendering() {
return false;
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
index ef75562..8d6e17e 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSContainer.java
@@ -60,6 +60,7 @@
private QSAnimator mQSAnimator;
private QSCustomizer mQSCustomizer;
private NotificationPanelView mPanelView;
+ private boolean mListening;
public QSContainer(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -209,6 +210,7 @@
public void setExpanded(boolean expanded) {
if (DEBUG) Log.d(TAG, "setExpanded " + expanded);
mQsExpanded = expanded;
+ mQSPanel.setListening(mListening && mQsExpanded);
updateQsState();
}
@@ -227,8 +229,9 @@
public void setListening(boolean listening) {
if (DEBUG) Log.d(TAG, "setListening " + listening);
- mQSPanel.setListening(listening);
+ mListening = listening;
mHeader.setListening(listening);
+ mQSPanel.setListening(mListening && mQsExpanded);
}
public void setQsExpansion(float expansion, float headerTranslation) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
index 6c224f7..9c4a149 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSIconView.java
@@ -80,7 +80,7 @@
Drawable d = state.icon != null
? iv.isShown() && mAnimationEnabled ? state.icon.getDrawable(mContext)
: state.icon.getInvisibleDrawable(mContext) : null;
- int padding = state.icon != null ? state.icon.getPadding() : null;
+ int padding = state.icon != null ? state.icon.getPadding() : 0;
if (d != null && state.autoMirrorDrawable) {
d.setAutoMirrored(true);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
index 1211354..8148844 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSPanel.java
@@ -57,7 +57,7 @@
private int mPanelPaddingBottom;
private int mBrightnessPaddingTop;
private boolean mExpanded;
- private boolean mListening;
+ protected boolean mListening;
private Callback mCallback;
private BrightnessController mBrightnessController;
@@ -102,6 +102,7 @@
protected void setupTileLayout() {
mTileLayout = (QSTileLayout) LayoutInflater.from(mContext).inflate(
R.layout.qs_paged_tile_layout, this, false);
+ mTileLayout.setListening(mListening);
addView((View) mTileLayout);
}
@@ -228,8 +229,8 @@
public void setListening(boolean listening) {
if (mListening == listening) return;
mListening = listening;
- for (TileRecord r : mRecords) {
- r.tile.setListening(mListening);
+ if (mTileLayout != null) {
+ mTileLayout.setListening(listening);
}
mFooter.setListening(mListening);
if (mListening) {
@@ -341,7 +342,6 @@
}
};
r.tileView.init(click, longClick);
- r.tile.setListening(mListening);
callback.onStateChanged(r.tile.getState());
r.tile.refreshState();
mRecords.add(r);
@@ -531,5 +531,7 @@
void removeTile(TileRecord tile);
int getOffsetTop(TileRecord tile);
boolean updateResources();
+
+ void setListening(boolean listening);
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
index 0cc30a8..8d9f23f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QSTile.java
@@ -24,6 +24,7 @@
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
+import android.util.ArraySet;
import android.util.Log;
import android.util.SparseArray;
import android.view.View;
@@ -63,7 +64,7 @@
* handleUpdateState. Callbacks affecting state should use refreshState to trigger another
* state update pass on tile looper.
*/
-public abstract class QSTile<TState extends State> implements Listenable {
+public abstract class QSTile<TState extends State> {
protected final String TAG = "Tile." + getClass().getSimpleName();
protected static final boolean DEBUG = Log.isLoggable("Tile", Log.DEBUG);
@@ -71,6 +72,7 @@
protected final Context mContext;
protected final H mHandler;
protected final Handler mUiHandler = new Handler(Looper.getMainLooper());
+ private final ArraySet<Object> mListeners = new ArraySet<>();
private final ArrayList<Callback> mCallbacks = new ArrayList<>();
protected TState mState = newTileState();
@@ -97,6 +99,24 @@
mHandler = new H(host.getLooper());
}
+ /**
+ * Adds or removes a listening client for the tile. If the tile has one or more
+ * listening client it will go into the listening state.
+ */
+ public void setListening(Object listener, boolean listening) {
+ if (listening) {
+ if (mListeners.add(listener) && mListeners.size() == 1) {
+ if (DEBUG) Log.d(TAG, "setListening " + true);
+ mHandler.obtainMessage(H.SET_LISTENING, 1, 0).sendToTarget();
+ }
+ } else {
+ if (mListeners.remove(listener) && mListeners.size() == 0) {
+ if (DEBUG) Log.d(TAG, "setListening " + false);
+ mHandler.obtainMessage(H.SET_LISTENING, 0, 0).sendToTarget();
+ }
+ }
+ }
+
public String getTileSpec() {
return mTileSpec;
}
@@ -279,6 +299,8 @@
handleRefreshState(null);
}
+ protected abstract void setListening(boolean listening);
+
protected void handleDestroy() {
setListening(false);
mCallbacks.clear();
@@ -312,6 +334,7 @@
private static final int DESTROY = 10;
private static final int CLEAR_STATE = 11;
private static final int REMOVE_CALLBACKS = 12;
+ private static final int SET_LISTENING = 13;
private H(Looper looper) {
super(looper);
@@ -364,6 +387,9 @@
} else if (msg.what == CLEAR_STATE) {
name = "handleClearState";
handleClearState();
+ } else if (msg.what == SET_LISTENING) {
+ name = "setListening";
+ setListening(msg.arg1 != 0);
} else {
throw new IllegalArgumentException("Unknown msg: " + msg.what);
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
index 9adcfbf..2a0e6b3 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/QuickQSPanel.java
@@ -55,6 +55,7 @@
removeView((View) mTileLayout);
}
mTileLayout = new HeaderTileLayout(context);
+ mTileLayout.setListening(mListening);
addView((View) mTileLayout, 1 /* Between brightness and footer */);
}
@@ -146,6 +147,7 @@
private static class HeaderTileLayout extends LinearLayout implements QSTileLayout {
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
+ private boolean mListening;
public HeaderTileLayout(Context context) {
super(context);
@@ -156,6 +158,15 @@
}
@Override
+ public void setListening(boolean listening) {
+ if (mListening == listening) return;
+ mListening = listening;
+ for (TileRecord record : mRecords) {
+ record.tile.setListening(this, mListening);
+ }
+ }
+
+ @Override
public void addTile(TileRecord tile) {
if (getChildCount() != 0) {
// Add a spacer.
@@ -163,6 +174,7 @@
}
addView(tile.tileView, getChildCount(), generateLayoutParams());
mRecords.add(tile);
+ tile.tile.setListening(this, mListening);
}
private LayoutParams generateSpaceParams() {
@@ -190,6 +202,7 @@
removeViewAt(childIndex);
}
mRecords.remove(tile);
+ tile.tile.setListening(this, false);
}
private int getChildIndex(QSTileBaseView tileView) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
index a578e6c..a5a1eaa 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/TileLayout.java
@@ -25,6 +25,7 @@
protected final ArrayList<TileRecord> mRecords = new ArrayList<>();
private int mCellMarginTop;
+ private boolean mListening;
public TileLayout(Context context) {
this(context, null);
@@ -41,18 +42,32 @@
return getTop();
}
+ @Override
+ public void setListening(boolean listening) {
+ if (mListening == listening) return;
+ mListening = listening;
+ for (TileRecord record : mRecords) {
+ record.tile.setListening(this, mListening);
+ }
+ }
+
public void addTile(TileRecord tile) {
mRecords.add(tile);
+ tile.tile.setListening(this, mListening);
addView(tile.tileView);
}
@Override
public void removeTile(TileRecord tile) {
mRecords.remove(tile);
+ tile.tile.setListening(this, false);
removeView(tile.tileView);
}
public void removeAllViews() {
+ for (TileRecord record : mRecords) {
+ record.tile.setListening(this, false);
+ }
mRecords.clear();
super.removeAllViews();
}
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java
index e512f93..26fc6df 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/CustomizeTileView.java
@@ -26,7 +26,7 @@
public class CustomizeTileView extends QSTileView {
private TextView mAppLabel;
-
+ private int mLabelMinLines;
public CustomizeTileView(Context context, QSIconView icon) {
super(context, icon);
}
@@ -34,6 +34,7 @@
@Override
protected void createLabel() {
super.createLabel();
+ mLabelMinLines = mLabel.getMinLines();
View view = LayoutInflater.from(mContext).inflate(R.layout.qs_tile_label, null);
mAppLabel = (TextView) view.findViewById(R.id.tile_label);
mAppLabel.setAlpha(.6f);
@@ -44,6 +45,9 @@
public void setShowAppLabel(boolean showAppLabel) {
mAppLabel.setVisibility(showAppLabel ? View.VISIBLE : View.GONE);
mLabel.setSingleLine(showAppLabel);
+ if (!showAppLabel) {
+ mLabel.setMinLines(mLabelMinLines);
+ }
}
public void setAppLabel(CharSequence label) {
diff --git a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
index fb76918..8ec6a2f 100644
--- a/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
+++ b/packages/SystemUI/src/com/android/systemui/qs/customize/TileQueryHelper.java
@@ -66,10 +66,10 @@
if (tile == null || !tile.isAvailable()) {
continue;
}
- tile.setListening(true);
+ tile.setListening(this, true);
tile.clearState();
tile.refreshState();
- tile.setListening(false);
+ tile.setListening(this, false);
qsHandler.post(new Runnable() {
@Override
public void run() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
index 71f74cd..42c9a126 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ActivatableNotificationView.java
@@ -98,6 +98,7 @@
private boolean mDark;
private int mBgTint = 0;
+ private float mBgAlpha = 1f;
/**
* Flag to indicate that the notification has been touched once and the second touch will
@@ -392,6 +393,7 @@
public void setDimmed(boolean dimmed, boolean fade) {
if (mDimmed != dimmed) {
mDimmed = dimmed;
+ resetBackgroundAlpha();
if (fade) {
fadeDimmedBackground();
} else {
@@ -594,14 +596,28 @@
mBackgroundAnimator.start();
}
+ protected void updateBackgroundAlpha(float transformationAmount) {
+ mBgAlpha = isChildInGroup() && mDimmed ? transformationAmount : 1f;
+ mBackgroundDimmed.setAlpha(mBgAlpha);
+ }
+
+ protected void resetBackgroundAlpha() {
+ updateBackgroundAlpha(0f /* transformationAmount */);
+ }
+
protected void updateBackground() {
cancelFadeAnimations();
if (shouldHideBackground()) {
mBackgroundDimmed.setVisibility(View.INVISIBLE);
mBackgroundNormal.setVisibility(View.INVISIBLE);
} else if (mDimmed) {
- mBackgroundDimmed.setVisibility(View.VISIBLE);
- mBackgroundNormal.setVisibility(mActivated ? View.VISIBLE : View.INVISIBLE);
+ // When groups are animating to the expanded state from the lockscreen, show the
+ // normal background instead of the dimmed background
+ final boolean dontShowDimmed = isGroupExpansionChanging() && isChildInGroup();
+ mBackgroundDimmed.setVisibility(dontShowDimmed ? View.INVISIBLE : View.VISIBLE);
+ mBackgroundNormal.setVisibility((mActivated || dontShowDimmed)
+ ? View.VISIBLE
+ : View.INVISIBLE);
} else {
mBackgroundDimmed.setVisibility(View.INVISIBLE);
mBackgroundNormal.setVisibility(View.VISIBLE);
@@ -876,6 +892,7 @@
public void reset() {
setTintColor(0);
+ resetBackgroundAlpha();
setShowingLegacyBackground(false);
setBelowSpeedBump(false);
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
index b855b7c..aedc7df 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/ExpandableNotificationRow.java
@@ -381,6 +381,7 @@
boolean childInGroup = BaseStatusBar.ENABLE_CHILD_NOTIFICATIONS && isChildInGroup;
mNotificationParent = childInGroup ? parent : null;
mPrivateLayout.setIsChildInGroup(childInGroup);
+ resetBackgroundAlpha();
updateBackgroundForGroupState();
updateClickAndFocus();
if (mNotificationParent != null) {
@@ -1072,7 +1073,7 @@
mPrivateLayout.setUserExpanding(userLocked);
if (mIsSummaryWithChildren) {
mChildrenContainer.setUserLocked(userLocked);
- if (userLocked) {
+ if (userLocked || (!userLocked && !isGroupExpanded())) {
updateBackgroundForGroupState();
}
}
@@ -1096,7 +1097,7 @@
mIsSystemExpanded = expand;
notifyHeightChanged(false /* needsAnimation */);
logExpansionEvent(false, wasExpanded);
- if (mChildrenContainer != null) {
+ if (mIsSummaryWithChildren) {
mChildrenContainer.updateGroupOverflow();
}
}
@@ -1165,13 +1166,14 @@
mChildrenContainer.recreateNotificationHeader(mExpandClickListener,
mEntry.notification);
}
+ getShowingLayout().updateBackgroundColor(false /* animate */);
mPrivateLayout.updateExpandButtons(isExpandable());
updateChildrenHeaderAppearance();
updateChildrenVisibility();
}
public void updateChildrenHeaderAppearance() {
- if (mChildrenContainer != null) {
+ if (mIsSummaryWithChildren) {
mChildrenContainer.updateChildrenHeaderAppearance();
}
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
index 79e06c6..9211562 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/KeyboardShortcuts.java
@@ -72,7 +72,6 @@
private static final String TAG = KeyboardShortcuts.class.getSimpleName();
private static final Object sLock = new Object();
private static KeyboardShortcuts sInstance;
- private static boolean sIsShowing;
private final SparseArray<String> mSpecialCharacterNames = new SparseArray<>();
private final SparseArray<String> mModifierNames = new SparseArray<>();
@@ -131,13 +130,12 @@
dismiss();
}
getInstance(context).showKeyboardShortcuts(deviceId);
- sIsShowing = true;
}
}
public static void toggle(Context context, int deviceId) {
synchronized (sLock) {
- if (sIsShowing) {
+ if (isShowing()) {
dismiss();
} else {
show(context, deviceId);
@@ -151,10 +149,14 @@
sInstance.dismissKeyboardShortcuts();
sInstance = null;
}
- sIsShowing = false;
}
}
+ private static boolean isShowing() {
+ return sInstance != null && sInstance.mKeyboardShortcutsDialog != null
+ && sInstance.mKeyboardShortcutsDialog.isShowing();
+ }
+
private void loadResources(Context context) {
mSpecialCharacterNames.put(
KeyEvent.KEYCODE_HOME, context.getString(R.string.keyboard_key_home));
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
index d6c02e4..21fed3c 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/NotificationContentView.java
@@ -277,15 +277,25 @@
mContractedChild.animate().cancel();
removeView(mContractedChild);
}
- mPreviousExpandedRemoteInputIntent =
- mExpandedRemoteInput != null ? mExpandedRemoteInput.getPendingIntent() : null;
+ mPreviousExpandedRemoteInputIntent = null;
+ if (mExpandedRemoteInput != null) {
+ mExpandedRemoteInput.onNotificationUpdateOrReset();
+ if (mExpandedRemoteInput.isActive()) {
+ mPreviousExpandedRemoteInputIntent = mExpandedRemoteInput.getPendingIntent();
+ }
+ }
if (mExpandedChild != null) {
mExpandedChild.animate().cancel();
removeView(mExpandedChild);
mExpandedRemoteInput = null;
}
- mPreviousHeadsUpRemoteInputIntent =
- mHeadsUpRemoteInput != null ? mHeadsUpRemoteInput.getPendingIntent() : null;
+ mPreviousHeadsUpRemoteInputIntent = null;
+ if (mHeadsUpRemoteInput != null) {
+ mHeadsUpRemoteInput.onNotificationUpdateOrReset();
+ if (mHeadsUpRemoteInput.isActive()) {
+ mPreviousHeadsUpRemoteInputIntent = mHeadsUpRemoteInput.getPendingIntent();
+ }
+ }
if (mHeadsUpChild != null) {
mHeadsUpChild.animate().cancel();
removeView(mHeadsUpChild);
@@ -462,6 +472,7 @@
endColor = NotificationUtils.interpolateColors(startColor, endColor,
transformationAmount);
}
+ mContainingNotification.updateBackgroundAlpha(transformationAmount);
mContainingNotification.setContentBackground(endColor, false, this);
}
@@ -594,6 +605,7 @@
public void updateBackgroundColor(boolean animate) {
int customBackgroundColor = getBackgroundColor(mVisibleType);
+ mContainingNotification.resetBackgroundAlpha();
mContainingNotification.setContentBackground(customBackgroundColor, animate, this);
}
@@ -908,7 +920,7 @@
view.findViewWithTag(RemoteInputView.VIEW_TAG);
if (existing != null) {
- existing.onNotificationUpdate();
+ existing.onNotificationUpdateOrReset();
}
if (existing == null && hasRemoteInput) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
index 61df44a..85e87dd 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/notification/NotificationCustomViewWrapper.java
@@ -127,7 +127,8 @@
@Override
public int getCustomBackgroundColor() {
- return mBackgroundColor;
+ // Parent notifications should always use the normal background color
+ return mRow.isSummaryWithChildren() ? 0 : mBackgroundColor;
}
@Override
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
index 30d24ff..b5a48a3 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/ButtonDispatcher.java
@@ -14,11 +14,10 @@
package com.android.systemui.statusbar.phone;
+import android.annotation.DrawableRes;
+import android.annotation.Nullable;
import android.graphics.drawable.Drawable;
import android.view.View;
-import android.widget.ImageView;
-
-import com.android.systemui.statusbar.policy.KeyButtonView;
import java.util.ArrayList;
@@ -65,9 +64,9 @@
view.setVisibility(mVisibility);
}
if (mImageResource > 0) {
- ((ImageView) view).setImageResource(mImageResource);
+ ((ButtonInterface) view).setImageResource(mImageResource);
} else if (mImageDrawable != null) {
- ((ImageView) view).setImageDrawable(mImageDrawable);
+ ((ButtonInterface) view).setImageDrawable(mImageDrawable);
}
}
@@ -88,7 +87,7 @@
mImageResource = -1;
final int N = mViews.size();
for (int i = 0; i < N; i++) {
- ((ImageView) mViews.get(i)).setImageDrawable(mImageDrawable);
+ ((ButtonInterface) mViews.get(i)).setImageDrawable(mImageDrawable);
}
}
@@ -97,7 +96,7 @@
mImageDrawable = null;
final int N = mViews.size();
for (int i = 0; i < N; i++) {
- ((ImageView) mViews.get(i)).setImageResource(mImageResource);
+ ((ButtonInterface) mViews.get(i)).setImageResource(mImageResource);
}
}
@@ -114,7 +113,7 @@
// This seems to be an instantaneous thing, so not going to persist it.
final int N = mViews.size();
for (int i = 0; i < N; i++) {
- ((KeyButtonView) mViews.get(i)).abortCurrentGesture();
+ ((ButtonInterface) mViews.get(i)).abortCurrentGesture();
}
}
@@ -165,4 +164,15 @@
public void setCurrentView(View currentView) {
mCurrentView = currentView.findViewById(mId);
}
+
+ /**
+ * Interface for ImageView button actions.
+ */
+ public interface ButtonInterface {
+ void setImageResource(@DrawableRes int resId);
+
+ void setImageDrawable(@Nullable Drawable drawable);
+
+ void abortCurrentGesture();
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
index 8d74536..772c766 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardBottomAreaView.java
@@ -230,6 +230,24 @@
mIndicationText.setTextSize(TypedValue.COMPLEX_UNIT_PX,
getResources().getDimensionPixelSize(
com.android.internal.R.dimen.text_size_small_material));
+
+ ViewGroup.LayoutParams lp = mCameraImageView.getLayoutParams();
+ lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
+ lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
+ mCameraImageView.setLayoutParams(lp);
+ mCameraImageView.setImageDrawable(mContext.getDrawable(R.drawable.ic_camera_alt_24dp));
+
+ lp = mLockIcon.getLayoutParams();
+ lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
+ lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
+ mLockIcon.setLayoutParams(lp);
+ mLockIcon.update(true /* force */);
+
+ lp = mLeftAffordanceView.getLayoutParams();
+ lp.width = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_width);
+ lp.height = getResources().getDimensionPixelSize(R.dimen.keyguard_affordance_height);
+ mLeftAffordanceView.setLayoutParams(lp);
+ updateLeftAffordanceIcon();
}
public void setActivityStarter(ActivityStarter activityStarter) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
index e08b945..7db2870 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/KeyguardStatusBarView.java
@@ -58,6 +58,7 @@
private KeyguardUserSwitcher mKeyguardUserSwitcher;
private int mSystemIconsSwitcherHiddenExpandedMargin;
+ private View mSystemIconsContainer;
public KeyguardStatusBarView(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -67,6 +68,7 @@
protected void onFinishInflate() {
super.onFinishInflate();
mSystemIconsSuperContainer = findViewById(R.id.system_icons_super_container);
+ mSystemIconsContainer = findViewById(R.id.system_icons_container);
mMultiUserSwitch = (MultiUserSwitch) findViewById(R.id.multi_user_switch);
mMultiUserAvatar = (ImageView) findViewById(R.id.multi_user_avatar);
mBatteryLevel = (TextView) findViewById(R.id.battery_level);
@@ -79,17 +81,58 @@
protected void onConfigurationChanged(Configuration newConfig) {
super.onConfigurationChanged(newConfig);
- // Respect font size setting.
- mCarrierLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
- getResources().getDimensionPixelSize(
- com.android.internal.R.dimen.text_size_small_material));
- mBatteryLevel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
- getResources().getDimensionPixelSize(R.dimen.battery_level_text_size));
-
MarginLayoutParams lp = (MarginLayoutParams) mMultiUserAvatar.getLayoutParams();
lp.width = lp.height = getResources().getDimensionPixelSize(
R.dimen.multi_user_avatar_keyguard_size);
mMultiUserAvatar.setLayoutParams(lp);
+
+ lp = (MarginLayoutParams) mMultiUserSwitch.getLayoutParams();
+ lp.width = getResources().getDimensionPixelSize(
+ R.dimen.multi_user_switch_width_keyguard);
+ lp.setMarginEnd(getResources().getDimensionPixelSize(
+ R.dimen.multi_user_switch_keyguard_margin));
+ mMultiUserSwitch.setLayoutParams(lp);
+
+ lp = (MarginLayoutParams) mSystemIconsSuperContainer.getLayoutParams();
+ lp.height = getResources().getDimensionPixelSize(
+ R.dimen.status_bar_header_height);
+ lp.setMarginStart(getResources().getDimensionPixelSize(
+ R.dimen.system_icons_super_container_margin_start));
+ mSystemIconsSuperContainer.setLayoutParams(lp);
+ mSystemIconsSuperContainer.setPaddingRelative(mSystemIconsSuperContainer.getPaddingStart(),
+ mSystemIconsSuperContainer.getPaddingTop(),
+ getResources().getDimensionPixelSize(R.dimen.system_icons_keyguard_padding_end),
+ mSystemIconsSuperContainer.getPaddingBottom());
+
+ lp = (MarginLayoutParams) mSystemIconsContainer.getLayoutParams();
+ lp.height = getResources().getDimensionPixelSize(
+ R.dimen.status_bar_height);
+ mSystemIconsContainer.setLayoutParams(lp);
+
+ lp = (MarginLayoutParams) mBatteryLevel.getLayoutParams();
+ lp.setMarginStart(
+ getResources().getDimensionPixelSize(R.dimen.header_battery_margin_keyguard));
+ mBatteryLevel.setLayoutParams(lp);
+ mBatteryLevel.setPaddingRelative(mBatteryLevel.getPaddingStart(),
+ mBatteryLevel.getPaddingTop(),
+ getResources().getDimensionPixelSize(R.dimen.battery_level_padding_end),
+ mBatteryLevel.getPaddingBottom());
+ mBatteryLevel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ getResources().getDimensionPixelSize(R.dimen.battery_level_text_size));
+
+ // Respect font size setting.
+ mCarrierLabel.setTextSize(TypedValue.COMPLEX_UNIT_PX,
+ getResources().getDimensionPixelSize(
+ com.android.internal.R.dimen.text_size_small_material));
+ lp = (MarginLayoutParams) mCarrierLabel.getLayoutParams();
+ lp.setMarginStart(
+ getResources().getDimensionPixelSize(R.dimen.keyguard_carrier_text_margin));
+ mCarrierLabel.setLayoutParams(lp);
+
+ lp = (MarginLayoutParams) getLayoutParams();
+ lp.height = getResources().getDimensionPixelSize(
+ R.dimen.status_bar_header_height_keyguard);
+ setLayoutParams(lp);
}
private void loadDimens() {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
index 8e58d14..ab5ee93 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/LockIcon.java
@@ -17,6 +17,7 @@
package com.android.systemui.statusbar.phone;
import android.content.Context;
+import android.content.res.Configuration;
import android.graphics.drawable.AnimatedVectorDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.InsetDrawable;
@@ -46,10 +47,11 @@
private boolean mDeviceInteractive;
private boolean mScreenOn;
private boolean mLastScreenOn;
- private final TrustDrawable mTrustDrawable;
+ private TrustDrawable mTrustDrawable;
private final UnlockMethodCache mUnlockMethodCache;
private AccessibilityController mAccessibilityController;
private boolean mHasFingerPrintIcon;
+ private int mDensity;
public LockIcon(Context context, AttributeSet attrs) {
super(context, attrs);
@@ -89,7 +91,24 @@
update();
}
+ @Override
+ protected void onConfigurationChanged(Configuration newConfig) {
+ super.onConfigurationChanged(newConfig);
+ final int density = newConfig.densityDpi;
+ if (density != mDensity) {
+ mDensity = density;
+ mTrustDrawable.stop();
+ mTrustDrawable = new TrustDrawable(getContext());
+ setBackground(mTrustDrawable);
+ update();
+ }
+ }
+
public void update() {
+ update(false /* force */);
+ }
+
+ public void update(boolean force) {
boolean visible = isShown()
&& KeyguardUpdateMonitor.getInstance(mContext).isDeviceInteractive();
if (visible) {
@@ -103,7 +122,7 @@
boolean useAdditionalPadding = anyFingerprintIcon;
boolean trustHidden = anyFingerprintIcon;
if (state != mLastState || mDeviceInteractive != mLastDeviceInteractive
- || mScreenOn != mLastScreenOn) {
+ || mScreenOn != mLastScreenOn || force) {
boolean isAnim = true;
int iconRes = getAnimationResForTransition(mLastState, state, mLastDeviceInteractive,
mDeviceInteractive, mLastScreenOn, mScreenOn);
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
index 2bee816..dd46b08 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NavigationBarInflaterView.java
@@ -26,7 +26,9 @@
import android.widget.FrameLayout;
import android.widget.LinearLayout;
import android.widget.Space;
+
import com.android.systemui.R;
+import com.android.systemui.SystemUIFactory;
import com.android.systemui.statusbar.policy.KeyButtonView;
import com.android.systemui.tuner.TunerService;
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
index 522f250..5064d8e 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/NotificationPanelView.java
@@ -1735,7 +1735,7 @@
public void onQsHeightChanged() {
mQsMaxExpansionHeight = mQsContainer.getDesiredHeight();
- if (mQsExpanded) {
+ if (mQsExpanded && mQsFullyExpanded) {
mQsExpansionHeight = mQsMaxExpansionHeight;
requestScrollerTopPaddingUpdate(false /* animate */);
requestPanelHeightUpdate();
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
index 268c46b..376f724a 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/PhoneStatusBar.java
@@ -765,7 +765,7 @@
// no window manager? good luck with that
}
- mAssistManager = new AssistManager(this, context);
+ mAssistManager = SystemUIFactory.getInstance().createAssistManager(this, context);
// figure out which pixel-format to use for the status bar.
mPixelFormat = PixelFormat.OPAQUE;
@@ -997,7 +997,7 @@
private void inflateSignalClusters() {
SignalClusterView signalClusterView = reinflateSignalCluster(mStatusBarView);
mIconController.setSignalCluster(signalClusterView);
- reinflateSignalCluster(mKeyguardStatusView);
+ reinflateSignalCluster(mKeyguardStatusBar);
}
private SignalClusterView reinflateSignalCluster(View view) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
index 29b4db1..68e5d0b 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/phone/QSTileHost.java
@@ -369,13 +369,15 @@
}
public void addTile(String spec) {
- if (mTileSpecs.contains(spec)) {
+ final String setting = Settings.Secure.getStringForUser(mContext.getContentResolver(),
+ TILES_SETTING, ActivityManager.getCurrentUser());
+ final List<String> tileSpecs = loadTileSpecs(mContext, setting);
+ if (tileSpecs.contains(spec)) {
return;
}
- ArrayList<String> specs = new ArrayList<>(mTileSpecs);
- specs.add(spec);
+ tileSpecs.add(spec);
Settings.Secure.putStringForUser(mContext.getContentResolver(), TILES_SETTING,
- TextUtils.join(",", specs), ActivityManager.getCurrentUser());
+ TextUtils.join(",", tileSpecs), ActivityManager.getCurrentUser());
}
public void addTile(ComponentName tile) {
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
index c8c824a..d8b1a62 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/KeyButtonView.java
@@ -16,6 +16,8 @@
package com.android.systemui.statusbar.policy;
+import android.annotation.DrawableRes;
+import android.annotation.Nullable;
import android.app.ActivityManager;
import android.content.Context;
import android.content.res.Configuration;
@@ -42,11 +44,12 @@
import android.widget.ImageView;
import com.android.systemui.R;
+import com.android.systemui.statusbar.phone.ButtonDispatcher;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_CLICK;
import static android.view.accessibility.AccessibilityNodeInfo.ACTION_LONG_CLICK;
-public class KeyButtonView extends ImageView {
+public class KeyButtonView extends ImageView implements ButtonDispatcher.ButtonInterface {
private int mContentDescriptionRes;
private long mDownTime;
@@ -247,10 +250,21 @@
InputManager.INJECT_INPUT_EVENT_MODE_ASYNC);
}
+ @Override
public void abortCurrentGesture() {
setPressed(false);
mGestureAborted = true;
}
+
+ @Override
+ public void setImageResource(@DrawableRes int resId) {
+ super.setImageResource(resId);
+ }
+
+ @Override
+ public void setImageDrawable(@Nullable Drawable drawable) {
+ super.setImageDrawable(drawable);
+ }
}
diff --git a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
index 40ff051..7704a07 100644
--- a/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
+++ b/packages/SystemUI/src/com/android/systemui/statusbar/policy/RemoteInputView.java
@@ -227,7 +227,7 @@
updateSendButton();
}
- public void onNotificationUpdate() {
+ public void onNotificationUpdateOrReset() {
boolean sending = mProgressBar.getVisibility() == VISIBLE;
if (sending) {
diff --git a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
index f2cd885..c6992aa 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/VolumeDialog.java
@@ -106,14 +106,14 @@
private ViewGroup mDialogContentView;
private ImageButton mExpandButton;
private final List<VolumeRow> mRows = new ArrayList<>();
- private final SpTexts mSpTexts;
+ private SpTexts mSpTexts;
private final SparseBooleanArray mDynamic = new SparseBooleanArray();
private final KeyguardManager mKeyguard;
private final AudioManager mAudioManager;
private final AccessibilityManager mAccessibilityMgr;
private int mExpandButtonAnimationDuration;
private ZenFooter mZenFooter;
- private final LayoutTransition mLayoutTransition;
+ private LayoutTransition mLayoutTransition;
private final Object mSafetyWarningLock = new Object();
private final Accessibility mAccessibility = new Accessibility();
private final ColorStateList mActiveSliderTint;
@@ -149,14 +149,11 @@
mCallback = callback;
mWindowType = windowType;
mZenModeController = zenModeController;
- mSpTexts = new SpTexts(mContext);
mKeyguard = (KeyguardManager) context.getSystemService(Context.KEYGUARD_SERVICE);
mAudioManager = (AudioManager) context.getSystemService(Context.AUDIO_SERVICE);
mAccessibilityMgr = (AccessibilityManager) mContext.getSystemService(Context.ACCESSIBILITY_SERVICE);
mActiveSliderTint = loadColorStateList(R.color.system_accent_color);
mInactiveSliderTint = loadColorStateList(R.color.volume_slider_inactive);
- mLayoutTransition = new LayoutTransition();
- mLayoutTransition.setDuration(new ValueAnimator().getDuration() / 2);
initDialog();
@@ -173,6 +170,9 @@
private void initDialog() {
mDialog = new CustomDialog(mContext);
+ mSpTexts = new SpTexts(mContext);
+ mLayoutTransition = new LayoutTransition();
+ mLayoutTransition.setDuration(new ValueAnimator().getDuration() / 2);
mHovering = false;
mShowing = false;
final Window window = mDialog.getWindow();
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
index 005767f..65975d9 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenFooter.java
@@ -70,16 +70,6 @@
}
public void init(final ZenModeController controller) {
- controller.addCallback(new ZenModeController.Callback() {
- @Override
- public void onZenChanged(int zen) {
- setZen(zen);
- }
- @Override
- public void onConfigChanged(ZenModeConfig config) {
- setConfig(config);
- }
- });
mEndNowButton.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
@@ -92,6 +82,18 @@
update();
}
+ @Override
+ protected void onAttachedToWindow() {
+ super.onAttachedToWindow();
+ mController.addCallback(mZenCallback);
+ }
+
+ @Override
+ protected void onDetachedFromWindow() {
+ super.onDetachedFromWindow();
+ mController.removeCallback(mZenCallback);
+ }
+
private void setZen(int zen) {
if (mZen == zen) return;
mZen = zen;
@@ -143,4 +145,14 @@
mSpTexts.update();
}
+ private final ZenModeController.Callback mZenCallback = new ZenModeController.Callback() {
+ @Override
+ public void onZenChanged(int zen) {
+ setZen(zen);
+ }
+ @Override
+ public void onConfigChanged(ZenModeConfig config) {
+ setConfig(config);
+ }
+ };
}
diff --git a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
index fda57eb..15c163f 100644
--- a/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
+++ b/packages/SystemUI/src/com/android/systemui/volume/ZenModePanel.java
@@ -48,6 +48,7 @@
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RadioButton;
+import android.widget.RadioGroup;
import android.widget.TextView;
import com.android.internal.logging.MetricsLogger;
@@ -102,6 +103,8 @@
private TextView mZenIntroductionCustomize;
protected LinearLayout mZenConditions;
private TextView mZenAlarmWarning;
+ private RadioGroup mZenRadioGroup;
+ private LinearLayout mZenRadioGroupContent;
private Callback mCallback;
private ZenModeController mController;
@@ -117,7 +120,6 @@
private Condition mSessionExitCondition;
private Condition[] mConditions;
private Condition mTimeCondition;
- private Condition mTimeUntilAlarmCondition;
private boolean mVoiceCapable;
public ZenModePanel(Context context, AttributeSet attrs) {
@@ -190,6 +192,8 @@
mZenConditions = (LinearLayout) findViewById(R.id.zen_conditions);
mZenAlarmWarning = (TextView) findViewById(R.id.zen_alarm_warning);
+ mZenRadioGroup = (RadioGroup) findViewById(R.id.zen_radio_buttons);
+ mZenRadioGroupContent = (LinearLayout) findViewById(R.id.zen_radio_buttons_content);
}
@Override
@@ -227,6 +231,7 @@
mAttachedZen = getSelectedZen(-1);
mSessionZen = mAttachedZen;
mTransitionHelper.clear();
+ mController.addCallback(mZenCallback);
setSessionExitCondition(copy(mExitCondition));
updateWidgets();
setRequestingConditions(!mHidden);
@@ -240,6 +245,7 @@
mAttached = false;
mAttachedZen = -1;
mSessionZen = -1;
+ mController.removeCallback(mZenCallback);
setSessionExitCondition(null);
setRequestingConditions(false);
mTransitionHelper.clear();
@@ -306,7 +312,12 @@
protected void addZenConditions(int count) {
for (int i = 0; i < count; i++) {
- mZenConditions.addView(mInflater.inflate(R.layout.zen_mode_condition, this, false));
+ final View rb = mInflater.inflate(R.layout.zen_mode_button, this, false);
+ rb.setId(i);
+ mZenRadioGroup.addView(rb);
+ final View rbc = mInflater.inflate(R.layout.zen_mode_condition, this, false);
+ rbc.setId(i + count);
+ mZenRadioGroupContent.addView(rbc);
}
}
@@ -320,7 +331,6 @@
handleUpdateManualRule(mController.getManualRule());
if (DEBUG) Log.d(mTag, "init mExitCondition=" + mExitCondition);
hideAllConditions();
- mController.addCallback(mZenCallback);
}
public void updateLocale() {
@@ -385,7 +395,7 @@
final ConditionTag tag = getConditionTagAt(i);
if (tag != null) {
if (sameConditionId(tag.condition, mExitCondition)) {
- bind(exitCondition, mZenConditions.getChildAt(i), i);
+ bind(exitCondition, mZenRadioGroupContent.getChildAt(i), i);
}
}
}
@@ -481,20 +491,28 @@
final int conditionCount = mConditions == null ? 0 : mConditions.length;
if (DEBUG) Log.d(mTag, "handleUpdateConditions conditionCount=" + conditionCount);
// forever
- bind(forever(), mZenConditions.getChildAt(FOREVER_CONDITION_INDEX),
+ bind(forever(), mZenRadioGroupContent.getChildAt(FOREVER_CONDITION_INDEX),
FOREVER_CONDITION_INDEX);
// countdown
if (mCountdownConditionSupported && mTimeCondition != null) {
- bind(mTimeCondition, mZenConditions.getChildAt(COUNTDOWN_CONDITION_INDEX),
+ bind(mTimeCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
COUNTDOWN_CONDITION_INDEX);
}
// countdown until alarm
if (mCountdownConditionSupported) {
Condition nextAlarmCondition = getTimeUntilNextAlarmCondition();
if (nextAlarmCondition != null) {
+ mZenRadioGroup.getChildAt(
+ COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.VISIBLE);
+ mZenRadioGroupContent.getChildAt(
+ COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.VISIBLE);
bind(nextAlarmCondition,
- mZenConditions.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX),
+ mZenRadioGroupContent.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX),
COUNTDOWN_ALARM_CONDITION_INDEX);
+ } else {
+ mZenRadioGroup.getChildAt(COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.GONE);
+ mZenRadioGroupContent.getChildAt(
+ COUNTDOWN_ALARM_CONDITION_INDEX).setVisibility(View.GONE);
}
}
// ensure something is selected
@@ -541,22 +559,22 @@
}
private ConditionTag getConditionTagAt(int index) {
- return (ConditionTag) mZenConditions.getChildAt(index).getTag();
+ return (ConditionTag) mZenRadioGroupContent.getChildAt(index).getTag();
}
private int getVisibleConditions() {
int rt = 0;
- final int N = mZenConditions.getChildCount();
+ final int N = mZenRadioGroupContent.getChildCount();
for (int i = 0; i < N; i++) {
- rt += mZenConditions.getChildAt(i).getVisibility() == VISIBLE ? 1 : 0;
+ rt += mZenRadioGroupContent.getChildAt(i).getVisibility() == VISIBLE ? 1 : 0;
}
return rt;
}
private void hideAllConditions() {
- final int N = mZenConditions.getChildCount();
+ final int N = mZenRadioGroupContent.getChildCount();
for (int i = 0; i < N; i++) {
- mZenConditions.getChildAt(i).setVisibility(GONE);
+ mZenRadioGroupContent.getChildAt(i).setVisibility(GONE);
}
}
@@ -576,27 +594,14 @@
if (DEBUG) Log.d(mTag, "Selecting a default");
final int favoriteIndex = mPrefs.getMinuteIndex();
if (favoriteIndex == -1 || !mCountdownConditionSupported) {
- setChecked(foreverTag.rb, true);
+ foreverTag.rb.setChecked(true);
} else {
mTimeCondition = ZenModeConfig.toTimeCondition(mContext,
MINUTE_BUCKETS[favoriteIndex], ActivityManager.getCurrentUser());
mBucketIndex = favoriteIndex;
- bind(mTimeCondition, mZenConditions.getChildAt(COUNTDOWN_CONDITION_INDEX),
+ bind(mTimeCondition, mZenRadioGroupContent.getChildAt(COUNTDOWN_CONDITION_INDEX),
COUNTDOWN_CONDITION_INDEX);
- setChecked(getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb, true);
- }
- }
-
- private void setChecked(RadioButton rb, boolean checked) {
- final int N = getVisibleConditions();
- for (int i = 0; i < N; i++) {
- final ConditionTag tag = getConditionTagAt(i);
- if (tag != null && tag.rb.isChecked() && !Objects.equals(tag.rb, rb)) {
- tag.rb.setChecked(false);
- }
- }
- if (rb.isChecked() != checked) {
- rb.setChecked(checked);
+ getConditionTagAt(COUNTDOWN_CONDITION_INDEX).rb.setChecked(true);
}
}
@@ -616,18 +621,18 @@
row.setTag(tag);
final boolean first = tag.rb == null;
if (tag.rb == null) {
- tag.rb = (RadioButton) row.findViewById(android.R.id.checkbox);
+ tag.rb = (RadioButton) mZenRadioGroup.getChildAt(rowId);
}
tag.condition = condition;
final Uri conditionId = getConditionId(tag.condition);
- if (DEBUG) Log.d(mTag, "bind i=" + mZenConditions.indexOfChild(row) + " first=" + first
- + " condition=" + conditionId);
+ if (DEBUG) Log.d(mTag, "bind i=" + mZenRadioGroupContent.indexOfChild(row) + " first="
+ + first + " condition=" + conditionId);
tag.rb.setEnabled(enabled);
tag.rb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
@Override
public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
if (mExpanded && isChecked) {
- setChecked(tag.rb, isChecked);
+ tag.rb.setChecked(true);
if (DEBUG) Log.d(mTag, "onCheckedChanged " + conditionId);
MetricsLogger.action(mContext, MetricsEvent.QS_DND_CONDITION_SELECT);
select(tag.condition);
@@ -678,7 +683,7 @@
tag.lines.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
- setChecked(tag.rb, true);
+ tag.rb.setChecked(true);
}
});
@@ -767,7 +772,7 @@
}
mTimeCondition = newCondition;
bind(mTimeCondition, row, rowId);
- setChecked(tag.rb, true);
+ tag.rb.setChecked(true);
select(mTimeCondition);
announceConditionSelection(tag);
}
diff --git a/proto/src/metrics_constants.proto b/proto/src/metrics_constants.proto
index 3a14ad2..1dcb13c 100644
--- a/proto/src/metrics_constants.proto
+++ b/proto/src/metrics_constants.proto
@@ -2256,6 +2256,8 @@
// CATEGORY: SETTINGS
SETTINGS_GESTURES = 459;
+ // ---- End N-MR1 Constants, all N-MR1 constants go above this line ----
+
// Add new aosp constants above this line.
// END OF AOSP CONSTANTS
}
diff --git a/services/core/java/com/android/server/AttributeCache.java b/services/core/java/com/android/server/AttributeCache.java
index 427dbc0..57f18c0 100644
--- a/services/core/java/com/android/server/AttributeCache.java
+++ b/services/core/java/com/android/server/AttributeCache.java
@@ -24,10 +24,12 @@
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.os.UserHandle;
+import android.util.ArrayMap;
import android.util.SparseArray;
-import java.util.HashMap;
-import java.util.WeakHashMap;
+import com.android.internal.annotations.GuardedBy;
+
+import java.lang.ref.WeakReference;
/**
* TODO: This should be better integrated into the system so it doesn't need
@@ -35,17 +37,18 @@
*/
public final class AttributeCache {
private static AttributeCache sInstance = null;
-
+
private final Context mContext;
- private final WeakHashMap<String, Package> mPackages =
- new WeakHashMap<String, Package>();
+
+ @GuardedBy("this")
+ private final ArrayMap<String, WeakReference<Package>> mPackages = new ArrayMap<>();
+ @GuardedBy("this")
private final Configuration mConfiguration = new Configuration();
-
+
public final static class Package {
public final Context context;
- private final SparseArray<HashMap<int[], Entry>> mMap
- = new SparseArray<HashMap<int[], Entry>>();
-
+ private final SparseArray<ArrayMap<int[], Entry>> mMap = new SparseArray<>();
+
public Package(Context c) {
context = c;
}
@@ -59,6 +62,12 @@
context = c;
array = ta;
}
+
+ void recycle() {
+ if (array != null) {
+ array.recycle();
+ }
+ }
}
public static void init(Context context) {
@@ -74,13 +83,27 @@
public AttributeCache(Context context) {
mContext = context;
}
-
+
public void removePackage(String packageName) {
synchronized (this) {
- mPackages.remove(packageName);
+ final WeakReference<Package> ref = mPackages.remove(packageName);
+ final Package pkg = (ref != null) ? ref.get() : null;
+ if (pkg != null) {
+ if (pkg.mMap != null) {
+ for (int i = 0; i < pkg.mMap.size(); i++) {
+ final ArrayMap<int[], Entry> map = pkg.mMap.valueAt(i);
+ for (int j = 0; j < map.size(); j++) {
+ map.valueAt(j).recycle();
+ }
+ }
+ }
+
+ final Resources res = pkg.context.getResources();
+ res.flushLayoutCache();
+ }
}
}
-
+
public void updateConfiguration(Configuration config) {
synchronized (this) {
int changes = mConfiguration.updateFrom(config);
@@ -97,8 +120,9 @@
public Entry get(String packageName, int resId, int[] styleable, int userId) {
synchronized (this) {
- Package pkg = mPackages.get(packageName);
- HashMap<int[], Entry> map = null;
+ WeakReference<Package> ref = mPackages.get(packageName);
+ Package pkg = (ref != null) ? ref.get() : null;
+ ArrayMap<int[], Entry> map = null;
Entry ent = null;
if (pkg != null) {
map = pkg.mMap.get(resId);
@@ -120,11 +144,11 @@
return null;
}
pkg = new Package(context);
- mPackages.put(packageName, pkg);
+ mPackages.put(packageName, new WeakReference<>(pkg));
}
if (map == null) {
- map = new HashMap<int[], Entry>();
+ map = new ArrayMap<>();
pkg.mMap.put(resId, map);
}
diff --git a/services/core/java/com/android/server/BluetoothManagerService.java b/services/core/java/com/android/server/BluetoothManagerService.java
index 831ce01..d58f864 100644
--- a/services/core/java/com/android/server/BluetoothManagerService.java
+++ b/services/core/java/com/android/server/BluetoothManagerService.java
@@ -657,19 +657,6 @@
Slog.d(TAG,"enable(): mBluetooth =" + mBluetooth +
" mBinding = " + mBinding + " mState = " + mState);
}
- // We do not honor ON requests when the adapter is already turned ON or in the process of
- // turning ON.
- // As a protective mechanism to make sure that the native stack gets cleaned up properly
- // before turning it back ON we ignore requests while the bluetooth is turning OFF.
- // Bug: b/28318203
- if (mState == BluetoothAdapter.STATE_BLE_TURNING_OFF ||
- mState == BluetoothAdapter.STATE_TURNING_OFF ||
- mState == BluetoothAdapter.STATE_ON ||
- mState == BluetoothAdapter.STATE_BLE_ON ||
- mState == BluetoothAdapter.STATE_TURNING_ON ||
- mState == BluetoothAdapter.STATE_BLE_TURNING_ON) {
- return false;
- }
synchronized(mReceiver) {
mQuietEnableExternal = false;
@@ -719,6 +706,7 @@
mBluetoothLock.writeLock().lock();
if (mUnbinding) return;
mUnbinding = true;
+ mHandler.removeMessages(MESSAGE_BLUETOOTH_STATE_CHANGE);
if (mBluetooth != null) {
//Unregister callback object
try {
@@ -1183,7 +1171,31 @@
}
mHandler.removeMessages(MESSAGE_RESTART_BLUETOOTH_SERVICE);
mEnable = true;
- handleEnable(msg.arg1 == 1);
+ if (mBluetooth == null) {
+ handleEnable(msg.arg1 == 1);
+ } else {
+ //
+ // We need to wait until transitioned to STATE_OFF and
+ // the previous Bluetooth process has exited. The
+ // waiting period has three components:
+ // (a) Wait until the local state is STATE_OFF. This
+ // is accomplished by "waitForOnOff(false, true)".
+ // (b) Wait until the STATE_OFF state is updated to
+ // all components.
+ // (c) Wait until the Bluetooth process exits, and
+ // ActivityManager detects it.
+ // The waiting for (b) and (c) is accomplished by
+ // delaying the MESSAGE_RESTART_BLUETOOTH_SERVICE
+ // message. On slower devices, that delay needs to be
+ // on the order of (2 * SERVICE_RESTART_TIME_MS).
+ //
+ waitForOnOff(false, true);
+ mQuietEnable = (msg.arg1 == 1);
+ Message restartMsg = mHandler.obtainMessage(
+ MESSAGE_RESTART_BLUETOOTH_SERVICE);
+ mHandler.sendMessageDelayed(restartMsg,
+ 2 * SERVICE_RESTART_TIME_MS);
+ }
break;
case MESSAGE_DISABLE:
@@ -1635,14 +1647,11 @@
if (newState == BluetoothAdapter.STATE_OFF) {
// If Bluetooth is off, send service down event to proxy objects, and unbind
if (DBG) Slog.d(TAG, "Bluetooth is complete turn off");
- if (canUnbindBluetoothService()) {
- if (DBG) Slog.d(TAG, "Good to unbind!");
- sendBluetoothServiceDownCallback();
- unbindAndFinish();
- sendBleStateChanged(prevState, newState);
- // Don't broadcast as it has already been broadcast before
- isStandardBroadcast = false;
- }
+ sendBluetoothServiceDownCallback();
+ unbindAndFinish();
+ sendBleStateChanged(prevState, newState);
+ // Don't broadcast as it has already been broadcast before
+ isStandardBroadcast = false;
} else if (!intermediate_off) {
// connect to GattService
@@ -1744,25 +1753,6 @@
quietMode ? 1 : 0, 0));
}
- private boolean canUnbindBluetoothService() {
- try {
- //Only unbind with mEnable flag not set
- //For race condition: disable and enable back-to-back
- //Avoid unbind right after enable due to callback from disable
- //Only unbind with Bluetooth at OFF state
- //Only unbind without any MESSAGE_BLUETOOTH_STATE_CHANGE message
- mBluetoothLock.readLock().lock();
- if (mEnable || (mBluetooth == null)) return false;
- if (mHandler.hasMessages(MESSAGE_BLUETOOTH_STATE_CHANGE)) return false;
- return (mBluetooth.getState() == BluetoothAdapter.STATE_OFF);
- } catch (RemoteException e) {
- Slog.e(TAG, "getState()", e);
- } finally {
- mBluetoothLock.readLock().unlock();
- }
- return false;
- }
-
private void recoverBluetoothServiceFromError() {
Slog.e(TAG,"recoverBluetoothServiceFromError");
try {
diff --git a/services/core/java/com/android/server/MasterClearReceiver.java b/services/core/java/com/android/server/MasterClearReceiver.java
index 1653db9..6f8edec 100644
--- a/services/core/java/com/android/server/MasterClearReceiver.java
+++ b/services/core/java/com/android/server/MasterClearReceiver.java
@@ -47,6 +47,7 @@
final String reason = intent.getStringExtra(Intent.EXTRA_REASON);
final boolean wipeExternalStorage = intent.getBooleanExtra(
Intent.EXTRA_WIPE_EXTERNAL_STORAGE, false);
+ final boolean forceWipe = intent.getBooleanExtra(Intent.EXTRA_FORCE_MASTER_CLEAR, false);
Slog.w(TAG, "!!! FACTORY RESET !!!");
// The reboot call is blocking, so we need to do it on another thread.
@@ -54,7 +55,7 @@
@Override
public void run() {
try {
- RecoverySystem.rebootWipeUserData(context, shutdown, reason);
+ RecoverySystem.rebootWipeUserData(context, shutdown, reason, forceWipe);
Log.wtf(TAG, "Still running after master clear?!");
} catch (IOException e) {
Slog.e(TAG, "Can't perform master clear/factory reset", e);
diff --git a/services/core/java/com/android/server/VibratorService.java b/services/core/java/com/android/server/VibratorService.java
index 4db60d5..7f3eb15 100644
--- a/services/core/java/com/android/server/VibratorService.java
+++ b/services/core/java/com/android/server/VibratorService.java
@@ -306,7 +306,6 @@
synchronized (mVibrations) {
removeVibrationLocked(token);
doCancelVibrateLocked();
- mCurrentVibration = vib;
addToPreviousVibrationsLocked(vib);
startVibrationLocked(vib);
}
@@ -368,7 +367,6 @@
} else {
// A negative repeat means that this pattern is not meant
// to repeat. Treat it like a simple vibration.
- mCurrentVibration = vib;
startVibrationLocked(vib);
}
addToPreviousVibrationsLocked(vib);
@@ -443,8 +441,7 @@
mCurrentVibration = null;
return;
}
- mCurrentVibration = mVibrations.getFirst();
- startVibrationLocked(mCurrentVibration);
+ startVibrationLocked(mVibrations.getFirst());
}
// Lock held on mVibrations
@@ -466,7 +463,9 @@
mode = mAppOpsService.startOperation(AppOpsManager.getToken(mAppOpsService),
AppOpsManager.OP_VIBRATE, vib.mUid, vib.mOpPkg);
}
- if (mode != AppOpsManager.MODE_ALLOWED) {
+ if (mode == AppOpsManager.MODE_ALLOWED) {
+ mCurrentVibration = vib;
+ } else {
if (mode == AppOpsManager.MODE_ERRORED) {
Slog.w(TAG, "Would be an error: vibrate from uid " + vib.mUid);
}
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index e07243f..b6097f5 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -11272,6 +11272,9 @@
} catch (RemoteException e) {
Log.w(TAG, "Content provider dead retrieving " + uri, e);
return null;
+ } catch (Exception e) {
+ Log.w(TAG, "Exception while determining type of " + uri, e);
+ return null;
} finally {
// We need to clear the identity to call removeContentProviderExternalUnchecked
if (!clearedIdentity) {
@@ -18578,7 +18581,7 @@
&& config.navigation == Configuration.NAVIGATION_NONAV);
int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
- && (modeType != Configuration.UI_MODE_TYPE_WATCH || "eng".equals(Build.TYPE)));
+ && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
}
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index ba044cc4..b77381c 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -73,7 +73,6 @@
import static com.android.server.am.ActivityRecord.STARTING_WINDOW_REMOVED;
import static com.android.server.am.ActivityRecord.STARTING_WINDOW_SHOWN;
import static com.android.server.am.ActivityStackSupervisor.FindTaskResult;
-import static com.android.server.am.ActivityStackSupervisor.MOVING;
import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_CLOSE;
@@ -4464,6 +4463,7 @@
// Short circuit: if the two configurations are equal (the common case), then there is
// nothing to do.
final Configuration newConfig = mService.mConfiguration;
+ r.task.sanitizeOverrideConfiguration(newConfig);
final Configuration taskConfig = r.task.mOverrideConfig;
if (r.configuration.equals(newConfig)
&& r.taskConfigOverride.equals(taskConfig)
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index 197d9ec..1cf121c 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -3525,7 +3525,9 @@
}
void showLockTaskToast() {
- mLockTaskNotify.showToast(mLockTaskModeState);
+ if (mLockTaskNotify != null) {
+ mLockTaskNotify.showToast(mLockTaskModeState);
+ }
}
void showLockTaskEscapeMessageLocked(TaskRecord task) {
@@ -4402,6 +4404,12 @@
"startActivityFromRecentsInner: Task " + taskId + " not found.");
}
+ // Since we don't have an actual source record here, we assume that the currently focused
+ // activity was the source.
+ final ActivityStack focusedStack = getFocusedStack();
+ final ActivityRecord sourceRecord =
+ focusedStack != null ? focusedStack.topActivity() : null;
+
if (launchStackId != INVALID_STACK_ID) {
if (task.stack.mStackId != launchStackId) {
moveTaskToStackLocked(
@@ -4414,6 +4422,7 @@
// Work Challenge is present) let startActivityInPackage handle the intercepting.
if (!mService.mUserController.shouldConfirmCredentials(task.userId)
&& task.getRootActivity() != null) {
+ mService.mActivityStarter.sendPowerHintForLaunchIfNeeded(true /* forceSend */);
mActivityMetricsLogger.notifyActivityLaunching();
mService.moveTaskToFrontLocked(task.taskId, 0, bOptions);
mActivityMetricsLogger.notifyActivityLaunched(ActivityManager.START_TASK_TO_FRONT,
@@ -4425,6 +4434,11 @@
if (launchStackId == DOCKED_STACK_ID) {
setResizingDuringAnimation(taskId);
}
+
+ mService.mActivityStarter.postStartActivityUncheckedProcessing(task.getTopActivity(),
+ ActivityManager.START_TASK_TO_FRONT,
+ sourceRecord != null ? sourceRecord.task.stack.mStackId : INVALID_STACK_ID,
+ sourceRecord, task.stack);
return ActivityManager.START_TASK_TO_FRONT;
}
callingUid = task.mCallingUid;
diff --git a/services/core/java/com/android/server/am/ActivityStarter.java b/services/core/java/com/android/server/am/ActivityStarter.java
index 7101937..8dc13d4 100644
--- a/services/core/java/com/android/server/am/ActivityStarter.java
+++ b/services/core/java/com/android/server/am/ActivityStarter.java
@@ -102,6 +102,7 @@
import android.os.Build;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.PowerManagerInternal;
import android.os.RemoteException;
import android.os.SystemClock;
import android.os.UserHandle;
@@ -172,6 +173,7 @@
private boolean mNoAnimation;
private boolean mKeepCurTransition;
private boolean mAvoidMoveToFront;
+ private boolean mPowerHintSent;
private IVoiceInteractionSession mVoiceSession;
private IVoiceInteractor mVoiceInteractor;
@@ -210,6 +212,8 @@
mKeepCurTransition = false;
mAvoidMoveToFront = false;
+ mPowerHintSent = false;
+
mVoiceSession = null;
mVoiceInteractor = null;
}
@@ -536,12 +540,13 @@
} finally {
mService.mWindowManager.continueSurfaceLayout();
}
- postStartActivityUncheckedProcessing(r, err, stack.mStackId);
+ postStartActivityUncheckedProcessing(r, err, stack.mStackId, mSourceRecord, mTargetStack);
return err;
}
void postStartActivityUncheckedProcessing(
- ActivityRecord r, int result, int prevFocusedStackId) {
+ ActivityRecord r, int result, int prevFocusedStackId, ActivityRecord sourceRecord,
+ ActivityStack targetStack) {
if (result < START_SUCCESS) {
// If someone asked to have the keyguard dismissed on the next activity start,
@@ -555,7 +560,7 @@
if (r.task != null && r.task.stack != null) {
startedActivityStackId = r.task.stack.mStackId;
} else if (mTargetStack != null) {
- startedActivityStackId = mTargetStack.mStackId;
+ startedActivityStackId = targetStack.mStackId;
}
// If we launched the activity from a no display activity that was launched from the home
@@ -563,9 +568,9 @@
// noDisplay activity will be finished shortly after.
// TODO: We should prevent noDisplay activities from affecting task/stack ordering and
// visibility instead of using this flag.
- final boolean noDisplayActivityOverHome = mSourceRecord != null
- && mSourceRecord.noDisplay
- && mSourceRecord.task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE;
+ final boolean noDisplayActivityOverHome = sourceRecord != null
+ && sourceRecord.noDisplay
+ && sourceRecord.task.getTaskToReturnTo() == HOME_ACTIVITY_TYPE;
if (startedActivityStackId == DOCKED_STACK_ID
&& (prevFocusedStackId == HOME_STACK_ID || noDisplayActivityOverHome)) {
final ActivityStack homeStack = mSupervisor.getStack(HOME_STACK_ID);
@@ -942,6 +947,20 @@
return START_SUCCESS;
}
+ void sendPowerHintForLaunchIfNeeded(boolean forceSend) {
+ // Trigger launch power hint if activity is not in the current task
+ final ActivityStack focusStack = mSupervisor.getFocusedStack();
+ final ActivityRecord curTop = (focusStack == null)
+ ? null : focusStack.topRunningNonDelayedActivityLocked(mNotTop);
+ if ((forceSend || (!mPowerHintSent && curTop != null &&
+ curTop.task != null && mStartActivity != null &&
+ curTop.task != mStartActivity.task )) &&
+ mService.mLocalPowerManager != null) {
+ mService.mLocalPowerManager.powerHint(PowerManagerInternal.POWER_HINT_LAUNCH, 0);
+ mPowerHintSent = true;
+ }
+ }
+
private int startActivityUnchecked(final ActivityRecord r, ActivityRecord sourceRecord,
IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor,
int startFlags, boolean doResume, ActivityOptions options, TaskRecord inTask) {
@@ -1003,6 +1022,8 @@
}
}
+ sendPowerHintForLaunchIfNeeded(false /* forceSend */);
+
mReusedActivity = setTargetStackAndMoveToFrontIfNeeded(mReusedActivity);
if ((mStartFlags & START_FLAG_ONLY_IF_NEEDED) != 0) {
@@ -1125,6 +1146,9 @@
ActivityStack.logStartActivity(
EventLogTags.AM_CREATE_ACTIVITY, mStartActivity, mStartActivity.task);
mTargetStack.mLastPausedActivity = null;
+
+ sendPowerHintForLaunchIfNeeded(false /* forceSend */);
+
mTargetStack.startActivityLocked(mStartActivity, newTask, mKeepCurTransition, mOptions);
if (mDoResume) {
if (!mLaunchTaskBehind) {
@@ -1788,7 +1812,8 @@
final int result = startActivityUnchecked(
pal.r, pal.sourceRecord, null, null, pal.startFlags, resume, null, null);
postStartActivityUncheckedProcessing(
- pal.r, result, mSupervisor.mFocusedStack.mStackId);
+ pal.r, result, mSupervisor.mFocusedStack.mStackId, mSourceRecord,
+ mTargetStack);
} catch (Exception e) {
Slog.e(TAG, "Exception during pending activity launch pal=" + pal, e);
pal.sendErrorResult(e.getMessage());
diff --git a/services/core/java/com/android/server/am/RetailDemoModeService.java b/services/core/java/com/android/server/am/RetailDemoModeService.java
index a1106f5..6a5ec96 100644
--- a/services/core/java/com/android/server/am/RetailDemoModeService.java
+++ b/services/core/java/com/android/server/am/RetailDemoModeService.java
@@ -17,22 +17,29 @@
package com.android.server.am;
import android.app.ActivityManagerNative;
+import android.app.AppGlobals;
import android.app.Notification;
import android.app.NotificationManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
+import android.content.ComponentName;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
+import android.content.pm.IPackageManager;
+import android.content.pm.PackageManager;
import android.content.pm.UserInfo;
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Handler;
+import android.os.Looper;
+import android.os.Message;
import android.os.PowerManager;
-import android.os.ServiceManager;
+import android.os.RemoteException;
+import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.provider.Settings;
@@ -40,10 +47,9 @@
import com.android.internal.os.BackgroundThread;
import com.android.internal.R;
+import com.android.internal.widget.LockPatternUtils;
import com.android.server.ServiceThread;
import com.android.server.SystemService;
-import com.android.server.pm.UserManagerService;
-
import java.io.File;
public class RetailDemoModeService extends SystemService {
@@ -53,42 +59,89 @@
private static final String DEMO_USER_NAME = "Demo";
private static final String ACTION_RESET_DEMO = "com.android.server.am.ACTION_RESET_DEMO";
- private static final long SCREEN_WAKEUP_DELAY = 5000;
+ private static final int MSG_TURN_SCREEN_ON = 0;
+ private static final int MSG_INACTIVITY_TIME_OUT = 1;
+ private static final int MSG_START_NEW_SESSION = 2;
+ private static final long SCREEN_WAKEUP_DELAY = 2500;
+ private static final long USER_INACTIVITY_TIMEOUT = 30000;
+
+ boolean mDeviceInDemoMode = false;
private ActivityManagerService mAms;
- private UserManagerService mUms;
private NotificationManager mNm;
+ private UserManager mUm;
private PowerManager mPm;
private PowerManager.WakeLock mWakeLock;
- private Handler mHandler;
+ Handler mHandler;
private ServiceThread mHandlerThread;
private PendingIntent mResetDemoPendingIntent;
private BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
- if (!UserManager.isDeviceInDemoMode(getContext())) {
+ if (!mDeviceInDemoMode) {
return;
}
switch (intent.getAction()) {
case Intent.ACTION_SCREEN_OFF:
- mHandler.postDelayed(new Runnable() {
- @Override
- public void run() {
- if (mWakeLock.isHeld()) {
- mWakeLock.release();
- }
- mWakeLock.acquire();
- }
- }, SCREEN_WAKEUP_DELAY);
+ mHandler.removeMessages(MSG_TURN_SCREEN_ON);
+ mHandler.sendEmptyMessageDelayed(MSG_TURN_SCREEN_ON, SCREEN_WAKEUP_DELAY);
break;
case ACTION_RESET_DEMO:
- createAndSwitchToDemoUser();
+ mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
break;
}
}
};
+ final class MainHandler extends Handler {
+
+ MainHandler(Looper looper) {
+ super(looper, null, true);
+ }
+
+ @Override
+ public void handleMessage(Message msg) {
+ switch (msg.what) {
+ case MSG_TURN_SCREEN_ON:
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ }
+ mWakeLock.acquire();
+ break;
+ case MSG_INACTIVITY_TIME_OUT:
+ IPackageManager pm = AppGlobals.getPackageManager();
+ int enabledState = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
+ String demoLauncherComponent = getContext().getResources()
+ .getString(R.string.config_demoModeLauncherComponent);
+ try {
+ enabledState = pm.getComponentEnabledSetting(
+ ComponentName.unflattenFromString(demoLauncherComponent),
+ getActivityManager().getCurrentUser().id);
+ } catch (RemoteException exc) {
+ // XXX: shouldn't happen
+ }
+ if (enabledState == PackageManager.COMPONENT_ENABLED_STATE_DISABLED) {
+ Slog.i(TAG, "Restarting session due to user inactivity timeout");
+ sendEmptyMessage(MSG_START_NEW_SESSION);
+ }
+ break;
+ case MSG_START_NEW_SESSION:
+ if (DEBUG) {
+ Slog.d(TAG, "Switching to a new demo user");
+ }
+ removeMessages(MSG_START_NEW_SESSION);
+ UserInfo demoUser = getUserManager().createUser(DEMO_USER_NAME,
+ UserInfo.FLAG_DEMO | UserInfo.FLAG_EPHEMERAL);
+ if (demoUser != null) {
+ setupDemoUser(demoUser);
+ getActivityManager().switchUser(demoUser.id);
+ }
+ break;
+ }
+ }
+ }
+
public RetailDemoModeService(Context context) {
super(context);
}
@@ -102,6 +155,7 @@
.setShowWhen(false)
.setVisibility(Notification.VISIBILITY_PUBLIC)
.setContentIntent(getResetDemoPendingIntent())
+ .setColor(getContext().getColor(R.color.system_notification_accent_color))
.build();
}
@@ -113,20 +167,17 @@
return mResetDemoPendingIntent;
}
- private void createAndSwitchToDemoUser() {
- if (DEBUG) {
- Slog.d(TAG, "Switching to a new demo user");
- }
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- UserInfo demoUser = getUserManager().createUser(DEMO_USER_NAME,
- UserInfo.FLAG_DEMO | UserInfo.FLAG_EPHEMERAL);
- if (demoUser != null) {
- getActivityManager().switchUser(demoUser.id);
- }
- }
- });
+ void setupDemoUser(UserInfo userInfo) {
+ UserManager um = getUserManager();
+ UserHandle user = UserHandle.of(userInfo.id);
+ LockPatternUtils lockPatternUtils = new LockPatternUtils(getContext());
+ lockPatternUtils.setLockScreenDisabled(true, userInfo.id);
+ um.setUserRestriction(UserManager.DISALLOW_CONFIG_WIFI, true, user);
+ um.setUserRestriction(UserManager.DISALLOW_INSTALL_UNKNOWN_SOURCES, true, user);
+ um.setUserRestriction(UserManager.DISALLOW_CONFIG_MOBILE_NETWORKS, true, user);
+ um.setUserRestriction(UserManager.DISALLOW_USB_FILE_TRANSFER, true, user);
+ Settings.Secure.putIntForUser(getContext().getContentResolver(),
+ Settings.Secure.SKIP_FIRST_USE_HINTS, 1, userInfo.id);
}
private ActivityManagerService getActivityManager() {
@@ -136,12 +187,11 @@
return mAms;
}
- private UserManagerService getUserManager() {
- if (mUms == null) {
- mUms = (UserManagerService) UserManagerService.Stub
- .asInterface(ServiceManager.getService(Context.USER_SERVICE));
+ private UserManager getUserManager() {
+ if (mUm == null) {
+ mUm = getContext().getSystemService(UserManager.class);
}
- return mUms;
+ return mUm;
}
private void registerSettingsChangeObserver() {
@@ -152,14 +202,16 @@
final ContentObserver deviceDemoModeSettingObserver = new ContentObserver(mHandler) {
@Override
public void onChange(boolean selfChange, Uri uri, int userId) {
- boolean deviceInDemoMode = UserManager.isDeviceInDemoMode(getContext());
if (deviceDemoModeUri.equals(uri)) {
- if (deviceInDemoMode) {
- createAndSwitchToDemoUser();
+ mDeviceInDemoMode = UserManager.isDeviceInDemoMode(getContext());
+ if (mDeviceInDemoMode) {
+ mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
+ } else if (mWakeLock.isHeld()) {
+ mWakeLock.release();
}
}
// If device is provisioned and left demo mode - run the cleanup in demo folder
- if (!deviceInDemoMode && isDeviceProvisioned()) {
+ if (!mDeviceInDemoMode && isDeviceProvisioned()) {
// Run on the bg thread to not block the fg thread
BackgroundThread.getHandler().post(new Runnable() {
@Override
@@ -204,7 +256,8 @@
mHandlerThread = new ServiceThread(TAG, android.os.Process.THREAD_PRIORITY_FOREGROUND,
false);
mHandlerThread.start();
- mHandler = new Handler(mHandlerThread.getLooper(), null, true);
+ mHandler = new MainHandler(mHandlerThread.getLooper());
+ publishLocalService(RetailDemoModeServiceInternal.class, mLocalService);
}
@Override
@@ -218,7 +271,8 @@
mNm = NotificationManager.from(getContext());
if (UserManager.isDeviceInDemoMode(getContext())) {
- createAndSwitchToDemoUser();
+ mDeviceInDemoMode = true;
+ mHandler.sendEmptyMessage(MSG_START_NEW_SESSION);
}
registerSettingsChangeObserver();
registerBroadcastReceiver();
@@ -226,16 +280,15 @@
@Override
public void onSwitchUser(int userId) {
+ if (!mDeviceInDemoMode) {
+ return;
+ }
if (DEBUG) {
Slog.d(TAG, "onSwitchUser: " + userId);
}
UserInfo ui = getUserManager().getUserInfo(userId);
if (!ui.isDemo()) {
- if (UserManager.isDeviceInDemoMode(getContext())) {
- Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode");
- } else if (mWakeLock.isHeld()) {
- mWakeLock.release();
- }
+ Slog.wtf(TAG, "Should not allow switch to non-demo user in demo mode");
return;
}
if (!mWakeLock.isHeld()) {
@@ -243,4 +296,23 @@
}
mNm.notifyAsUser(TAG, 1, createResetNotification(), UserHandle.of(userId));
}
+
+ public RetailDemoModeServiceInternal mLocalService = new RetailDemoModeServiceInternal() {
+ private static final long USER_ACTIVITY_DEBOUNCE_TIME = 2000;
+ private long mLastUserActivityTime = 0;
+
+ @Override
+ public void onUserActivity() {
+ if (!mDeviceInDemoMode) {
+ return;
+ }
+ long timeOfActivity = SystemClock.uptimeMillis();
+ if (timeOfActivity < mLastUserActivityTime + USER_ACTIVITY_DEBOUNCE_TIME) {
+ return;
+ }
+ mLastUserActivityTime = timeOfActivity;
+ mHandler.removeMessages(MSG_INACTIVITY_TIME_OUT);
+ mHandler.sendEmptyMessageDelayed(MSG_INACTIVITY_TIME_OUT, USER_INACTIVITY_TIMEOUT);
+ }
+ };
}
diff --git a/services/core/java/com/android/server/am/RetailDemoModeServiceInternal.java b/services/core/java/com/android/server/am/RetailDemoModeServiceInternal.java
new file mode 100644
index 0000000..32de03a
--- /dev/null
+++ b/services/core/java/com/android/server/am/RetailDemoModeServiceInternal.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License
+ */
+
+package com.android.server.am;
+
+public interface RetailDemoModeServiceInternal {
+ public void onUserActivity();
+}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/am/TaskRecord.java b/services/core/java/com/android/server/am/TaskRecord.java
index 8e9af40..578fc44 100644
--- a/services/core/java/com/android/server/am/TaskRecord.java
+++ b/services/core/java/com/android/server/am/TaskRecord.java
@@ -73,6 +73,8 @@
import static android.content.pm.ActivityInfo.RESIZE_MODE_CROP_WINDOWS;
import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
import static android.content.pm.ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
+import static android.content.res.Configuration.SCREENLAYOUT_LONG_MASK;
+import static android.content.res.Configuration.SCREENLAYOUT_SIZE_MASK;
import static android.provider.Settings.Secure.USER_SETUP_COMPLETE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ADD_REMOVE;
import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
@@ -1574,6 +1576,29 @@
return bounds;
}
+ /**
+ * Update fields that are not overridden for task from global configuration.
+ *
+ * @param globalConfig global configuration to update from.
+ */
+ void sanitizeOverrideConfiguration(Configuration globalConfig) {
+ // If it's fullscreen, the override config should be empty and we should leave it alone.
+ if (mFullscreen) {
+ return;
+ }
+
+ // screenLayout field is set in #calculateOverrideConfig but only part of it is really
+ // overridden - aspect ratio and size. Other flags (like layout direction) can be updated
+ // separately in global config and they also must be updated in override config.
+ int overrideScreenLayout = mOverrideConfig.screenLayout;
+ int newScreenLayout = globalConfig.screenLayout;
+ newScreenLayout = (newScreenLayout & ~SCREENLAYOUT_LONG_MASK)
+ | (overrideScreenLayout & SCREENLAYOUT_LONG_MASK);
+ newScreenLayout = (newScreenLayout & ~SCREENLAYOUT_SIZE_MASK)
+ | (overrideScreenLayout & SCREENLAYOUT_SIZE_MASK);
+ mOverrideConfig.screenLayout = newScreenLayout;
+ }
+
static Rect validateBounds(Rect bounds) {
if (bounds != null && bounds.isEmpty()) {
Slog.wtf(TAG, "Received strange task bounds: " + bounds, new Throwable());
diff --git a/services/core/java/com/android/server/am/UserSwitchingDialog.java b/services/core/java/com/android/server/am/UserSwitchingDialog.java
index 10e88e6..7022856 100644
--- a/services/core/java/com/android/server/am/UserSwitchingDialog.java
+++ b/services/core/java/com/android/server/am/UserSwitchingDialog.java
@@ -68,6 +68,12 @@
String viewMessage;
if (UserManager.isSplitSystemUser() && newUser.id == UserHandle.USER_SYSTEM) {
viewMessage = res.getString(R.string.user_logging_out_message, oldUser.name);
+ } else if (UserManager.isDeviceInDemoMode(context)) {
+ if (oldUser.isDemo()) {
+ viewMessage = res.getString(R.string.demo_restarting_message);
+ } else {
+ viewMessage = res.getString(R.string.demo_starting_message);
+ }
} else {
viewMessage = res.getString(R.string.user_switching_message, newUser.name);
}
diff --git a/services/core/java/com/android/server/job/JobPackageTracker.java b/services/core/java/com/android/server/job/JobPackageTracker.java
index eb5edd3..ba96b74 100644
--- a/services/core/java/com/android/server/job/JobPackageTracker.java
+++ b/services/core/java/com/android/server/job/JobPackageTracker.java
@@ -105,6 +105,8 @@
final long mStartElapsedTime;
final long mStartClockTime;
long mSummedTime;
+ int mMaxTotalActive;
+ int mMaxFgActive;
public DataSet(DataSet otherTimes) {
mStartUptimeTime = otherTimes.mStartUptimeTime;
@@ -257,6 +259,12 @@
}
}
}
+ if (mMaxTotalActive > out.mMaxTotalActive) {
+ out.mMaxTotalActive = mMaxTotalActive;
+ }
+ if (mMaxFgActive > out.mMaxFgActive) {
+ out.mMaxFgActive = mMaxFgActive;
+ }
}
void printDuration(PrintWriter pw, long period, long duration, int count, String suffix) {
@@ -317,6 +325,9 @@
pw.println();
}
}
+ pw.print(prefix); pw.print(" Max concurrency: ");
+ pw.print(mMaxTotalActive); pw.print(" total, ");
+ pw.print(mMaxFgActive); pw.println(" foreground");
}
}
@@ -366,6 +377,15 @@
addEvent(EVENT_STOP_JOB, job.getSourceUid(), job.getBatteryName());
}
+ public void noteConcurrency(int totalActive, int fgActive) {
+ if (totalActive > mCurDataSet.mMaxTotalActive) {
+ mCurDataSet.mMaxTotalActive = totalActive;
+ }
+ if (fgActive > mCurDataSet.mMaxFgActive) {
+ mCurDataSet.mMaxFgActive = fgActive;
+ }
+ }
+
public float getLoadFactor(JobStatus job) {
final int uid = job.getSourceUid();
final String pkg = job.getSourcePackageName();
diff --git a/services/core/java/com/android/server/job/JobSchedulerService.java b/services/core/java/com/android/server/job/JobSchedulerService.java
index 1b8eccb..27b3aa2 100644
--- a/services/core/java/com/android/server/job/JobSchedulerService.java
+++ b/services/core/java/com/android/server/job/JobSchedulerService.java
@@ -23,6 +23,8 @@
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
@@ -37,6 +39,7 @@
import android.app.job.IJobScheduler;
import android.content.BroadcastReceiver;
import android.content.ComponentName;
+import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
@@ -44,6 +47,7 @@
import android.content.pm.PackageManager;
import android.content.pm.ServiceInfo;
import android.content.pm.PackageManager.NameNotFoundException;
+import android.database.ContentObserver;
import android.net.Uri;
import android.os.BatteryStats;
import android.os.Binder;
@@ -57,6 +61,8 @@
import android.os.ServiceManager;
import android.os.SystemClock;
import android.os.UserHandle;
+import android.provider.Settings;
+import android.util.KeyValueListParser;
import android.util.Slog;
import android.util.SparseArray;
import android.util.SparseIntArray;
@@ -98,17 +104,12 @@
public static final boolean DEBUG = false;
/** The maximum number of concurrent jobs we run at one time. */
- private static final int MAX_JOB_CONTEXTS_COUNT = 12;
- /** The number of MAX_JOB_CONTEXTS_COUNT we reserve for the foreground app. */
- private static final int FG_JOB_CONTEXTS_COUNT = 4;
+ private static final int MAX_JOB_CONTEXTS_COUNT = 16;
/** Enforce a per-app limit on scheduled jobs? */
private static final boolean ENFORCE_MAX_JOBS = true;
/** The maximum number of jobs that we allow an unprivileged app to schedule */
private static final int MAX_JOBS_PER_APP = 100;
- /** This is the job execution factor that is considered to be heavy use of the system. */
- private static final float HEAVY_USE_FACTOR = .9f;
- /** This is the job execution factor that is considered to be moderate use of the system. */
- private static final float MODERATE_USE_FACTOR = .5f;
+
/** Global local for all job scheduler state. */
final Object mLock = new Object();
@@ -122,34 +123,6 @@
static final int MSG_STOP_JOB = 2;
static final int MSG_CHECK_JOB_GREEDY = 3;
- // Policy constants
- /**
- * Minimum # of idle jobs that must be ready in order to force the JMS to schedule things
- * early.
- */
- static final int MIN_IDLE_COUNT = 1;
- /**
- * Minimum # of charging jobs that must be ready in order to force the JMS to schedule things
- * early.
- */
- static final int MIN_CHARGING_COUNT = 1;
- /**
- * Minimum # of connectivity jobs that must be ready in order to force the JMS to schedule
- * things early.
- */
- static final int MIN_CONNECTIVITY_COUNT = 1; // Run connectivity jobs as soon as ready.
- /**
- * Minimum # of content trigger jobs that must be ready in order to force the JMS to schedule
- * things early.
- */
- static final int MIN_CONTENT_COUNT = 1;
- /**
- * Minimum # of jobs (with no particular constraints) for which the JMS will be happy running
- * some work early.
- * This is correlated with the amount of batching we'll be able to do.
- */
- static final int MIN_READY_JOBS_COUNT = 2;
-
/**
* Track Services that have currently active or pending jobs. The index is provided by
* {@link JobStatus#getServiceToken()}
@@ -186,7 +159,7 @@
* Current limit on the number of concurrent JobServiceContext entries we want to
* keep actively running a job.
*/
- int mMaxActiveJobs = MAX_JOB_CONTEXTS_COUNT - FG_JOB_CONTEXTS_COUNT;
+ int mMaxActiveJobs = 1;
/**
* Which uids are currently in the foreground.
@@ -212,6 +185,211 @@
int[] mTmpAssignPreferredUidForContext = new int[MAX_JOB_CONTEXTS_COUNT];
/**
+ * All times are in milliseconds. These constants are kept synchronized with the system
+ * global Settings. Any access to this class or its fields should be done while
+ * holding the JobSchedulerService.mLock lock.
+ */
+ private final class Constants extends ContentObserver {
+ // Key names stored in the settings value.
+ private static final String KEY_MIN_IDLE_COUNT = "min_idle_count";
+ private static final String KEY_MIN_CHARGING_COUNT = "min_charging_count";
+ private static final String KEY_MIN_CONNECTIVITY_COUNT = "min_connectivity_count";
+ private static final String KEY_MIN_CONTENT_COUNT = "min_content_count";
+ private static final String KEY_MIN_READY_JOBS_COUNT = "min_ready_jobs_count";
+ private static final String KEY_HEAVY_USE_FACTOR = "heavy_use_factor";
+ private static final String KEY_MODERATE_USE_FACTOR = "moderate_use_factor";
+ private static final String KEY_FG_JOB_COUNT = "fg_job_count";
+ private static final String KEY_BG_NORMAL_JOB_COUNT = "bg_normal_job_count";
+ private static final String KEY_BG_MODERATE_JOB_COUNT = "bg_moderate_job_count";
+ private static final String KEY_BG_LOW_JOB_COUNT = "bg_low_job_count";
+ private static final String KEY_BG_CRITICAL_JOB_COUNT = "bg_critical_job_count";
+
+ private static final int DEFAULT_MIN_IDLE_COUNT = 1;
+ private static final int DEFAULT_MIN_CHARGING_COUNT = 1;
+ private static final int DEFAULT_MIN_CONNECTIVITY_COUNT = 1;
+ private static final int DEFAULT_MIN_CONTENT_COUNT = 1;
+ private static final int DEFAULT_MIN_READY_JOBS_COUNT = 1;
+ private static final float DEFAULT_HEAVY_USE_FACTOR = .9f;
+ private static final float DEFAULT_MODERATE_USE_FACTOR = .5f;
+ private static final int DEFAULT_FG_JOB_COUNT = 4;
+ private static final int DEFAULT_BG_NORMAL_JOB_COUNT = 6;
+ private static final int DEFAULT_BG_MODERATE_JOB_COUNT = 4;
+ private static final int DEFAULT_BG_LOW_JOB_COUNT = 2;
+ private static final int DEFAULT_BG_CRITICAL_JOB_COUNT = 1;
+
+ /**
+ * Minimum # of idle jobs that must be ready in order to force the JMS to schedule things
+ * early.
+ */
+ int MIN_IDLE_COUNT = DEFAULT_MIN_IDLE_COUNT;
+ /**
+ * Minimum # of charging jobs that must be ready in order to force the JMS to schedule
+ * things early.
+ */
+ int MIN_CHARGING_COUNT = DEFAULT_MIN_CHARGING_COUNT;
+ /**
+ * Minimum # of connectivity jobs that must be ready in order to force the JMS to schedule
+ * things early. 1 == Run connectivity jobs as soon as ready.
+ */
+ int MIN_CONNECTIVITY_COUNT = DEFAULT_MIN_CONNECTIVITY_COUNT;
+ /**
+ * Minimum # of content trigger jobs that must be ready in order to force the JMS to
+ * schedule things early.
+ */
+ int MIN_CONTENT_COUNT = DEFAULT_MIN_CONTENT_COUNT;
+ /**
+ * Minimum # of jobs (with no particular constraints) for which the JMS will be happy
+ * running some work early. This (and thus the other min counts) is now set to 1, to
+ * prevent any batching at this level. Since we now do batching through doze, that is
+ * a much better mechanism.
+ */
+ int MIN_READY_JOBS_COUNT = DEFAULT_MIN_READY_JOBS_COUNT;
+ /**
+ * This is the job execution factor that is considered to be heavy use of the system.
+ */
+ float HEAVY_USE_FACTOR = DEFAULT_HEAVY_USE_FACTOR;
+ /**
+ * This is the job execution factor that is considered to be moderate use of the system.
+ */
+ float MODERATE_USE_FACTOR = DEFAULT_MODERATE_USE_FACTOR;
+ /**
+ * The number of MAX_JOB_CONTEXTS_COUNT we reserve for the foreground app.
+ */
+ int FG_JOB_COUNT = DEFAULT_FG_JOB_COUNT;
+ /**
+ * The maximum number of background jobs we allow when the system is in a normal
+ * memory state.
+ */
+ int BG_NORMAL_JOB_COUNT = DEFAULT_BG_NORMAL_JOB_COUNT;
+ /**
+ * The maximum number of background jobs we allow when the system is in a moderate
+ * memory state.
+ */
+ int BG_MODERATE_JOB_COUNT = DEFAULT_BG_MODERATE_JOB_COUNT;
+ /**
+ * The maximum number of background jobs we allow when the system is in a low
+ * memory state.
+ */
+ int BG_LOW_JOB_COUNT = DEFAULT_BG_LOW_JOB_COUNT;
+ /**
+ * The maximum number of background jobs we allow when the system is in a critical
+ * memory state.
+ */
+ int BG_CRITICAL_JOB_COUNT = DEFAULT_BG_CRITICAL_JOB_COUNT;
+
+ private ContentResolver mResolver;
+ private final KeyValueListParser mParser = new KeyValueListParser(',');
+
+ public Constants(Handler handler) {
+ super(handler);
+ }
+
+ public void start(ContentResolver resolver) {
+ mResolver = resolver;
+ mResolver.registerContentObserver(Settings.Global.getUriFor(
+ Settings.Global.JOB_SCHEDULER_CONSTANTS), false, this);
+ updateConstants();
+ }
+
+ @Override
+ public void onChange(boolean selfChange, Uri uri) {
+ updateConstants();
+ }
+
+ private void updateConstants() {
+ synchronized (mLock) {
+ try {
+ mParser.setString(Settings.Global.getString(mResolver,
+ Settings.Global.ALARM_MANAGER_CONSTANTS));
+ } catch (IllegalArgumentException e) {
+ // Failed to parse the settings string, log this and move on
+ // with defaults.
+ Slog.e(TAG, "Bad device idle settings", e);
+ }
+
+ MIN_IDLE_COUNT = mParser.getInt(KEY_MIN_IDLE_COUNT,
+ DEFAULT_MIN_IDLE_COUNT);
+ MIN_CHARGING_COUNT = mParser.getInt(KEY_MIN_CHARGING_COUNT,
+ DEFAULT_MIN_CHARGING_COUNT);
+ MIN_CONNECTIVITY_COUNT = mParser.getInt(KEY_MIN_CONNECTIVITY_COUNT,
+ DEFAULT_MIN_CONNECTIVITY_COUNT);
+ MIN_CONTENT_COUNT = mParser.getInt(KEY_MIN_CONTENT_COUNT,
+ DEFAULT_MIN_CONTENT_COUNT);
+ MIN_READY_JOBS_COUNT = mParser.getInt(KEY_MIN_READY_JOBS_COUNT,
+ DEFAULT_MIN_READY_JOBS_COUNT);
+ HEAVY_USE_FACTOR = mParser.getFloat(KEY_HEAVY_USE_FACTOR,
+ DEFAULT_HEAVY_USE_FACTOR);
+ MODERATE_USE_FACTOR = mParser.getFloat(KEY_MODERATE_USE_FACTOR,
+ DEFAULT_MODERATE_USE_FACTOR);
+ FG_JOB_COUNT = mParser.getInt(KEY_FG_JOB_COUNT,
+ DEFAULT_FG_JOB_COUNT);
+ BG_NORMAL_JOB_COUNT = mParser.getInt(KEY_BG_NORMAL_JOB_COUNT,
+ DEFAULT_BG_NORMAL_JOB_COUNT);
+ if ((FG_JOB_COUNT+BG_NORMAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+ BG_NORMAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+ }
+ BG_MODERATE_JOB_COUNT = mParser.getInt(KEY_BG_MODERATE_JOB_COUNT,
+ DEFAULT_BG_MODERATE_JOB_COUNT);
+ if ((FG_JOB_COUNT+BG_MODERATE_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+ BG_MODERATE_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+ }
+ BG_LOW_JOB_COUNT = mParser.getInt(KEY_BG_LOW_JOB_COUNT,
+ DEFAULT_BG_LOW_JOB_COUNT);
+ if ((FG_JOB_COUNT+BG_LOW_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+ BG_LOW_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+ }
+ BG_CRITICAL_JOB_COUNT = mParser.getInt(KEY_BG_CRITICAL_JOB_COUNT,
+ DEFAULT_BG_CRITICAL_JOB_COUNT);
+ if ((FG_JOB_COUNT+BG_CRITICAL_JOB_COUNT) > MAX_JOB_CONTEXTS_COUNT) {
+ BG_CRITICAL_JOB_COUNT = MAX_JOB_CONTEXTS_COUNT - FG_JOB_COUNT;
+ }
+ }
+ }
+
+ void dump(PrintWriter pw) {
+ pw.println(" Settings:");
+
+ pw.print(" "); pw.print(KEY_MIN_IDLE_COUNT); pw.print("=");
+ pw.print(MIN_IDLE_COUNT); pw.println();
+
+ pw.print(" "); pw.print(KEY_MIN_CHARGING_COUNT); pw.print("=");
+ pw.print(MIN_CHARGING_COUNT); pw.println();
+
+ pw.print(" "); pw.print(KEY_MIN_CONNECTIVITY_COUNT); pw.print("=");
+ pw.print(MIN_CONNECTIVITY_COUNT); pw.println();
+
+ pw.print(" "); pw.print(KEY_MIN_CONTENT_COUNT); pw.print("=");
+ pw.print(MIN_CONTENT_COUNT); pw.println();
+
+ pw.print(" "); pw.print(KEY_MIN_READY_JOBS_COUNT); pw.print("=");
+ pw.print(MIN_READY_JOBS_COUNT); pw.println();
+
+ pw.print(" "); pw.print(KEY_HEAVY_USE_FACTOR); pw.print("=");
+ pw.print(HEAVY_USE_FACTOR); pw.println();
+
+ pw.print(" "); pw.print(KEY_MODERATE_USE_FACTOR); pw.print("=");
+ pw.print(MODERATE_USE_FACTOR); pw.println();
+
+ pw.print(" "); pw.print(KEY_FG_JOB_COUNT); pw.print("=");
+ pw.print(FG_JOB_COUNT); pw.println();
+
+ pw.print(" "); pw.print(KEY_BG_NORMAL_JOB_COUNT); pw.print("=");
+ pw.print(BG_NORMAL_JOB_COUNT); pw.println();
+
+ pw.print(" "); pw.print(KEY_BG_MODERATE_JOB_COUNT); pw.print("=");
+ pw.print(BG_MODERATE_JOB_COUNT); pw.println();
+
+ pw.print(" "); pw.print(KEY_BG_LOW_JOB_COUNT); pw.print("=");
+ pw.print(BG_LOW_JOB_COUNT); pw.println();
+
+ pw.print(" "); pw.print(KEY_BG_CRITICAL_JOB_COUNT); pw.print("=");
+ pw.print(BG_CRITICAL_JOB_COUNT); pw.println();
+ }
+ }
+
+ final Constants mConstants;
+
+ /**
* Cleans up outstanding jobs when a package is removed. Even if it's being replaced later we
* still clean up. On reinstall the package will have a new uid.
*/
@@ -484,11 +662,13 @@
public void onDeviceIdleStateChanged(boolean deviceIdle) {
synchronized (mLock) {
if (deviceIdle) {
- // When becoming idle, make sure no jobs are actively running.
+ // When becoming idle, make sure no jobs are actively running,
+ // except those using the idle exemption flag.
for (int i=0; i<mActiveServices.size(); i++) {
JobServiceContext jsc = mActiveServices.get(i);
final JobStatus executing = jsc.getRunningJob();
- if (executing != null) {
+ if (executing != null
+ && (executing.getFlags() & JobInfo.FLAG_WILL_BE_FOREGROUND) == 0) {
jsc.cancelExecutingJob(JobParameters.REASON_DEVICE_IDLE);
}
}
@@ -539,6 +719,11 @@
*/
public JobSchedulerService(Context context) {
super(context);
+ mHandler = new JobHandler(context.getMainLooper());
+ mConstants = new Constants(mHandler);
+ mJobSchedulerStub = new JobSchedulerStub();
+ mJobs = JobStore.initAndGet(this);
+
// Create the controllers.
mControllers = new ArrayList<StateController>();
mControllers.add(ConnectivityController.get(this));
@@ -548,10 +733,6 @@
mControllers.add(AppIdleController.get(this));
mControllers.add(ContentObserverController.get(this));
mControllers.add(DeviceIdleJobsController.get(this));
-
- mHandler = new JobHandler(context.getMainLooper());
- mJobSchedulerStub = new JobSchedulerStub();
- mJobs = JobStore.initAndGet(this);
}
@Override
@@ -563,6 +744,7 @@
@Override
public void onBootPhase(int phase) {
if (PHASE_SYSTEM_SERVICES_READY == phase) {
+ mConstants.start(getContext().getContentResolver());
// Register br for package removals and user removals.
final IntentFilter filter = new IntentFilter();
filter.addAction(Intent.ACTION_PACKAGE_REMOVED);
@@ -994,11 +1176,12 @@
public void postProcess() {
if (backoffCount > 0 ||
- idleCount >= MIN_IDLE_COUNT ||
- connectivityCount >= MIN_CONNECTIVITY_COUNT ||
- chargingCount >= MIN_CHARGING_COUNT ||
- contentCount >= MIN_CONTENT_COUNT ||
- (runnableJobs != null && runnableJobs.size() >= MIN_READY_JOBS_COUNT)) {
+ idleCount >= mConstants.MIN_IDLE_COUNT ||
+ connectivityCount >= mConstants.MIN_CONNECTIVITY_COUNT ||
+ chargingCount >= mConstants.MIN_CHARGING_COUNT ||
+ contentCount >= mConstants.MIN_CONTENT_COUNT ||
+ (runnableJobs != null
+ && runnableJobs.size() >= mConstants.MIN_READY_JOBS_COUNT)) {
if (DEBUG) {
Slog.d(TAG, "maybeQueueReadyJobsForExecutionLockedH: Running jobs.");
}
@@ -1095,9 +1278,9 @@
private int adjustJobPriority(int curPriority, JobStatus job) {
if (curPriority < JobInfo.PRIORITY_TOP_APP) {
float factor = mJobPackageTracker.getLoadFactor(job);
- if (factor >= HEAVY_USE_FACTOR) {
+ if (factor >= mConstants.HEAVY_USE_FACTOR) {
curPriority += JobInfo.PRIORITY_ADJ_ALWAYS_RUNNING;
- } else if (factor >= MODERATE_USE_FACTOR) {
+ } else if (factor >= mConstants.MODERATE_USE_FACTOR) {
curPriority += JobInfo.PRIORITY_ADJ_OFTEN_RUNNING;
}
}
@@ -1135,16 +1318,16 @@
}
switch (memLevel) {
case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
- mMaxActiveJobs = ((MAX_JOB_CONTEXTS_COUNT - FG_JOB_CONTEXTS_COUNT) * 2) / 3;
+ mMaxActiveJobs = mConstants.BG_MODERATE_JOB_COUNT;
break;
case ProcessStats.ADJ_MEM_FACTOR_LOW:
- mMaxActiveJobs = (MAX_JOB_CONTEXTS_COUNT - FG_JOB_CONTEXTS_COUNT) / 3;
+ mMaxActiveJobs = mConstants.BG_LOW_JOB_COUNT;
break;
case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
- mMaxActiveJobs = 1;
+ mMaxActiveJobs = mConstants.BG_CRITICAL_JOB_COUNT;
break;
default:
- mMaxActiveJobs = MAX_JOB_CONTEXTS_COUNT - FG_JOB_CONTEXTS_COUNT;
+ mMaxActiveJobs = mConstants.BG_NORMAL_JOB_COUNT;
break;
}
@@ -1152,10 +1335,15 @@
boolean[] act = mTmpAssignAct;
int[] preferredUidForContext = mTmpAssignPreferredUidForContext;
int numActive = 0;
+ int numForeground = 0;
for (int i=0; i<MAX_JOB_CONTEXTS_COUNT; i++) {
final JobServiceContext js = mActiveServices.get(i);
- if ((contextIdToJobMap[i] = js.getRunningJob()) != null) {
+ final JobStatus status = js.getRunningJob();
+ if ((contextIdToJobMap[i] = status) != null) {
numActive++;
+ if (status.lastEvaluatedPriority >= JobInfo.PRIORITY_TOP_APP) {
+ numForeground++;
+ }
}
act[i] = false;
preferredUidForContext[i] = js.getPreferredUid();
@@ -1184,13 +1372,14 @@
JobStatus job = contextIdToJobMap[j];
int preferredUid = preferredUidForContext[j];
if (job == null) {
- if ((numActive < mMaxActiveJobs || priority >= JobInfo.PRIORITY_TOP_APP) &&
+ if ((numActive < mMaxActiveJobs ||
+ (priority >= JobInfo.PRIORITY_TOP_APP &&
+ numForeground < mConstants.FG_JOB_COUNT)) &&
(preferredUid == nextPending.getUid() ||
preferredUid == JobServiceContext.NO_PREFERRED_UID)) {
// This slot is free, and we haven't yet hit the limit on
// concurrent jobs... we can just throw the job in to here.
minPriorityContextId = j;
- numActive++;
break;
}
// No job on this context, but nextPending can't run here because
@@ -1212,11 +1401,16 @@
if (minPriorityContextId != -1) {
contextIdToJobMap[minPriorityContextId] = nextPending;
act[minPriorityContextId] = true;
+ numActive++;
+ if (priority >= JobInfo.PRIORITY_TOP_APP) {
+ numForeground++;
+ }
}
}
if (DEBUG) {
Slog.d(TAG, printContextIdToJobMap(contextIdToJobMap, "running jobs final"));
}
+ mJobPackageTracker.noteConcurrency(numActive, numForeground);
for (int i=0; i<MAX_JOB_CONTEXTS_COUNT; i++) {
boolean preservePreferredUid = false;
if (act[i]) {
@@ -1569,36 +1763,49 @@
final int filterUidFinal = UserHandle.getAppId(filterUid);
final long now = SystemClock.elapsedRealtime();
synchronized (mLock) {
+ mConstants.dump(pw);
+ pw.println();
pw.println("Started users: " + Arrays.toString(mStartedUsers));
- pw.println("Registered jobs:");
+ pw.print("Registered ");
+ pw.print(mJobs.size());
+ pw.println(" jobs:");
if (mJobs.size() > 0) {
- mJobs.forEachJob(new JobStatusFunctor() {
- private int index = 0;
-
+ final List<JobStatus> jobs = mJobs.mJobSet.getAllJobs();
+ Collections.sort(jobs, new Comparator<JobStatus>() {
@Override
- public void process(JobStatus job) {
- pw.print(" Job #"); pw.print(index++); pw.print(": ");
- pw.println(job.toShortString());
-
- // Skip printing details if the caller requested a filter
- if (!job.shouldDump(filterUidFinal)) {
- return;
+ public int compare(JobStatus o1, JobStatus o2) {
+ int uid1 = o1.getUid();
+ int uid2 = o2.getUid();
+ int id1 = o1.getJobId();
+ int id2 = o2.getJobId();
+ if (uid1 != uid2) {
+ return uid1 < uid2 ? -1 : 1;
}
-
- job.dump(pw, " ", true);
- pw.print(" Ready: ");
- pw.print(mHandler.isReadyToBeExecutedLocked(job));
- pw.print(" (job=");
- pw.print(job.isReady());
- pw.print(" pending=");
- pw.print(mPendingJobs.contains(job));
- pw.print(" active=");
- pw.print(isCurrentlyActiveLocked(job));
- pw.print(" user=");
- pw.print(ArrayUtils.contains(mStartedUsers, job.getUserId()));
- pw.println(")");
+ return id1 < id2 ? -1 : (id1 > id2 ? 1 : 0);
}
});
+ for (JobStatus job : jobs) {
+ pw.print(" JOB #"); job.printUniqueId(pw); pw.print(": ");
+ pw.println(job.toShortStringExceptUniqueId());
+
+ // Skip printing details if the caller requested a filter
+ if (!job.shouldDump(filterUidFinal)) {
+ continue;
+ }
+
+ job.dump(pw, " ", true);
+ pw.print(" Ready: ");
+ pw.print(mHandler.isReadyToBeExecutedLocked(job));
+ pw.print(" (job=");
+ pw.print(job.isReady());
+ pw.print(" pending=");
+ pw.print(mPendingJobs.contains(job));
+ pw.print(" active=");
+ pw.print(isCurrentlyActiveLocked(job));
+ pw.print(" user=");
+ pw.print(ArrayUtils.contains(mStartedUsers, job.getUserId()));
+ pw.println(")");
+ }
} else {
pw.println(" None.");
}
diff --git a/services/core/java/com/android/server/job/JobStore.java b/services/core/java/com/android/server/job/JobStore.java
index 1f7d312..602b9c7 100644
--- a/services/core/java/com/android/server/job/JobStore.java
+++ b/services/core/java/com/android/server/job/JobStore.java
@@ -844,8 +844,16 @@
// Inefficient; use only for testing
public List<JobStatus> getAllJobs() {
ArrayList<JobStatus> allJobs = new ArrayList<JobStatus>(size());
- for (int i = mJobs.size(); i >= 0; i--) {
- allJobs.addAll(mJobs.valueAt(i));
+ for (int i = mJobs.size() - 1; i >= 0; i--) {
+ ArraySet<JobStatus> jobs = mJobs.valueAt(i);
+ if (jobs != null) {
+ // Use a for loop over the ArraySet, so we don't need to make its
+ // optional collection class iterator implementation or have to go
+ // through a temporary array from toArray().
+ for (int j = jobs.size() - 1; j >= 0; j--) {
+ allJobs.add(jobs.valueAt(j));
+ }
+ }
}
return allJobs;
}
diff --git a/services/core/java/com/android/server/job/controllers/AppIdleController.java b/services/core/java/com/android/server/job/controllers/AppIdleController.java
index 7593035..a23af35 100644
--- a/services/core/java/com/android/server/job/controllers/AppIdleController.java
+++ b/services/core/java/com/android/server/job/controllers/AppIdleController.java
@@ -18,6 +18,7 @@
import android.app.usage.UsageStatsManagerInternal;
import android.content.Context;
+import android.os.UserHandle;
import android.util.Slog;
import com.android.server.LocalServices;
@@ -42,6 +43,7 @@
private static volatile AppIdleController sController;
private final JobSchedulerService mJobSchedulerService;
private final UsageStatsManagerInternal mUsageStatsInternal;
+ private boolean mInitializedParoleOn;
boolean mAppIdleParoleOn;
final class GlobalUpdateFunc implements JobStore.JobStatusFunctor {
@@ -100,12 +102,16 @@
super(service, context, lock);
mJobSchedulerService = service;
mUsageStatsInternal = LocalServices.getService(UsageStatsManagerInternal.class);
- mAppIdleParoleOn = mUsageStatsInternal.isAppIdleParoleOn();
+ mAppIdleParoleOn = true;
mUsageStatsInternal.addAppIdleStateChangeListener(new AppIdleStateChangeListener());
}
@Override
public void maybeStartTrackingJobLocked(JobStatus jobStatus, JobStatus lastJob) {
+ if (!mInitializedParoleOn) {
+ mInitializedParoleOn = true;
+ mAppIdleParoleOn = mUsageStatsInternal.isAppIdleParoleOn();
+ }
String packageName = jobStatus.getSourcePackageName();
final boolean appIdle = !mAppIdleParoleOn && mUsageStatsInternal.isAppIdle(packageName,
jobStatus.getSourceUid(), jobStatus.getSourceUserId());
@@ -122,21 +128,24 @@
@Override
public void dumpControllerStateLocked(final PrintWriter pw, final int filterUid) {
- pw.println("AppIdle");
- pw.println("Parole On: " + mAppIdleParoleOn);
+ pw.print("AppIdle: parole on = ");
+ pw.println(mAppIdleParoleOn);
mJobSchedulerService.getJobStore().forEachJob(new JobStore.JobStatusFunctor() {
@Override public void process(JobStatus jobStatus) {
// Skip printing details if the caller requested a filter
if (!jobStatus.shouldDump(filterUid)) {
return;
}
- pw.print(" ");
+ pw.print(" #");
+ jobStatus.printUniqueId(pw);
+ pw.print(" from ");
+ UserHandle.formatUid(pw, jobStatus.getSourceUid());
+ pw.print(": ");
pw.print(jobStatus.getSourcePackageName());
- pw.print(": runnable=");
+ pw.print(", runnable=");
pw.println((jobStatus.satisfiedConstraints&JobStatus.CONSTRAINT_APP_NOT_IDLE) != 0);
}
});
- pw.println();
}
void setAppIdleParoleOn(boolean isAppIdleParoleOn) {
diff --git a/services/core/java/com/android/server/job/controllers/BatteryController.java b/services/core/java/com/android/server/job/controllers/BatteryController.java
index a0cb25f..f6b8ef4 100644
--- a/services/core/java/com/android/server/job/controllers/BatteryController.java
+++ b/services/core/java/com/android/server/job/controllers/BatteryController.java
@@ -23,6 +23,7 @@
import android.os.BatteryManager;
import android.os.BatteryManagerInternal;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
@@ -195,21 +196,21 @@
@Override
public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
- pw.println("Batt.");
- pw.println("Stable power: " + mChargeTracker.isOnStablePower());
- Iterator<JobStatus> it = mTrackedTasks.iterator();
- if (it.hasNext()) {
- JobStatus jobStatus = it.next();
- if (jobStatus.shouldDump(filterUid)) {
- pw.print(String.valueOf(jobStatus.hashCode()));
+ pw.print("Battery: stable power = ");
+ pw.println(mChargeTracker.isOnStablePower());
+ pw.print("Tracking ");
+ pw.print(mTrackedTasks.size());
+ pw.println(":");
+ for (int i = 0; i < mTrackedTasks.size(); i++) {
+ final JobStatus js = mTrackedTasks.get(i);
+ if (!js.shouldDump(filterUid)) {
+ continue;
}
+ pw.print(" #");
+ js.printUniqueId(pw);
+ pw.print(" from ");
+ UserHandle.formatUid(pw, js.getSourceUid());
+ pw.println();
}
- while (it.hasNext()) {
- JobStatus jobStatus = it.next();
- if (jobStatus.shouldDump(filterUid)) {
- pw.print("," + String.valueOf(jobStatus.hashCode()));
- }
- }
- pw.println();
}
}
diff --git a/services/core/java/com/android/server/job/controllers/ConnectivityController.java b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
index 7d28633..2ff880c 100644
--- a/services/core/java/com/android/server/job/controllers/ConnectivityController.java
+++ b/services/core/java/com/android/server/job/controllers/ConnectivityController.java
@@ -187,14 +187,20 @@
@Override
public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
- pw.println("Conn.");
+ pw.println("Connectivity.");
+ pw.print("Tracking ");
+ pw.print(mTrackedJobs.size());
+ pw.println(":");
for (int i = 0; i < mTrackedJobs.size(); i++) {
final JobStatus js = mTrackedJobs.get(i);
if (js.shouldDump(filterUid)) {
- pw.println(String.valueOf(js.getJobId() + "," + js.getUid())
- + ": C=" + js.hasConnectivityConstraint()
- + ", UM=" + js.hasUnmeteredConstraint()
- + ", NR=" + js.hasNotRoamingConstraint());
+ pw.print(" #");
+ js.printUniqueId(pw);
+ pw.print(" from ");
+ UserHandle.formatUid(pw, js.getSourceUid());
+ pw.print(": C="); pw.print(js.hasConnectivityConstraint());
+ pw.print(": UM="); pw.print(js.hasUnmeteredConstraint());
+ pw.print(": NR="); pw.println(js.hasNotRoamingConstraint());
}
}
}
diff --git a/services/core/java/com/android/server/job/controllers/ContentObserverController.java b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
index c1d7c58..26660e8 100644
--- a/services/core/java/com/android/server/job/controllers/ContentObserverController.java
+++ b/services/core/java/com/android/server/job/controllers/ContentObserverController.java
@@ -21,6 +21,7 @@
import android.database.ContentObserver;
import android.net.Uri;
import android.os.Handler;
+import android.os.UserHandle;
import android.util.TimeUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -323,23 +324,17 @@
@Override
public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
- pw.println("Content.");
- boolean printed = false;
+ pw.println("Content:");
Iterator<JobStatus> it = mTrackedTasks.iterator();
while (it.hasNext()) {
JobStatus js = it.next();
if (!js.shouldDump(filterUid)) {
continue;
}
- if (!printed) {
- pw.print(" ");
- printed = true;
- } else {
- pw.print(",");
- }
- pw.print(System.identityHashCode(js));
- }
- if (printed) {
+ pw.print(" #");
+ js.printUniqueId(pw);
+ pw.print(" from ");
+ UserHandle.formatUid(pw, js.getSourceUid());
pw.println();
}
int N = mObservers.size();
@@ -367,8 +362,10 @@
pw.println(" Jobs:");
for (int j=0; j<M; j++) {
JobInstance inst = obs.mJobs.valueAt(j);
- pw.print(" ");
- pw.print(System.identityHashCode(inst.mJobStatus));
+ pw.print(" #");
+ inst.mJobStatus.printUniqueId(pw);
+ pw.print(" from ");
+ UserHandle.formatUid(pw, inst.mJobStatus.getSourceUid());
if (inst.mChangedAuthorities != null) {
pw.println(":");
if (inst.mTriggerPending) {
diff --git a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
index 345a032..bf1297f 100644
--- a/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
+++ b/services/core/java/com/android/server/job/controllers/DeviceIdleJobsController.java
@@ -180,13 +180,16 @@
if (!jobStatus.shouldDump(filterUid)) {
return;
}
- pw.print(" ");
+ pw.print(" #");
+ jobStatus.printUniqueId(pw);
+ pw.print(" from ");
+ UserHandle.formatUid(pw, jobStatus.getSourceUid());
+ pw.print(": ");
pw.print(jobStatus.getSourcePackageName());
- pw.print(": runnable=");
+ pw.print(", runnable=");
pw.println((jobStatus.satisfiedConstraints
& JobStatus.CONSTRAINT_DEVICE_NOT_DOZING) != 0);
}
});
- pw.println();
}
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/job/controllers/IdleController.java b/services/core/java/com/android/server/job/controllers/IdleController.java
index 5899d16..f41e187 100644
--- a/services/core/java/com/android/server/job/controllers/IdleController.java
+++ b/services/core/java/com/android/server/job/controllers/IdleController.java
@@ -26,6 +26,7 @@
import android.content.Intent;
import android.content.IntentFilter;
import android.os.SystemClock;
+import android.os.UserHandle;
import android.util.Slog;
import com.android.server.am.ActivityManagerService;
@@ -191,15 +192,19 @@
public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
pw.print("Idle: ");
pw.println(mIdleTracker.isIdle() ? "true" : "false");
- pw.println(mTrackedTasks.size());
+ pw.print("Tracking ");
+ pw.print(mTrackedTasks.size());
+ pw.println(":");
for (int i = 0; i < mTrackedTasks.size(); i++) {
final JobStatus js = mTrackedTasks.get(i);
if (!js.shouldDump(filterUid)) {
continue;
}
- pw.print(" ");
- pw.print(String.valueOf(js.getJobId() + "," + js.getUid()));
- pw.println("..");
+ pw.print(" #");
+ js.printUniqueId(pw);
+ pw.print(" from ");
+ UserHandle.formatUid(pw, js.getSourceUid());
+ pw.println();
}
}
}
diff --git a/services/core/java/com/android/server/job/controllers/JobStatus.java b/services/core/java/com/android/server/job/controllers/JobStatus.java
index 072787b..ded7a2f 100644
--- a/services/core/java/com/android/server/job/controllers/JobStatus.java
+++ b/services/core/java/com/android/server/job/controllers/JobStatus.java
@@ -249,6 +249,12 @@
return job.getId();
}
+ public void printUniqueId(PrintWriter pw) {
+ UserHandle.formatUid(pw, callingUid);
+ pw.print("/");
+ pw.print(job.getId());
+ }
+
public int getNumFailures() {
return numFailures;
}
@@ -410,6 +416,10 @@
return true;
}
+ boolean isConstraintSatisfied(int constraint) {
+ return (satisfiedConstraints&constraint) != 0;
+ }
+
public boolean shouldDump(int filterUid) {
return filterUid == -1 || UserHandle.getAppId(getUid()) == filterUid
|| UserHandle.getAppId(getSourceUid()) == filterUid;
@@ -505,10 +515,22 @@
public String toShortString() {
StringBuilder sb = new StringBuilder();
sb.append(Integer.toHexString(System.identityHashCode(this)));
- sb.append(" jId=");
+ sb.append(" #");
+ UserHandle.formatUid(sb, callingUid);
+ sb.append("/");
sb.append(job.getId());
sb.append(' ');
- UserHandle.formatUid(sb, callingUid);
+ sb.append(batteryName);
+ return sb.toString();
+ }
+
+ /**
+ * Convenience function to identify a job uniquely without pulling all the data that
+ * {@link #toString()} returns.
+ */
+ public String toShortStringExceptUniqueId() {
+ StringBuilder sb = new StringBuilder();
+ sb.append(Integer.toHexString(System.identityHashCode(this)));
sb.append(' ');
sb.append(batteryName);
return sb.toString();
diff --git a/services/core/java/com/android/server/job/controllers/TimeController.java b/services/core/java/com/android/server/job/controllers/TimeController.java
index 2f8ca7e..0b3b00f 100644
--- a/services/core/java/com/android/server/job/controllers/TimeController.java
+++ b/services/core/java/com/android/server/job/controllers/TimeController.java
@@ -20,7 +20,10 @@
import android.app.AlarmManager.OnAlarmListener;
import android.content.Context;
import android.os.SystemClock;
+import android.os.UserHandle;
+import android.os.WorkSource;
import android.util.Slog;
+import android.util.TimeUtils;
import com.android.server.job.JobSchedulerService;
import com.android.server.job.StateChangedListener;
@@ -39,9 +42,9 @@
private static final String TAG = "JobScheduler.Time";
/** Deadline alarm tag for logging purposes */
- private final String DEADLINE_TAG = "JobScheduler.deadline";
+ private final String DEADLINE_TAG = "*job.deadline*";
/** Delay alarm tag for logging purposes */
- private final String DELAY_TAG = "JobScheduler.delay";
+ private final String DELAY_TAG = "*job.delay*";
private long mNextJobExpiredElapsedMillis;
private long mNextDelayExpiredElapsedMillis;
@@ -91,7 +94,8 @@
it.add(job);
maybeUpdateAlarmsLocked(
job.hasTimingDelayConstraint() ? job.getEarliestRunTime() : Long.MAX_VALUE,
- job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE);
+ job.hasDeadlineConstraint() ? job.getLatestRunTimeElapsed() : Long.MAX_VALUE,
+ job.getSourceUid());
}
}
@@ -134,6 +138,7 @@
private void checkExpiredDeadlinesAndResetAlarm() {
synchronized (mLock) {
long nextExpiryTime = Long.MAX_VALUE;
+ int nextExpiryUid = 0;
final long nowElapsedMillis = SystemClock.elapsedRealtime();
Iterator<JobStatus> it = mTrackedJobs.iterator();
@@ -153,10 +158,11 @@
it.remove();
} else { // Sorted by expiry time, so take the next one and stop.
nextExpiryTime = jobDeadline;
+ nextExpiryUid = job.getSourceUid();
break;
}
}
- setDeadlineExpiredAlarmLocked(nextExpiryTime);
+ setDeadlineExpiredAlarmLocked(nextExpiryTime, nextExpiryUid);
}
}
@@ -168,6 +174,7 @@
synchronized (mLock) {
final long nowElapsedMillis = SystemClock.elapsedRealtime();
long nextDelayTime = Long.MAX_VALUE;
+ int nextDelayUid = 0;
boolean ready = false;
Iterator<JobStatus> it = mTrackedJobs.iterator();
while (it.hasNext()) {
@@ -184,25 +191,29 @@
if (job.isReady()) {
ready = true;
}
- } else { // Keep going through list to get next delay time.
+ } else if (!job.isConstraintSatisfied(JobStatus.CONSTRAINT_TIMING_DELAY)) {
+ // If this job still doesn't have its delay constraint satisfied,
+ // then see if it is the next upcoming delay time for the alarm.
if (nextDelayTime > jobDelayTime) {
nextDelayTime = jobDelayTime;
+ nextDelayUid = job.getSourceUid();
}
}
}
if (ready) {
mStateChangedListener.onControllerStateChanged();
}
- setDelayExpiredAlarmLocked(nextDelayTime);
+ setDelayExpiredAlarmLocked(nextDelayTime, nextDelayUid);
}
}
- private void maybeUpdateAlarmsLocked(long delayExpiredElapsed, long deadlineExpiredElapsed) {
+ private void maybeUpdateAlarmsLocked(long delayExpiredElapsed, long deadlineExpiredElapsed,
+ int uid) {
if (delayExpiredElapsed < mNextDelayExpiredElapsedMillis) {
- setDelayExpiredAlarmLocked(delayExpiredElapsed);
+ setDelayExpiredAlarmLocked(delayExpiredElapsed, uid);
}
if (deadlineExpiredElapsed < mNextJobExpiredElapsedMillis) {
- setDeadlineExpiredAlarmLocked(deadlineExpiredElapsed);
+ setDeadlineExpiredAlarmLocked(deadlineExpiredElapsed, uid);
}
}
@@ -211,11 +222,11 @@
* delay will expire.
* This alarm <b>will</b> wake up the phone.
*/
- private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis) {
+ private void setDelayExpiredAlarmLocked(long alarmTimeElapsedMillis, int uid) {
alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
mNextDelayExpiredElapsedMillis = alarmTimeElapsedMillis;
updateAlarmWithListenerLocked(DELAY_TAG, mNextDelayExpiredListener,
- mNextDelayExpiredElapsedMillis);
+ mNextDelayExpiredElapsedMillis, uid);
}
/**
@@ -223,11 +234,11 @@
* deadline will expire.
* This alarm <b>will</b> wake up the phone.
*/
- private void setDeadlineExpiredAlarmLocked(long alarmTimeElapsedMillis) {
+ private void setDeadlineExpiredAlarmLocked(long alarmTimeElapsedMillis, int uid) {
alarmTimeElapsedMillis = maybeAdjustAlarmTime(alarmTimeElapsedMillis);
mNextJobExpiredElapsedMillis = alarmTimeElapsedMillis;
updateAlarmWithListenerLocked(DEADLINE_TAG, mDeadlineExpiredListener,
- mNextJobExpiredElapsedMillis);
+ mNextJobExpiredElapsedMillis, uid);
}
private long maybeAdjustAlarmTime(long proposedAlarmTimeElapsedMillis) {
@@ -239,7 +250,7 @@
}
private void updateAlarmWithListenerLocked(String tag, OnAlarmListener listener,
- long alarmTimeElapsed) {
+ long alarmTimeElapsed, int uid) {
ensureAlarmServiceLocked();
if (alarmTimeElapsed == Long.MAX_VALUE) {
mAlarmService.cancel(listener);
@@ -248,7 +259,7 @@
Slog.d(TAG, "Setting " + tag + " for: " + alarmTimeElapsed);
}
mAlarmService.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, alarmTimeElapsed,
- tag, listener, null);
+ AlarmManager.WINDOW_HEURISTIC, 0, tag, listener, null, new WorkSource(uid));
}
}
@@ -277,20 +288,39 @@
@Override
public void dumpControllerStateLocked(PrintWriter pw, int filterUid) {
final long nowElapsed = SystemClock.elapsedRealtime();
- pw.println("Alarms (" + SystemClock.elapsedRealtime() + ")");
- pw.println(
- "Next delay alarm in " + (mNextDelayExpiredElapsedMillis - nowElapsed)/1000 + "s");
- pw.println("Next deadline alarm in " + (mNextJobExpiredElapsedMillis - nowElapsed)/1000
- + "s");
- pw.println("Tracking:");
+ pw.print("Alarms: now=");
+ pw.print(SystemClock.elapsedRealtime());
+ pw.println();
+ pw.print("Next delay alarm in ");
+ TimeUtils.formatDuration(mNextDelayExpiredElapsedMillis, nowElapsed, pw);
+ pw.println();
+ pw.print("Next deadline alarm in ");
+ TimeUtils.formatDuration(mNextJobExpiredElapsedMillis, nowElapsed, pw);
+ pw.println();
+ pw.print("Tracking ");
+ pw.print(mTrackedJobs.size());
+ pw.println(":");
for (JobStatus ts : mTrackedJobs) {
if (!ts.shouldDump(filterUid)) {
continue;
}
- pw.println(String.valueOf(ts.getJobId() + "," + ts.getUid())
- + ": (" + (ts.hasTimingDelayConstraint() ? ts.getEarliestRunTime() : "N/A")
- + ", " + (ts.hasDeadlineConstraint() ?ts.getLatestRunTimeElapsed() : "N/A")
- + ")");
+ pw.print(" #");
+ ts.printUniqueId(pw);
+ pw.print(" from ");
+ UserHandle.formatUid(pw, ts.getSourceUid());
+ pw.print(": Delay=");
+ if (ts.hasTimingDelayConstraint()) {
+ TimeUtils.formatDuration(ts.getEarliestRunTime(), nowElapsed, pw);
+ } else {
+ pw.print("N/A");
+ }
+ pw.print(", Deadline=");
+ if (ts.hasDeadlineConstraint()) {
+ TimeUtils.formatDuration(ts.getLatestRunTimeElapsed(), nowElapsed, pw);
+ } else {
+ pw.print("N/A");
+ }
+ pw.println();
}
}
}
\ No newline at end of file
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index a8b1a4a..0af0c73 100644
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -181,7 +181,7 @@
= SystemProperties.getBoolean("debug.child_notifs", true);
static final int MAX_PACKAGE_NOTIFICATIONS = 50;
- static final float MAX_PACKAGE_ENQUEUE_RATE = 50f;
+ static final float DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE = 50f;
// message codes
static final int MESSAGE_TIMEOUT = 2;
@@ -305,6 +305,7 @@
private static final int MY_PID = Process.myPid();
private RankingHandler mRankingHandler;
private long mLastOverRateLogTime;
+ private float mMaxPackageEnqueueRate = DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE;
private static class Archive {
final int mBufferSize;
@@ -817,6 +818,8 @@
private final class SettingsObserver extends ContentObserver {
private final Uri NOTIFICATION_LIGHT_PULSE_URI
= Settings.System.getUriFor(Settings.System.NOTIFICATION_LIGHT_PULSE);
+ private final Uri NOTIFICATION_RATE_LIMIT_URI
+ = Settings.Global.getUriFor(Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE);
SettingsObserver(Handler handler) {
super(handler);
@@ -826,6 +829,8 @@
ContentResolver resolver = getContext().getContentResolver();
resolver.registerContentObserver(NOTIFICATION_LIGHT_PULSE_URI,
false, this, UserHandle.USER_ALL);
+ resolver.registerContentObserver(NOTIFICATION_RATE_LIMIT_URI,
+ false, this, UserHandle.USER_ALL);
update(null);
}
@@ -843,6 +848,10 @@
updateNotificationPulse();
}
}
+ if (uri == null || NOTIFICATION_RATE_LIMIT_URI.equals(uri)) {
+ mMaxPackageEnqueueRate = Settings.Global.getFloat(resolver,
+ Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE, mMaxPackageEnqueueRate);
+ }
}
}
@@ -899,6 +908,10 @@
public void onStart() {
Resources resources = getContext().getResources();
+ mMaxPackageEnqueueRate = Settings.Global.getFloat(getContext().getContentResolver(),
+ Settings.Global.MAX_NOTIFICATION_ENQUEUE_RATE,
+ DEFAULT_MAX_NOTIFICATION_ENQUEUE_RATE);
+
mAm = ActivityManagerNative.getDefault();
mAppOps = (AppOpsManager) getContext().getSystemService(Context.APP_OPS_SERVICE);
mVibrator = (Vibrator) getContext().getSystemService(Context.VIBRATOR_SERVICE);
@@ -2369,6 +2382,7 @@
pw.println(" mDisableNotificationEffects=" + mDisableNotificationEffects);
pw.println(" mCallState=" + callStateToString(mCallState));
pw.println(" mSystemReady=" + mSystemReady);
+ pw.println(" mMaxPackageEnqueueRate=" + mMaxPackageEnqueueRate);
}
pw.println(" mArchive=" + mArchive.toString());
Iterator<StatusBarNotification> iter = mArchive.descendingIterator();
@@ -2512,7 +2526,7 @@
if (!isSystemNotification && !isNotificationFromListener) {
synchronized (mNotificationList) {
final float appEnqueueRate = mUsageStats.getAppEnqueueRate(pkg);
- if (appEnqueueRate > MAX_PACKAGE_ENQUEUE_RATE) {
+ if (appEnqueueRate > mMaxPackageEnqueueRate) {
mUsageStats.registerOverRateQuota(pkg);
final long now = SystemClock.elapsedRealtime();
if ((now - mLastOverRateLogTime) > MIN_PACKAGE_OVERRATE_LOG_INTERVAL) {
diff --git a/services/core/java/com/android/server/pm/Installer.java b/services/core/java/com/android/server/pm/Installer.java
index 913c824..7b85a4f 100644
--- a/services/core/java/com/android/server/pm/Installer.java
+++ b/services/core/java/com/android/server/pm/Installer.java
@@ -153,6 +153,11 @@
return mInstaller.mergeProfiles(uid, pkgName);
}
+ public boolean dumpProfiles(String gid, String packageName, String codePaths)
+ throws InstallerException {
+ return mInstaller.dumpProfiles(gid, packageName, codePaths);
+ }
+
public void idmap(String targetApkPath, String overlayApkPath, int uid)
throws InstallerException {
mInstaller.execute("idmap", targetApkPath, overlayApkPath, uid);
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index eb4d755..3999d188 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -105,6 +105,7 @@
import android.app.ActivityManager;
import android.app.ActivityManagerNative;
import android.app.IActivityManager;
+import android.app.ResourcesManager;
import android.app.admin.DevicePolicyManagerInternal;
import android.app.admin.IDevicePolicyManager;
import android.app.admin.SecurityLog;
@@ -238,6 +239,7 @@
import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
+import com.android.server.AttributeCache;
import com.android.server.EventLogTags;
import com.android.server.FgThread;
import com.android.server.IntentResolver;
@@ -2723,7 +2725,6 @@
StorageManager.FLAG_STORAGE_DE | StorageManager.FLAG_STORAGE_CE
| Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
- clearAppProfilesLIF(ps.pkg, UserHandle.USER_ALL);
}
ver.fingerprint = Build.FINGERPRINT;
}
@@ -7458,6 +7459,45 @@
}
@Override
+ public void dumpProfiles(String packageName) {
+ PackageParser.Package pkg;
+ synchronized (mPackages) {
+ pkg = mPackages.get(packageName);
+ if (pkg == null) {
+ throw new IllegalArgumentException("Unknown package: " + packageName);
+ }
+ }
+ /* Only the shell or the app user should be able to dump profiles. */
+ int callingUid = Binder.getCallingUid();
+ if (callingUid != Process.SHELL_UID && callingUid != pkg.applicationInfo.uid) {
+ throw new SecurityException("dumpProfiles");
+ }
+
+ synchronized (mInstallLock) {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "dump profiles");
+ final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+ try {
+ final File codeFile = new File(pkg.applicationInfo.getCodePath());
+ List<String> allCodePaths = Collections.EMPTY_LIST;
+ if (codeFile != null && codeFile.exists()) {
+ try {
+ final PackageLite codePkg = PackageParser.parsePackageLite(codeFile, 0);
+ allCodePaths = codePkg.getAllCodePaths();
+ } catch (PackageParserException e) {
+ // Well, we tried.
+ }
+ }
+ String gid = Integer.toString(sharedGid);
+ String codePaths = TextUtils.join(";", allCodePaths);
+ mInstaller.dumpProfiles(gid, packageName, codePaths);
+ } catch (InstallerException e) {
+ Slog.w(TAG, "Failed to dump profiles", e);
+ }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ @Override
public void forceDexOpt(String packageName) {
enforceSystemOrRoot("forceDexOpt");
@@ -19134,6 +19174,11 @@
Slog.w(TAG, "Failed to unload " + ps.codePath);
}
}
+
+ // Try very hard to release any references to this package
+ // so we don't risk the system server being killed due to
+ // open FDs
+ AttributeCache.instance().removePackage(ps.name);
}
mSettings.writeLPr();
@@ -19142,6 +19187,15 @@
if (DEBUG_INSTALL) Slog.d(TAG, "Unloaded packages " + unloaded);
sendResourcesChangedBroadcast(false, false, unloaded, null);
+
+ // Try very hard to release any references to this path so we don't risk
+ // the system server being killed due to open FDs
+ ResourcesManager.getInstance().invalidatePath(vol.getPath().getAbsolutePath());
+
+ for (int i = 0; i < 3; i++) {
+ System.gc();
+ System.runFinalization();
+ }
}
/**
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index beff8fc..05f5b8f 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -105,6 +105,8 @@
return runInstallWrite();
case "compile":
return runCompile();
+ case "dump-profiles":
+ return runDumpProfiles();
case "list":
return runList();
case "uninstall":
@@ -387,6 +389,12 @@
}
}
+ private int runDumpProfiles() throws RemoteException {
+ String packageName = getNextArg();
+ mInterface.dumpProfiles(packageName);
+ return 0;
+ }
+
private int runList() throws RemoteException {
final PrintWriter pw = getOutPrintWriter();
final String type = getNextArg();
diff --git a/services/core/java/com/android/server/pm/ShortcutPackage.java b/services/core/java/com/android/server/pm/ShortcutPackage.java
index bca3777..e0c28fa 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackage.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackage.java
@@ -26,11 +26,13 @@
import android.text.format.Formatter;
import android.util.ArrayMap;
import android.util.ArraySet;
+import android.util.Log;
import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.Preconditions;
import com.android.internal.util.XmlUtils;
+import com.android.server.pm.ShortcutService.ShortcutOperation;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
@@ -40,6 +42,8 @@
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.List;
import java.util.Set;
import java.util.function.Predicate;
@@ -126,7 +130,8 @@
}
/**
- * Called when a shortcut is about to be published. At this point we know the publisher package
+ * Called when a shortcut is about to be published. At this point we know the publisher
+ * package
* exists (as opposed to Launcher trying to fetch shortcuts from a non-existent package), so
* we do some initialization for the package.
*/
@@ -292,12 +297,17 @@
}
/**
- * Remove a dynamic shortcut by ID.
+ * Remove a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut
+ * is pinned, it'll remain as a pinned shortcut, and is still enabled.
*/
public void deleteDynamicWithId(@NonNull String shortcutId) {
deleteOrDisableWithId(shortcutId, /* disable =*/ false, /* overrideImmutable=*/ false);
}
+ /**
+ * Disable a dynamic shortcut by ID. It'll be removed from the dynamic set, but if the shortcut
+ * is pinned, it'll remain as a pinned shortcut but will be disabled.
+ */
public void disableWithId(@NonNull String shortcutId, String disabledMessage,
int disabledMessageResId, boolean overrideImmutable) {
final ShortcutInfo disabled = deleteOrDisableWithId(shortcutId, /* disable =*/ true,
@@ -625,6 +635,10 @@
// (Re-)publish manifest shortcut.
changed |= publishManifestShortcuts(newManifestShortcutList);
+ if (newManifestShortcutList != null) {
+ changed |= pushOutExcessShortcuts();
+ }
+
if (changed) {
// This will send a notification to the launcher, and also save .
s.packageShortcutsChanged(getPackageName(), getPackageUserId());
@@ -642,10 +656,6 @@
}
boolean changed = false;
- // TODO: Check dynamic count
-
- // TODO: Kick out dynamic if too many
-
// Keep the previous IDs.
ArraySet<String> toDisableList = null;
for (int i = mShortcuts.size() - 1; i >= 0; i--) {
@@ -669,7 +679,7 @@
final ShortcutInfo newShortcut = newManifestShortcutList.get(i);
final boolean newDisabled = !newShortcut.isEnabled();
- final String id = newShortcut.getId();
+ final String id = newShortcut.getId();
final ShortcutInfo oldShortcut = mShortcuts.get(id);
boolean wasPinned = false;
@@ -692,7 +702,6 @@
// Just keep it in toDisableList, so the previous one would be removed.
continue;
}
- // TODO: Check dynamic count
// Note even if enabled=false, we still need to update all fields, so do it
// regardless.
@@ -725,6 +734,179 @@
return changed;
}
+ /**
+ * For each target activity, make sure # of dynamic + manifest shortcuts <= max.
+ * If too many, we'll remove the dynamic with the lowest ranks.
+ */
+ private boolean pushOutExcessShortcuts() {
+ final ShortcutService service = mShortcutUser.mService;
+ final int maxShortcuts = service.getMaxActivityShortcuts();
+
+ boolean changed = false;
+
+ final ArrayMap<ComponentName, ArrayList<ShortcutInfo>> all =
+ sortShortcutsToActivities();
+ for (int outer = all.size() - 1; outer >= 0; outer--) {
+ final ArrayList<ShortcutInfo> list = all.valueAt(outer);
+ if (list.size() <= maxShortcuts) {
+ continue;
+ }
+ // Sort by isManifestShortcut() and getRank().
+ Collections.sort(list, mShortcutTypeAndRankComparator);
+
+ // Keep [0 .. max), and remove (as dynamic) [max .. size)
+ for (int inner = list.size() - 1; inner >= maxShortcuts; inner--) {
+ final ShortcutInfo shortcut = list.get(inner);
+
+ if (shortcut.isManifestShortcut()) {
+ // This shouldn't happen -- excess shortcuts should all be non-manifest.
+ // But just in case.
+ service.wtf("Found manifest shortcuts in excess list.");
+ continue;
+ }
+ deleteDynamicWithId(shortcut.getId());
+ }
+ }
+ service.verifyStates();
+
+ return changed;
+ }
+
+ /**
+ * To sort by isManifestShortcut() and getRank(). i.e. manifest shortcuts come before
+ * non-manifest shortcuts, then sort by rank.
+ *
+ * This is used to decide which dynamic shortcuts to remove when an upgraded version has more
+ * manifest shortcuts than before and as a result we need to remove some of the dynamic
+ * shortcuts. We sort manifest + dynamic shortcuts by this order, and remove the ones with
+ * the last ones.
+ *
+ * (Note the number of manifest shortcuts is always <= the max number, because if there are
+ * more, ShortcutParser would ignore the rest.)
+ */
+ final Comparator<ShortcutInfo> mShortcutTypeAndRankComparator = (ShortcutInfo a,
+ ShortcutInfo b) -> {
+ if (a.isManifestShortcut() && !b.isManifestShortcut()) {
+ return -1;
+ }
+ if (!a.isManifestShortcut() && b.isManifestShortcut()) {
+ return 1;
+ }
+ return a.getRank() - b.getRank();
+ };
+
+ /**
+ * Build a list of shortcuts for each target activity and return as a map. The result won't
+ * contain "floating" shortcuts because they don't belong on any activities.
+ */
+ private ArrayMap<ComponentName, ArrayList<ShortcutInfo>> sortShortcutsToActivities() {
+ final int maxShortcuts = mShortcutUser.mService.getMaxActivityShortcuts();
+
+ final ArrayMap<ComponentName, ArrayList<ShortcutInfo>> activitiesToShortcuts
+ = new ArrayMap<>();
+ for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+ final ShortcutInfo si = mShortcuts.valueAt(i);
+ if (si.isFloating()) {
+ continue; // Ignore floating shortcuts, which are not tied to any activities.
+ }
+
+ final ComponentName activity = si.getActivity();
+
+ ArrayList<ShortcutInfo> list = activitiesToShortcuts.get(activity);
+ if (list == null) {
+ list = new ArrayList<>(maxShortcuts * 2);
+ activitiesToShortcuts.put(activity, list);
+ }
+ list.add(si);
+ }
+ return activitiesToShortcuts;
+ }
+
+ /** Used by {@link #enforceShortcutCountsBeforeOperation} */
+ private void incrementCountForActivity(ArrayMap<ComponentName, Integer> counts,
+ ComponentName cn, int increment) {
+ Integer oldValue = counts.get(cn);
+ if (oldValue == null) {
+ oldValue = 0;
+ }
+
+ counts.put(cn, oldValue + increment);
+ }
+
+ /**
+ * Called by
+ * {@link android.content.pm.ShortcutManager#setDynamicShortcuts},
+ * {@link android.content.pm.ShortcutManager#addDynamicShortcuts}, and
+ * {@link android.content.pm.ShortcutManager#updateShortcuts} before actually performing
+ * the operation to make sure the operation wouldn't result in the target activities having
+ * more than the allowed number of dynamic/manifest shortcuts.
+ *
+ * @param newList shortcut list passed to set, add or updateShortcuts().
+ * @param operation add, set or update.
+ * @throws IllegalArgumentException if the operation would result in going over the max
+ * shortcut count for any activity.
+ */
+ public void enforceShortcutCountsBeforeOperation(List<ShortcutInfo> newList,
+ @ShortcutOperation int operation) {
+ final ShortcutService service = mShortcutUser.mService;
+
+ // Current # of dynamic / manifest shortcuts for each activity.
+ // (If it's for update, then don't count dynamic shortcuts, since they'll be replaced
+ // anyway.)
+ final ArrayMap<ComponentName, Integer> counts = new ArrayMap<>(4);
+ for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+ final ShortcutInfo shortcut = mShortcuts.valueAt(i);
+
+ if (shortcut.isManifestShortcut()) {
+ incrementCountForActivity(counts, shortcut.getActivity(), 1);
+ } else if (shortcut.isDynamic() && (operation != ShortcutService.OPERATION_SET)) {
+ incrementCountForActivity(counts, shortcut.getActivity(), 1);
+ }
+ }
+
+ for (int i = newList.size() - 1; i >= 0; i--) {
+ final ShortcutInfo newShortcut = newList.get(i);
+ final ComponentName newActivity = newShortcut.getActivity();
+ if (newActivity == null) {
+ if (operation != ShortcutService.OPERATION_UPDATE) {
+ service.wtf("null Activity found for non-update");
+ }
+ continue; // Activity can be null for update.
+ }
+
+ final ShortcutInfo original = mShortcuts.get(newShortcut.getId());
+ if (original == null) {
+ if (operation == ShortcutService.OPERATION_UPDATE) {
+ continue; // When updating, ignore if there's no target.
+ }
+ // Add() or set(), and there's no existing shortcut with the same ID. We're
+ // simply publishing (as opposed to updating) this shortcut, so just +1.
+ incrementCountForActivity(counts, newActivity, 1);
+ continue;
+ }
+ if (original.isFloating() && (operation == ShortcutService.OPERATION_UPDATE)) {
+ // Updating floating shortcuts doesn't affect the count, so ignore.
+ continue;
+ }
+
+ // If it's add() or update(), then need to decrement for the previous activity.
+ // Skip it for set() since it's already been taken care of by not counting the original
+ // dynamic shortcuts in the first loop.
+ if (operation != ShortcutService.OPERATION_SET) {
+ final ComponentName oldActivity = original.getActivity();
+ if (!original.isFloating()) {
+ incrementCountForActivity(counts, oldActivity, -1);
+ }
+ }
+ incrementCountForActivity(counts, newActivity, 1);
+ }
+
+ // Then make sure none of the activities have more than the max number of shortcuts.
+ for (int i = counts.size() - 1; i >= 0; i--) {
+ service.enforceMaxActivityShortcuts(counts.valueAt(i));
+ }
+ }
+
public void dump(@NonNull PrintWriter pw, @NonNull String prefix) {
pw.println();
@@ -829,7 +1011,8 @@
ShortcutService.writeAttr(out, ATTR_TEXT, si.getText());
ShortcutService.writeAttr(out, ATTR_TEXT_RES_ID, si.getTextResId());
ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE, si.getDisabledMessage());
- ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE_RES_ID, si.getDisabledMessageResId());
+ ShortcutService.writeAttr(out, ATTR_DISABLED_MESSAGE_RES_ID,
+ si.getDisabledMessageResourceId());
ShortcutService.writeAttr(out, ATTR_INTENT, si.getIntentNoExtras());
ShortcutService.writeAttr(out, ATTR_RANK, si.getRank());
ShortcutService.writeAttr(out, ATTR_TIMESTAMP,
@@ -994,4 +1177,46 @@
List<ShortcutInfo> getAllShortcutsForTest() {
return new ArrayList<>(mShortcuts.values());
}
+
+ @Override
+ public void verifyStates() {
+ super.verifyStates();
+
+ boolean failed = false;
+
+ final ArrayMap<ComponentName, ArrayList<ShortcutInfo>> all =
+ sortShortcutsToActivities();
+
+ // Make sure each activity won't have more than max shortcuts.
+ for (int i = all.size() - 1; i >= 0; i--) {
+ if (all.valueAt(i).size() > mShortcutUser.mService.getMaxActivityShortcuts()) {
+ failed = true;
+ Log.e(TAG, "Package " + getPackageName() + ": activity " + all.keyAt(i)
+ + " has " + all.valueAt(i).size() + " shortcuts.");
+ }
+ }
+
+ for (int i = mShortcuts.size() - 1; i >= 0; i--) {
+ final ShortcutInfo si = mShortcuts.valueAt(i);
+ if (!(si.isManifestShortcut() || si.isDynamic() || si.isPinned())) {
+ failed = true;
+ Log.e(TAG, "Package " + getPackageName() + ": shortcut " + si.getId()
+ + " is not manifest, dynamic or pinned.");
+ }
+ if (si.getActivity() == null) {
+ failed = true;
+ Log.e(TAG, "Package " + getPackageName() + ": shortcut " + si.getId()
+ + " has null activity.");
+ }
+ if ((si.isDynamic() || si.isManifestShortcut()) && !si.isEnabled()) {
+ failed = true;
+ Log.e(TAG, "Package " + getPackageName() + ": shortcut " + si.getId()
+ + " is not floating, but is disabled.");
+ }
+ }
+
+ if (failed) {
+ throw new IllegalStateException("See logcat for errors");
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/ShortcutPackageItem.java b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
index d08b974..757dd19 100644
--- a/services/core/java/com/android/server/pm/ShortcutPackageItem.java
+++ b/services/core/java/com/android/server/pm/ShortcutPackageItem.java
@@ -132,4 +132,10 @@
public abstract void saveToXml(@NonNull XmlSerializer out, boolean forBackup)
throws IOException, XmlPullParserException;
+
+ /**
+ * Verify various internal states.
+ */
+ public void verifyStates() {
+ }
}
diff --git a/services/core/java/com/android/server/pm/ShortcutParser.java b/services/core/java/com/android/server/pm/ShortcutParser.java
index 44d0a9f..3eda13e 100644
--- a/services/core/java/com/android/server/pm/ShortcutParser.java
+++ b/services/core/java/com/android/server/pm/ShortcutParser.java
@@ -85,6 +85,10 @@
int type;
+ int rank = 0;
+ final int maxShortcuts = service.getMaxActivityShortcuts();
+ int numShortcuts = 0;
+
outer:
while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
&& (type != XmlPullParser.END_TAG || parser.getDepth() > 0)) {
@@ -99,7 +103,7 @@
}
if (depth == 2 && TAG_SHORTCUT.equals(tag)) {
final ShortcutInfo si = parseShortcutAttributes(
- service, attrs, packageName, activity, userId);
+ service, attrs, packageName, activity, userId, rank++);
if (ShortcutService.DEBUG) {
Slog.d(TAG, "Shortcut=" + si);
}
@@ -113,10 +117,17 @@
}
if (si != null) {
+ if (numShortcuts >= maxShortcuts) {
+ Slog.w(TAG, "More than " + maxShortcuts + " shortcuts found for "
+ + activityInfo.getComponentName() + ", ignoring the rest.");
+ return result;
+ }
+
if (result == null) {
result = new ArrayList<>();
}
result.add(si);
+ numShortcuts++;
}
continue;
}
@@ -132,16 +143,15 @@
private static ShortcutInfo parseShortcutAttributes(ShortcutService service,
AttributeSet attrs, String packageName, ComponentName activity,
- @UserIdInt int userId) {
+ @UserIdInt int userId, int rank) {
final TypedArray sa = service.mContext.getResources().obtainAttributes(attrs,
R.styleable.Shortcut);
try {
final String id = sa.getString(R.styleable.Shortcut_shortcutId);
final boolean enabled = sa.getBoolean(R.styleable.Shortcut_enabled, true);
- final int rank = sa.getInt(R.styleable.Shortcut_shortcutRank, 0);
final int iconResId = sa.getResourceId(R.styleable.Shortcut_shortcutIcon, 0);
- final int titleResId = sa.getResourceId(R.styleable.Shortcut_shortcutTitle, 0);
- final int textResId = sa.getResourceId(R.styleable.Shortcut_shortcutText, 0);
+ final int titleResId = sa.getResourceId(R.styleable.Shortcut_shortcutShortLabel, 0);
+ final int textResId = sa.getResourceId(R.styleable.Shortcut_shortcutLongLabel, 0);
final int disabledMessageResId = sa.getResourceId(
R.styleable.Shortcut_shortcutDisabledMessage, 0);
final String categories = sa.getString(R.styleable.Shortcut_shortcutCategories);
diff --git a/services/core/java/com/android/server/pm/ShortcutService.java b/services/core/java/com/android/server/pm/ShortcutService.java
index dc0404c..6f12741 100644
--- a/services/core/java/com/android/server/pm/ShortcutService.java
+++ b/services/core/java/com/android/server/pm/ShortcutService.java
@@ -15,6 +15,7 @@
*/
package com.android.server.pm;
+import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
@@ -102,6 +103,8 @@
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
@@ -114,8 +117,6 @@
/**
* TODO:
- * - Implement # of dynamic shortcuts cap.
- *
* - HandleUnlockUser needs to be async. Wait on it in onCleanupUser.
*
* - Implement reportShortcutUsed().
@@ -137,12 +138,12 @@
*
* - Add more call stats.
*
- * - Rename getMaxDynamicShortcutCount and mMaxDynamicShortcuts
+ * - Rename mMaxDynamicShortcuts, because it includes manifest shortcuts too.
*/
public class ShortcutService extends IShortcutService.Stub {
static final String TAG = "ShortcutService";
- static final boolean DEBUG = true; // STOPSHIP if true
+ static final boolean DEBUG = false; // STOPSHIP if true
static final boolean DEBUG_LOAD = false; // STOPSHIP if true
static final boolean DEBUG_PROCSTATE = false; // STOPSHIP if true
@@ -329,6 +330,19 @@
private static final int PROCESS_STATE_FOREGROUND_THRESHOLD =
ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
+ static final int OPERATION_SET = 0;
+ static final int OPERATION_ADD = 1;
+ static final int OPERATION_UPDATE = 2;
+
+ /** @hide */
+ @IntDef(value = {
+ OPERATION_SET,
+ OPERATION_ADD,
+ OPERATION_UPDATE
+ })
+ @Retention(RetentionPolicy.SOURCE)
+ @interface ShortcutOperation {}
+
public ShortcutService(Context context) {
this(context, BackgroundThread.get().getLooper());
}
@@ -1312,15 +1326,23 @@
}
/**
- * Throw if {@code numShortcuts} is bigger than {@link #mMaxDynamicShortcuts}.
+ * @throws IllegalArgumentException if {@code numShortcuts} is bigger than
+ * {@link #getMaxActivityShortcuts()}.
*/
- void enforceMaxDynamicShortcuts(int numShortcuts) {
+ void enforceMaxActivityShortcuts(int numShortcuts) {
if (numShortcuts > mMaxDynamicShortcuts) {
throw new IllegalArgumentException("Max number of dynamic shortcuts exceeded");
}
}
/**
+ * Return the max number of dynamic + manifest shortcuts for each launcher icon.
+ */
+ int getMaxActivityShortcuts() {
+ return mMaxDynamicShortcuts;
+ }
+
+ /**
* - Sends a notification to LauncherApps
* - Write to file
*/
@@ -1440,11 +1462,12 @@
ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
+ ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_SET);
+
// Throttling.
if (!ps.tryApiCall()) {
return false;
}
- enforceMaxDynamicShortcuts(size);
// Validate the shortcuts.
for (int i = 0; i < size; i++) {
@@ -1461,6 +1484,9 @@
}
}
packageShortcutsChanged(packageName, userId);
+
+ verifyStates();
+
return true;
}
@@ -1477,6 +1503,8 @@
ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
+ ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_UPDATE);
+
// Throttling.
if (!ps.tryApiCall()) {
return false;
@@ -1514,6 +1542,8 @@
}
packageShortcutsChanged(packageName, userId);
+ verifyStates();
+
return true;
}
@@ -1530,6 +1560,8 @@
ps.ensureImmutableShortcutsNotIncluded(newShortcuts);
+ ps.enforceShortcutCountsBeforeOperation(newShortcuts, OPERATION_ADD);
+
// Throttling.
if (!ps.tryApiCall()) {
return false;
@@ -1546,6 +1578,8 @@
}
packageShortcutsChanged(packageName, userId);
+ verifyStates();
+
return true;
}
@@ -1567,6 +1601,8 @@
}
}
packageShortcutsChanged(packageName, userId);
+
+ verifyStates();
}
@Override
@@ -1584,6 +1620,8 @@
}
}
packageShortcutsChanged(packageName, userId);
+
+ verifyStates();
}
@Override
@@ -1603,6 +1641,8 @@
}
}
packageShortcutsChanged(packageName, userId);
+
+ verifyStates();
}
@Override
@@ -1613,6 +1653,8 @@
getPackageShortcutsLocked(packageName, userId).deleteAllDynamicShortcuts();
}
packageShortcutsChanged(packageName, userId);
+
+ verifyStates();
}
@Override
@@ -2023,6 +2065,8 @@
launcher.pinShortcuts(userId, packageName, shortcutIds);
}
packageShortcutsChanged(packageName, userId);
+
+ verifyStates();
}
@Override
@@ -2940,4 +2984,29 @@
return pkg.findShortcutById(shortcutId);
}
}
+
+ /**
+ * Control whether {@link #verifyStates} should be performed. We always perform it during unit
+ * tests.
+ */
+ @VisibleForTesting
+ boolean injectShouldPerformVerification() {
+ return DEBUG;
+ }
+
+ /**
+ * Check various internal states and throws if there's any inconsistency.
+ * This is normally only enabled during unit tests.
+ */
+ final void verifyStates() {
+ if (injectShouldPerformVerification()) {
+ verifyStatesInner();
+ }
+ }
+
+ private void verifyStatesInner() {
+ synchronized (this) {
+ forEachLoadedUserLocked(u -> u.forAllPackageItems(ShortcutPackageItem::verifyStates));
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java
index 9c62b20..95689ca 100644
--- a/services/core/java/com/android/server/pm/UserManagerService.java
+++ b/services/core/java/com/android/server/pm/UserManagerService.java
@@ -1014,9 +1014,13 @@
// in getUserRestrictionSource on who set local policies.
mGlobalRestrictionOwnerUserId = userId;
} else {
- // When profile owner sets restrictions it passes null global bundle and we reset
- // global restriction owner userId.
- mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL;
+ if (mGlobalRestrictionOwnerUserId == userId) {
+ // When profile owner sets restrictions it passes null global bundle and we
+ // reset global restriction owner userId.
+ // This means this user used to have DO, but now the DO is gone and the user
+ // instead has PO.
+ mGlobalRestrictionOwnerUserId = UserHandle.USER_NULL;
+ }
}
{
// Update local.
@@ -2031,6 +2035,7 @@
final boolean isGuest = (flags & UserInfo.FLAG_GUEST) != 0;
final boolean isManagedProfile = (flags & UserInfo.FLAG_MANAGED_PROFILE) != 0;
final boolean isRestricted = (flags & UserInfo.FLAG_RESTRICTED) != 0;
+ final boolean isDemo = (flags & UserInfo.FLAG_DEMO) != 0;
final long ident = Binder.clearCallingIdentity();
UserInfo userInfo;
UserData userData;
@@ -2048,8 +2053,8 @@
Log.e(LOG_TAG, "Cannot add more managed profiles for user " + parentId);
return null;
}
- if (!isGuest && !isManagedProfile && isUserLimitReached()) {
- // If we're not adding a guest user or a managed profile and the limit has
+ if (!isGuest && !isManagedProfile && !isDemo && isUserLimitReached()) {
+ // If we're not adding a guest/demo user or a managed profile and the limit has
// been reached, cannot add a user.
return null;
}
diff --git a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
index a77d512..2e32fe3 100644
--- a/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
+++ b/services/core/java/com/android/server/policy/ImmersiveModeConfirmation.java
@@ -30,6 +30,7 @@
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.UserHandle;
+import android.os.UserManager;
import android.provider.Settings;
import android.service.vr.IVrManager;
import android.service.vr.IVrStateCallbacks;
@@ -142,7 +143,8 @@
if (!disabled
&& (DEBUG_SHOW_EVERY_TIME || !mConfirmed)
&& userSetupComplete
- && !mVrModeEnabled) {
+ && !mVrModeEnabled
+ && !UserManager.isDeviceInDemoMode(mContext)) {
mHandler.sendEmptyMessageDelayed(H.SHOW, mShowDelayMs);
}
} else {
diff --git a/services/core/java/com/android/server/power/Notifier.java b/services/core/java/com/android/server/power/Notifier.java
index 7108f4a..3ed6ec9 100644
--- a/services/core/java/com/android/server/power/Notifier.java
+++ b/services/core/java/com/android/server/power/Notifier.java
@@ -23,6 +23,7 @@
import com.android.internal.app.IBatteryStats;
import com.android.server.EventLogTags;
import com.android.server.LocalServices;
+import com.android.server.am.RetailDemoModeServiceInternal;
import android.app.ActivityManagerNative;
import android.content.BroadcastReceiver;
@@ -91,6 +92,7 @@
private final ActivityManagerInternal mActivityManagerInternal;
private final InputManagerInternal mInputManagerInternal;
private final InputMethodManagerInternal mInputMethodManagerInternal;
+ private final RetailDemoModeServiceInternal mRetailDemoModeServiceInternal;
private final NotifierHandler mHandler;
private final Intent mScreenOnIntent;
@@ -136,6 +138,7 @@
mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class);
mInputManagerInternal = LocalServices.getService(InputManagerInternal.class);
mInputMethodManagerInternal = LocalServices.getService(InputMethodManagerInternal.class);
+ mRetailDemoModeServiceInternal = LocalServices.getService(RetailDemoModeServiceInternal.class);
mHandler = new NotifierHandler(looper);
mScreenOnIntent = new Intent(Intent.ACTION_SCREEN_ON);
@@ -534,7 +537,9 @@
}
mUserActivityPending = false;
}
-
+ if (mRetailDemoModeServiceInternal != null) {
+ mRetailDemoModeServiceInternal.onUserActivity();
+ }
mPolicy.userActivity();
}
diff --git a/services/core/java/com/android/server/tv/TvInputHardwareManager.java b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
index 5c6a696..8043c65 100644
--- a/services/core/java/com/android/server/tv/TvInputHardwareManager.java
+++ b/services/core/java/com/android/server/tv/TvInputHardwareManager.java
@@ -742,7 +742,10 @@
synchronized (mImplLock) {
mAudioSource = null;
mAudioSink.clear();
- mAudioPatch = null;
+ if (mAudioPatch != null) {
+ mAudioManager.releaseAudioPatch(mAudioPatch);
+ mAudioPatch = null;
+ }
}
}
};
@@ -980,6 +983,9 @@
}
if (shouldRecreateAudioPatch) {
mCommittedVolume = volume;
+ if (mAudioPatch != null) {
+ mAudioManager.releaseAudioPatch(mAudioPatch);
+ }
mAudioManager.createAudioPatch(
audioPatchArray,
new AudioPortConfig[] { sourceConfig },
diff --git a/services/core/java/com/android/server/wm/WindowState.java b/services/core/java/com/android/server/wm/WindowState.java
index ff95afc..08bfa2d 100644
--- a/services/core/java/com/android/server/wm/WindowState.java
+++ b/services/core/java/com/android/server/wm/WindowState.java
@@ -2732,14 +2732,14 @@
return mStringNameCache;
}
- void transformFromScreenToSurfaceSpace(Rect rect) {
+ void transformClipRectFromScreenToSurfaceSpace(Rect clipRect) {
if (mHScale >= 0) {
- rect.left = (int) (rect.left / mHScale);
- rect.right = (int) (rect.right / mHScale);
+ clipRect.left = (int) (clipRect.left / mHScale);
+ clipRect.right = (int) Math.ceil(clipRect.right / mHScale);
}
if (mVScale >= 0) {
- rect.top = (int) (rect.top / mVScale);
- rect.bottom = (int) (rect.bottom / mVScale);
+ clipRect.top = (int) (clipRect.top / mVScale);
+ clipRect.bottom = (int) Math.ceil(clipRect.bottom / mVScale);
}
}
diff --git a/services/core/java/com/android/server/wm/WindowStateAnimator.java b/services/core/java/com/android/server/wm/WindowStateAnimator.java
index 37d6faf5..3b4c3cf 100644
--- a/services/core/java/com/android/server/wm/WindowStateAnimator.java
+++ b/services/core/java/com/android/server/wm/WindowStateAnimator.java
@@ -1281,7 +1281,7 @@
if (DEBUG_WINDOW_CROP) Slog.d(TAG,
"win=" + w + " Clip rect after stack adjustment=" + clipRect);
- w.transformFromScreenToSurfaceSpace(clipRect);
+ w.transformClipRectFromScreenToSurfaceSpace(clipRect);
// See {@link WindowState#notifyMovedInStack} for why this is necessary.
if (w.hasJustMovedInStack() && mLastClipRect.isEmpty() && !clipRect.isEmpty()) {
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 982a6d7..107de8b 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -706,13 +706,15 @@
// as appropriate.
mSystemServiceManager.startService(UiModeManagerService.class);
- Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "UpdatePackagesIfNeeded");
- try {
- mPackageManagerService.updatePackagesIfNeeded();
- } catch (Throwable e) {
- reportWtf("update packages", e);
+ if (!mOnlyCore) {
+ Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "UpdatePackagesIfNeeded");
+ try {
+ mPackageManagerService.updatePackagesIfNeeded();
+ } catch (Throwable e) {
+ reportWtf("update packages", e);
+ }
+ Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
- Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "PerformFstrimIfNeeded");
try {
diff --git a/services/tests/servicestests/res/xml/shortcut_1.xml b/services/tests/servicestests/res/xml/shortcut_1.xml
index c370e74..f6d54fc 100644
--- a/services/tests/servicestests/res/xml/shortcut_1.xml
+++ b/services/tests/servicestests/res/xml/shortcut_1.xml
@@ -2,10 +2,9 @@
<shortcut
android:shortcutId="ms1"
android:enabled="true"
- android:shortcutRank="1"
android:shortcutIcon="@drawable/icon1"
- android:shortcutTitle="@string/shortcut_title1"
- android:shortcutText="@string/shortcut_text1"
+ android:shortcutShortLabel="@string/shortcut_title1"
+ android:shortcutLongLabel="@string/shortcut_text1"
android:shortcutDisabledMessage="@string/shortcut_disabled_message1"
android:shortcutCategories="android.shortcut.conversation:android.shortcut.media"
android:shortcutIntentAction="action1"
diff --git a/services/tests/servicestests/res/xml/shortcut_1_alt.xml b/services/tests/servicestests/res/xml/shortcut_1_alt.xml
new file mode 100644
index 0000000..bf14f49
--- /dev/null
+++ b/services/tests/servicestests/res/xml/shortcut_1_alt.xml
@@ -0,0 +1,28 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
+ <shortcut
+ android:shortcutId="ms1-alt"
+ android:enabled="true"
+ android:shortcutIcon="@drawable/icon1"
+ android:shortcutShortLabel="@string/shortcut_title1"
+ android:shortcutLongLabel="@string/shortcut_text1"
+ android:shortcutDisabledMessage="@string/shortcut_disabled_message1"
+ android:shortcutCategories="android.shortcut.conversation:android.shortcut.media"
+ android:shortcutIntentAction="action1"
+ android:shortcutIntentData="data1"
+ />
+</shortcuts>
diff --git a/services/tests/servicestests/res/xml/shortcut_1_disable.xml b/services/tests/servicestests/res/xml/shortcut_1_disable.xml
index 08ecac3..81a84b4 100644
--- a/services/tests/servicestests/res/xml/shortcut_1_disable.xml
+++ b/services/tests/servicestests/res/xml/shortcut_1_disable.xml
@@ -1,11 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
android:shortcutId="ms1"
android:enabled="false"
- android:shortcutRank="1"
android:shortcutIcon="@drawable/icon2"
- android:shortcutTitle="@string/shortcut_title2"
- android:shortcutText="@string/shortcut_text2"
+ android:shortcutShortLabel="@string/shortcut_title2"
+ android:shortcutLongLabel="@string/shortcut_text2"
android:shortcutDisabledMessage="@string/shortcut_disabled_message2"
/>
</shortcuts>
diff --git a/services/tests/servicestests/res/xml/shortcut_2.xml b/services/tests/servicestests/res/xml/shortcut_2.xml
index 9e923f3..96ed382 100644
--- a/services/tests/servicestests/res/xml/shortcut_2.xml
+++ b/services/tests/servicestests/res/xml/shortcut_2.xml
@@ -1,11 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
android:shortcutId="ms1"
android:enabled="true"
- android:shortcutRank="1"
android:shortcutIcon="@drawable/icon1"
- android:shortcutTitle="@string/shortcut_title1"
- android:shortcutText="@string/shortcut_text1"
+ android:shortcutShortLabel="@string/shortcut_title1"
+ android:shortcutLongLabel="@string/shortcut_text1"
android:shortcutDisabledMessage="@string/shortcut_disabled_message1"
android:shortcutCategories="android.shortcut.conversation:android.shortcut.media"
android:shortcutIntentAction="action1"
@@ -14,10 +28,9 @@
<shortcut
android:shortcutId="ms2"
android:enabled="true"
- android:shortcutRank="2"
android:shortcutIcon="@drawable/icon2"
- android:shortcutTitle="@string/shortcut_title2"
- android:shortcutText="@string/shortcut_text2"
+ android:shortcutShortLabel="@string/shortcut_title2"
+ android:shortcutLongLabel="@string/shortcut_text2"
android:shortcutDisabledMessage="@string/shortcut_disabled_message2"
android:shortcutCategories="android.shortcut.conversation"
android:shortcutIntentAction="action2"
diff --git a/services/tests/servicestests/res/xml/shortcut_2_duplicate.xml b/services/tests/servicestests/res/xml/shortcut_2_duplicate.xml
index d90c18d..2f814b7 100644
--- a/services/tests/servicestests/res/xml/shortcut_2_duplicate.xml
+++ b/services/tests/servicestests/res/xml/shortcut_2_duplicate.xml
@@ -1,12 +1,27 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
android:shortcutId="ms1"
- android:shortcutTitle="@string/shortcut_title1"
+ android:shortcutShortLabel="@string/shortcut_title1"
android:shortcutIntentAction="action1"
/>
<shortcut
android:shortcutId="ms1"
- android:shortcutTitle="@string/shortcut_title2"
+ android:shortcutShortLabel="@string/shortcut_title2"
android:shortcutIntentAction="action2"
/>
</shortcuts>
diff --git a/services/tests/servicestests/res/xml/shortcut_5.xml b/services/tests/servicestests/res/xml/shortcut_5.xml
index f3f71d2..56dba0e 100644
--- a/services/tests/servicestests/res/xml/shortcut_5.xml
+++ b/services/tests/servicestests/res/xml/shortcut_5.xml
@@ -1,11 +1,25 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
android:shortcutId="ms1"
android:enabled="true"
- android:shortcutRank="1"
android:shortcutIcon="@drawable/icon1"
- android:shortcutTitle="@string/shortcut_title1"
- android:shortcutText="@string/shortcut_text1"
+ android:shortcutShortLabel="@string/shortcut_title1"
+ android:shortcutLongLabel="@string/shortcut_text1"
android:shortcutDisabledMessage="@string/shortcut_disabled_message1"
android:shortcutCategories="android.shortcut.conversation:android.shortcut.media"
android:shortcutIntentAction="action1"
@@ -14,27 +28,26 @@
<shortcut
android:shortcutId="ms2"
android:enabled="true"
- android:shortcutRank="2"
android:shortcutIcon="@drawable/icon2"
- android:shortcutTitle="@string/shortcut_title2"
- android:shortcutText="@string/shortcut_text2"
+ android:shortcutShortLabel="@string/shortcut_title2"
+ android:shortcutLongLabel="@string/shortcut_text2"
android:shortcutDisabledMessage="@string/shortcut_disabled_message2"
android:shortcutCategories="android.shortcut.conversation"
android:shortcutIntentAction="action2"
/>
<shortcut
android:shortcutId="ms3"
- android:shortcutTitle="@string/shortcut_title1"
+ android:shortcutShortLabel="@string/shortcut_title1"
android:shortcutIntentAction="android.intent.action.VIEW"
/>
<shortcut
android:shortcutId="ms4"
- android:shortcutTitle="@string/shortcut_title1"
+ android:shortcutShortLabel="@string/shortcut_title1"
android:shortcutIntentAction="android.intent.action.VIEW"
/>
<shortcut
android:shortcutId="ms5"
- android:shortcutTitle="@string/shortcut_title1"
+ android:shortcutShortLabel="@string/shortcut_title1"
android:shortcutIntentAction="android.intent.action.VIEW"
/>
</shortcuts>
diff --git a/services/tests/servicestests/res/xml/shortcut_5_alt.xml b/services/tests/servicestests/res/xml/shortcut_5_alt.xml
new file mode 100644
index 0000000..74085d9
--- /dev/null
+++ b/services/tests/servicestests/res/xml/shortcut_5_alt.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
+ <shortcut
+ android:shortcutId="ms1_alt"
+ android:enabled="true"
+ android:shortcutIcon="@drawable/icon1"
+ android:shortcutShortLabel="@string/shortcut_title1"
+ android:shortcutLongLabel="@string/shortcut_text1"
+ android:shortcutDisabledMessage="@string/shortcut_disabled_message1"
+ android:shortcutCategories="android.shortcut.conversation:android.shortcut.media"
+ android:shortcutIntentAction="action1"
+ android:shortcutIntentData="http://a.b.c/1"
+ />
+ <shortcut
+ android:shortcutId="ms2_alt"
+ android:enabled="true"
+ android:shortcutIcon="@drawable/icon2"
+ android:shortcutShortLabel="@string/shortcut_title2"
+ android:shortcutLongLabel="@string/shortcut_text2"
+ android:shortcutDisabledMessage="@string/shortcut_disabled_message2"
+ android:shortcutCategories="android.shortcut.conversation"
+ android:shortcutIntentAction="action2"
+ />
+ <shortcut
+ android:shortcutId="ms3_alt"
+ android:shortcutShortLabel="@string/shortcut_title1"
+ android:shortcutIntentAction="android.intent.action.VIEW"
+ />
+ <shortcut
+ android:shortcutId="ms4_alt"
+ android:shortcutShortLabel="@string/shortcut_title1"
+ android:shortcutIntentAction="android.intent.action.VIEW"
+ />
+ <shortcut
+ android:shortcutId="ms5_alt"
+ android:shortcutShortLabel="@string/shortcut_title1"
+ android:shortcutIntentAction="android.intent.action.VIEW"
+ />
+</shortcuts>
diff --git a/services/tests/servicestests/res/xml/shortcut_error_1.xml b/services/tests/servicestests/res/xml/shortcut_error_1.xml
index 2c51420..5822496 100644
--- a/services/tests/servicestests/res/xml/shortcut_error_1.xml
+++ b/services/tests/servicestests/res/xml/shortcut_error_1.xml
@@ -1,11 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
- android:shortcutTitle="@string/shortcut_title1"
+ android:shortcutShortLabel="@string/shortcut_title1"
android:shortcutIntentAction="android.intent.action.VIEW"
/>
<shortcut
android:shortcutId="x1"
- android:shortcutTitle="@string/shortcut_title1"
+ android:shortcutShortLabel="@string/shortcut_title1"
android:shortcutIntentAction="android.intent.action.VIEW"
/>
</shortcuts>
diff --git a/services/tests/servicestests/res/xml/shortcut_error_2.xml b/services/tests/servicestests/res/xml/shortcut_error_2.xml
index d075e7d..ca67ec7 100644
--- a/services/tests/servicestests/res/xml/shortcut_error_2.xml
+++ b/services/tests/servicestests/res/xml/shortcut_error_2.xml
@@ -1,3 +1,18 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
android:shortcutId="manifest-shortcut-3"
@@ -5,7 +20,7 @@
/>
<shortcut
android:shortcutId="x2"
- android:shortcutTitle="@string/shortcut_title1"
+ android:shortcutShortLabel="@string/shortcut_title1"
android:shortcutIntentAction="android.intent.action.VIEW"
/>
</shortcuts>
diff --git a/services/tests/servicestests/res/xml/shortcut_error_3.xml b/services/tests/servicestests/res/xml/shortcut_error_3.xml
index 30bf56e..fb7b31c 100644
--- a/services/tests/servicestests/res/xml/shortcut_error_3.xml
+++ b/services/tests/servicestests/res/xml/shortcut_error_3.xml
@@ -1,11 +1,26 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!-- Copyright (C) 2016 The Android Open Source Project
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
<shortcuts xmlns:android="http://schemas.android.com/apk/res/android" >
<shortcut
android:shortcutId="manifest-shortcut-3"
- android:shortcutTitle="@string/shortcut_title1"
+ android:shortcutShortLabel="@string/shortcut_title1"
/>
<shortcut
android:shortcutId="x3"
- android:shortcutTitle="@string/shortcut_title1"
+ android:shortcutShortLabel="@string/shortcut_title1"
android:shortcutIntentAction="android.intent.action.VIEW"
/>
</shortcuts>
diff --git a/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
new file mode 100644
index 0000000..6d75df2
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/BaseShortcutManagerTest.java
@@ -0,0 +1,1476 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.cloneShortcutList;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.hashSet;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.makeBundle;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
+
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.reset;
+import static org.mockito.Mockito.spy;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.annotation.RequiresPermission;
+import android.annotation.UserIdInt;
+import android.app.Activity;
+import android.app.IUidObserver;
+import android.content.BroadcastReceiver;
+import android.content.ComponentName;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ILauncherApps;
+import android.content.pm.LauncherApps;
+import android.content.pm.LauncherApps.ShortcutQuery;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
+import android.content.pm.ShortcutInfo;
+import android.content.pm.ShortcutManager;
+import android.content.pm.ShortcutServiceInternal;
+import android.content.pm.Signature;
+import android.content.pm.UserInfo;
+import android.content.res.Resources;
+import android.content.res.XmlResourceParser;
+import android.graphics.drawable.Icon;
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.FileUtils;
+import android.os.Handler;
+import android.os.Looper;
+import android.os.Process;
+import android.os.UserHandle;
+import android.os.UserManager;
+import android.test.InstrumentationTestCase;
+import android.test.mock.MockContext;
+import android.util.Log;
+import android.util.Pair;
+
+import com.android.internal.util.Preconditions;
+import com.android.server.LocalServices;
+import com.android.server.SystemService;
+import com.android.server.pm.LauncherAppsService.LauncherAppsImpl;
+import com.android.server.pm.ShortcutUser.PackageWithUser;
+
+import org.junit.Assert;
+import org.mockito.ArgumentCaptor;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.BufferedReader;
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.function.BiPredicate;
+import java.util.function.Consumer;
+
+public abstract class BaseShortcutManagerTest extends InstrumentationTestCase {
+ protected static final String TAG = "ShortcutManagerTest";
+
+ /**
+ * Whether to enable dump or not. Should be only true when debugging to avoid bugs where
+ * dump affecting the behavior.
+ */
+ protected static final boolean ENABLE_DUMP = false; // DO NOT SUBMIT WITH true
+
+ protected static final boolean DUMP_IN_TEARDOWN = false; // DO NOT SUBMIT WITH true
+
+ protected static final String[] EMPTY_STRINGS = new String[0]; // Just for readability.
+
+ // public for mockito
+ public class BaseContext extends MockContext {
+ @Override
+ public Object getSystemService(String name) {
+ switch (name) {
+ case Context.USER_SERVICE:
+ return mMockUserManager;
+ }
+ throw new UnsupportedOperationException();
+ }
+
+ @Override
+ public String getSystemServiceName(Class<?> serviceClass) {
+ return getTestContext().getSystemServiceName(serviceClass);
+ }
+
+ @Override
+ public PackageManager getPackageManager() {
+ return mMockPackageManager;
+ }
+
+ @Override
+ public Resources getResources() {
+ return getTestContext().getResources();
+ }
+
+ @Override
+ public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
+ IntentFilter filter, String broadcastPermission, Handler scheduler) {
+ // ignore.
+ return null;
+ }
+ }
+
+ /** Context used in the client side */
+ public class ClientContext extends BaseContext {
+ @Override
+ public String getPackageName() {
+ return mInjectedClientPackage;
+ }
+
+ @Override
+ public int getUserId() {
+ return getCallingUserId();
+ }
+ }
+
+ /** Context used in the service side */
+ public class ServiceContext extends BaseContext {
+ long injectClearCallingIdentity() {
+ final int prevCallingUid = mInjectedCallingUid;
+ mInjectedCallingUid = Process.SYSTEM_UID;
+ return prevCallingUid;
+ }
+
+ void injectRestoreCallingIdentity(long token) {
+ mInjectedCallingUid = (int) token;
+ }
+
+ @Override
+ public void startActivityAsUser(@RequiresPermission Intent intent, @Nullable Bundle options,
+ UserHandle userId) {
+ }
+
+ @Override
+ public int getUserId() {
+ return UserHandle.USER_SYSTEM;
+ }
+
+ public PackageInfo injectGetActivitiesWithMetadata(
+ String packageName, @UserIdInt int userId) {
+ return BaseShortcutManagerTest.this.injectGetActivitiesWithMetadata(packageName, userId);
+ }
+
+ public XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
+ return BaseShortcutManagerTest.this.injectXmlMetaData(activityInfo, key);
+ }
+ }
+
+ /** ShortcutService with injection override methods. */
+ protected final class ShortcutServiceTestable extends ShortcutService {
+ final ServiceContext mContext;
+ IUidObserver mUidObserver;
+
+ public ShortcutServiceTestable(ServiceContext context, Looper looper) {
+ super(context, looper);
+ mContext = context;
+ }
+
+ @Override
+ boolean injectShouldPerformVerification() {
+ return true; // Always verify during unit tests.
+ }
+
+ @Override
+ String injectShortcutManagerConstants() {
+ return ConfigConstants.KEY_RESET_INTERVAL_SEC + "=" + (INTERVAL / 1000) + ","
+ + ConfigConstants.KEY_MAX_SHORTCUTS + "=" + MAX_SHORTCUTS + ","
+ + ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "="
+ + MAX_UPDATES_PER_INTERVAL + ","
+ + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP + "=" + MAX_ICON_DIMENSION + ","
+ + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM + "="
+ + MAX_ICON_DIMENSION_LOWRAM + ","
+ + ConfigConstants.KEY_ICON_FORMAT + "=PNG,"
+ + ConfigConstants.KEY_ICON_QUALITY + "=100";
+ }
+
+ @Override
+ long injectClearCallingIdentity() {
+ return mContext.injectClearCallingIdentity();
+ }
+
+ @Override
+ void injectRestoreCallingIdentity(long token) {
+ mContext.injectRestoreCallingIdentity(token);
+ }
+
+ @Override
+ int injectDipToPixel(int dip) {
+ return dip;
+ }
+
+ @Override
+ long injectCurrentTimeMillis() {
+ return mInjectedCurrentTimeMillis;
+ }
+
+ @Override
+ long injectElapsedRealtime() {
+ // TODO This should be kept separately from mInjectedCurrentTimeMillis, since
+ // this should increase even if we rewind mInjectedCurrentTimeMillis in some tests.
+ return mInjectedCurrentTimeMillis - START_TIME;
+ }
+
+ @Override
+ int injectBinderCallingUid() {
+ return mInjectedCallingUid;
+ }
+
+ @Override
+ int injectGetPackageUid(String packageName, int userId) {
+ return getInjectedPackageInfo(packageName, userId, false).applicationInfo.uid;
+ }
+
+ @Override
+ File injectSystemDataPath() {
+ return new File(mInjectedFilePathRoot, "system");
+ }
+
+ @Override
+ File injectUserDataPath(@UserIdInt int userId) {
+ return new File(mInjectedFilePathRoot, "user-" + userId);
+ }
+
+ @Override
+ void injectValidateIconResPackage(ShortcutInfo shortcut, Icon icon) {
+ // Can't check
+ }
+
+ @Override
+ boolean injectIsLowRamDevice() {
+ return mInjectedIsLowRamDevice;
+ }
+
+ @Override
+ void injectRegisterUidObserver(IUidObserver observer, int which) {
+ mUidObserver = observer;
+ }
+
+ @Override
+ PackageManagerInternal injectPackageManagerInternal() {
+ return mMockPackageManagerInternal;
+ }
+
+ @Override
+ boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) {
+ return mDefaultLauncherChecker.test(callingPackage, userId);
+ }
+
+ @Override
+ PackageInfo injectPackageInfo(String packageName, @UserIdInt int userId,
+ boolean getSignatures) {
+ return getInjectedPackageInfo(packageName, userId, getSignatures);
+ }
+
+ @Override
+ ApplicationInfo injectApplicationInfo(String packageName, @UserIdInt int userId) {
+ PackageInfo pi = injectPackageInfo(packageName, userId, /* getSignatures= */ false);
+ return pi != null ? pi.applicationInfo : null;
+ }
+
+ @Override
+ List<ApplicationInfo> injectInstalledApplications(@UserIdInt int userId) {
+ return getInstalledApplications(userId);
+ }
+
+ @Override
+ PackageInfo injectGetActivitiesWithMetadata(String packageName, @UserIdInt int userId) {
+ return mContext.injectGetActivitiesWithMetadata(packageName, userId);
+ }
+
+ @Override
+ XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
+ return mContext.injectXmlMetaData(activityInfo, key);
+ }
+
+ @Override
+ void postToHandler(Runnable r) {
+ final long token = mContext.injectClearCallingIdentity();
+ r.run();
+ mContext.injectRestoreCallingIdentity(token);
+ }
+
+ @Override
+ void injectEnforceCallingPermission(String permission, String message) {
+ if (!mCallerPermissions.contains(permission)) {
+ throw new SecurityException("Missing permission: " + permission);
+ }
+ }
+
+ @Override
+ void wtf(String message, Exception e) {
+ // During tests, WTF is fatal.
+ fail(message + " exception: " + e);
+ }
+ }
+
+ /** ShortcutManager with injection override methods. */
+ protected class ShortcutManagerTestable extends ShortcutManager {
+ public ShortcutManagerTestable(Context context, ShortcutServiceTestable service) {
+ super(context, service);
+ }
+
+ @Override
+ protected int injectMyUserId() {
+ return UserHandle.getUserId(mInjectedCallingUid);
+ }
+
+ @Override
+ public boolean setDynamicShortcuts(@NonNull List<ShortcutInfo> shortcutInfoList) {
+ // Note to simulate the binder RPC, we need to clone the incoming arguments.
+ // Otherwise bad things will happen because they're mutable.
+ return super.setDynamicShortcuts(cloneShortcutList(shortcutInfoList));
+ }
+
+ @Override
+ public boolean addDynamicShortcuts(@NonNull List<ShortcutInfo> shortcutInfoList) {
+ // Note to simulate the binder RPC, we need to clone the incoming arguments.
+ return super.addDynamicShortcuts(cloneShortcutList(shortcutInfoList));
+ }
+
+ @Override
+ public boolean updateShortcuts(List<ShortcutInfo> shortcutInfoList) {
+ // Note to simulate the binder RPC, we need to clone the incoming arguments.
+ return super.updateShortcuts(cloneShortcutList(shortcutInfoList));
+ }
+ }
+
+ protected class LauncherAppImplTestable extends LauncherAppsImpl {
+ final ServiceContext mContext;
+
+ public LauncherAppImplTestable(ServiceContext context) {
+ super(context);
+ mContext = context;
+ }
+
+ @Override
+ public void verifyCallingPackage(String callingPackage) {
+ // SKIP
+ }
+
+ @Override
+ void postToPackageMonitorHandler(Runnable r) {
+ final long token = mContext.injectClearCallingIdentity();
+ r.run();
+ mContext.injectRestoreCallingIdentity(token);
+ }
+
+ @Override
+ int injectBinderCallingUid() {
+ return mInjectedCallingUid;
+ }
+
+ @Override
+ long injectClearCallingIdentity() {
+ final int prevCallingUid = mInjectedCallingUid;
+ mInjectedCallingUid = Process.SYSTEM_UID;
+ return prevCallingUid;
+ }
+
+ @Override
+ void injectRestoreCallingIdentity(long token) {
+ mInjectedCallingUid = (int) token;
+ }
+ }
+
+ protected class LauncherAppsTestable extends LauncherApps {
+ public LauncherAppsTestable(Context context, ILauncherApps service) {
+ super(context, service);
+ }
+ }
+
+ public static class ShortcutActivity extends Activity {
+ }
+
+ public static class ShortcutActivity2 extends Activity {
+ }
+
+ public static class ShortcutActivity3 extends Activity {
+ }
+
+ protected ServiceContext mServiceContext;
+ protected ClientContext mClientContext;
+
+ protected ShortcutServiceTestable mService;
+ protected ShortcutManagerTestable mManager;
+ protected ShortcutServiceInternal mInternal;
+
+ protected LauncherAppImplTestable mLauncherAppImpl;
+
+ // LauncherApps has per-instace state, so we need a differnt instance for each launcher.
+ protected final Map<Pair<Integer, String>, LauncherAppsTestable>
+ mLauncherAppsMap = new HashMap<>();
+ protected LauncherAppsTestable mLauncherApps; // Current one
+
+ protected File mInjectedFilePathRoot;
+
+ protected long mInjectedCurrentTimeMillis;
+
+ protected boolean mInjectedIsLowRamDevice;
+
+ protected int mInjectedCallingUid;
+ protected String mInjectedClientPackage;
+
+ protected Map<String, PackageInfo> mInjectedPackages;
+
+ protected Set<PackageWithUser> mUninstalledPackages;
+
+ protected PackageManager mMockPackageManager;
+ protected PackageManagerInternal mMockPackageManagerInternal;
+ protected UserManager mMockUserManager;
+
+ protected static final String CALLING_PACKAGE_1 = "com.android.test.1";
+ protected static final int CALLING_UID_1 = 10001;
+
+ protected static final String CALLING_PACKAGE_2 = "com.android.test.2";
+ protected static final int CALLING_UID_2 = 10002;
+
+ protected static final String CALLING_PACKAGE_3 = "com.android.test.3";
+ protected static final int CALLING_UID_3 = 10003;
+
+ protected static final String CALLING_PACKAGE_4 = "com.android.test.4";
+ protected static final int CALLING_UID_4 = 10004;
+
+ protected static final String LAUNCHER_1 = "com.android.launcher.1";
+ protected static final int LAUNCHER_UID_1 = 10011;
+
+ protected static final String LAUNCHER_2 = "com.android.launcher.2";
+ protected static final int LAUNCHER_UID_2 = 10012;
+
+ protected static final String LAUNCHER_3 = "com.android.launcher.3";
+ protected static final int LAUNCHER_UID_3 = 10013;
+
+ protected static final String LAUNCHER_4 = "com.android.launcher.4";
+ protected static final int LAUNCHER_UID_4 = 10014;
+
+ protected static final int USER_0 = UserHandle.USER_SYSTEM;
+ protected static final int USER_10 = 10;
+ protected static final int USER_11 = 11;
+ protected static final int USER_P0 = 20; // profile of user 0
+
+ protected static final UserHandle HANDLE_USER_0 = UserHandle.of(USER_0);
+ protected static final UserHandle HANDLE_USER_10 = UserHandle.of(USER_10);
+ protected static final UserHandle HANDLE_USER_11 = UserHandle.of(USER_11);
+ protected static final UserHandle HANDLE_USER_P0 = UserHandle.of(USER_P0);
+
+ protected static final UserInfo USER_INFO_0 = withProfileGroupId(
+ new UserInfo(USER_0, "user0",
+ UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED), 10);
+
+ protected static final UserInfo USER_INFO_10 =
+ new UserInfo(USER_10, "user10", UserInfo.FLAG_INITIALIZED);
+
+ protected static final UserInfo USER_INFO_11 =
+ new UserInfo(USER_11, "user11", UserInfo.FLAG_INITIALIZED);
+
+ protected static final UserInfo USER_INFO_P0 = withProfileGroupId(
+ new UserInfo(USER_P0, "userP0",
+ UserInfo.FLAG_MANAGED_PROFILE), 10);
+
+ protected BiPredicate<String, Integer> mDefaultLauncherChecker =
+ (callingPackage, userId) ->
+ LAUNCHER_1.equals(callingPackage) || LAUNCHER_2.equals(callingPackage)
+ || LAUNCHER_3.equals(callingPackage) || LAUNCHER_4.equals(callingPackage);
+
+ protected static final long START_TIME = 1440000000101L;
+
+ protected static final long INTERVAL = 10000;
+
+ protected static final int MAX_SHORTCUTS = 10;
+
+ protected static final int MAX_UPDATES_PER_INTERVAL = 3;
+
+ protected static final int MAX_ICON_DIMENSION = 128;
+
+ protected static final int MAX_ICON_DIMENSION_LOWRAM = 32;
+
+ protected static final ShortcutQuery QUERY_ALL = new ShortcutQuery();
+
+ protected final ArrayList<String> mCallerPermissions = new ArrayList<>();
+
+ protected final HashMap<String, LinkedHashMap<ComponentName, Integer>> mActivityMetadataResId
+ = new HashMap<>();
+
+ static {
+ QUERY_ALL.setQueryFlags(
+ ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED);
+ }
+
+ @Override
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ mServiceContext = spy(new ServiceContext());
+ mClientContext = new ClientContext();
+
+ mMockPackageManager = mock(PackageManager.class);
+ mMockPackageManagerInternal = mock(PackageManagerInternal.class);
+ mMockUserManager = mock(UserManager.class);
+
+ // Prepare injection values.
+
+ mInjectedCurrentTimeMillis = START_TIME;
+
+ mInjectedPackages = new HashMap<>();
+ addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 1);
+ addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 2);
+ addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 3);
+ addPackage(CALLING_PACKAGE_4, CALLING_UID_4, 10);
+ addPackage(LAUNCHER_1, LAUNCHER_UID_1, 4);
+ addPackage(LAUNCHER_2, LAUNCHER_UID_2, 5);
+ addPackage(LAUNCHER_3, LAUNCHER_UID_3, 6);
+ addPackage(LAUNCHER_4, LAUNCHER_UID_4, 10);
+
+ // CALLING_PACKAGE_3 / LAUNCHER_3 are not backup target.
+ updatePackageInfo(CALLING_PACKAGE_3,
+ pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
+ updatePackageInfo(LAUNCHER_3,
+ pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
+
+ mUninstalledPackages = new HashSet<>();
+
+ mInjectedFilePathRoot = new File(getTestContext().getCacheDir(), "test-files");
+
+ deleteAllSavedFiles();
+
+ // Set up users.
+ doAnswer(inv -> {
+ assertSystem();
+ return USER_INFO_0;
+ }).when(mMockUserManager).getUserInfo(eq(USER_0));
+
+ doAnswer(inv -> {
+ assertSystem();
+ return USER_INFO_10;
+ }).when(mMockUserManager).getUserInfo(eq(USER_10));
+
+ doAnswer(inv -> {
+ assertSystem();
+ return USER_INFO_11;
+ }).when(mMockUserManager).getUserInfo(eq(USER_11));
+
+ doAnswer(inv -> {
+ assertSystem();
+ return USER_INFO_P0;
+ }).when(mMockUserManager).getUserInfo(eq(USER_P0));
+
+ // User 0 is always running.
+ when(mMockUserManager.isUserRunning(eq(USER_0))).thenAnswer(new AnswerIsUserRunning(true));
+
+ initService();
+ setCaller(CALLING_PACKAGE_1);
+
+ // In order to complicate the situation, we set mLocaleChangeSequenceNumber to 1 by
+ // calling this. Running test with mLocaleChangeSequenceNumber == 0 might make us miss
+ // some edge cases.
+ mInternal.onSystemLocaleChangedNoLock();
+ }
+
+ /**
+ * Returns a boolean but also checks if the current UID is SYSTEM_UID.
+ */
+ protected class AnswerIsUserRunning implements Answer<Boolean> {
+ protected final boolean mAnswer;
+
+ protected AnswerIsUserRunning(boolean answer) {
+ mAnswer = answer;
+ }
+
+ @Override
+ public Boolean answer(InvocationOnMock invocation) throws Throwable {
+ assertEquals("isUserRunning() must be called on SYSTEM UID.",
+ Process.SYSTEM_UID, mInjectedCallingUid);
+ return mAnswer;
+ }
+ }
+
+ protected static UserInfo withProfileGroupId(UserInfo in, int groupId) {
+ in.profileGroupId = groupId;
+ return in;
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+ if (DUMP_IN_TEARDOWN) dumpsysOnLogcat("Teardown");
+
+ shutdownServices();
+
+ super.tearDown();
+ }
+
+ protected Context getTestContext() {
+ return getInstrumentation().getContext();
+ }
+
+ protected void deleteAllSavedFiles() {
+ // Empty the data directory.
+ if (mInjectedFilePathRoot.exists()) {
+ Assert.assertTrue("failed to delete dir",
+ FileUtils.deleteContents(mInjectedFilePathRoot));
+ }
+ mInjectedFilePathRoot.mkdirs();
+ }
+
+ /** (Re-) init the manager and the service. */
+ protected void initService() {
+ shutdownServices();
+
+ LocalServices.removeServiceForTest(ShortcutServiceInternal.class);
+
+ // Instantiate targets.
+ mService = new ShortcutServiceTestable(mServiceContext, Looper.getMainLooper());
+ mManager = new ShortcutManagerTestable(mClientContext, mService);
+
+ mInternal = LocalServices.getService(ShortcutServiceInternal.class);
+
+ mLauncherAppImpl = new LauncherAppImplTestable(mServiceContext);
+ mLauncherApps = null;
+ mLauncherAppsMap.clear();
+
+ // Load the setting file.
+ mService.onBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
+ }
+
+ protected void shutdownServices() {
+ if (mService != null) {
+ // Flush all the unsaved data from the previous instance.
+ mService.saveDirtyInfo();
+ }
+ LocalServices.removeServiceForTest(ShortcutServiceInternal.class);
+
+ mService = null;
+ mManager = null;
+ mInternal = null;
+ mLauncherAppImpl = null;
+ mLauncherApps = null;
+ mLauncherAppsMap.clear();
+ }
+
+ protected void addPackage(String packageName, int uid, int version) {
+ addPackage(packageName, uid, version, packageName);
+ }
+
+ protected Signature[] genSignatures(String... signatures) {
+ final Signature[] sigs = new Signature[signatures.length];
+ for (int i = 0; i < signatures.length; i++){
+ sigs[i] = new Signature(signatures[i].getBytes());
+ }
+ return sigs;
+ }
+
+ protected PackageInfo genPackage(String packageName, int uid, int version, String... signatures) {
+ final PackageInfo pi = new PackageInfo();
+ pi.packageName = packageName;
+ pi.applicationInfo = new ApplicationInfo();
+ pi.applicationInfo.uid = uid;
+ pi.applicationInfo.flags = ApplicationInfo.FLAG_INSTALLED
+ | ApplicationInfo.FLAG_ALLOW_BACKUP;
+ pi.versionCode = version;
+ pi.applicationInfo.versionCode = version;
+ pi.signatures = genSignatures(signatures);
+
+ return pi;
+ }
+
+ protected void addPackage(String packageName, int uid, int version, String... signatures) {
+ mInjectedPackages.put(packageName, genPackage(packageName, uid, version, signatures));
+ }
+
+ protected void updatePackageInfo(String packageName, Consumer<PackageInfo> c) {
+ c.accept(mInjectedPackages.get(packageName));
+ }
+
+ protected void updatePackageVersion(String packageName, int increment) {
+ updatePackageInfo(packageName, pi -> {
+ pi.versionCode += increment;
+ pi.applicationInfo.versionCode += increment;
+ });
+ }
+
+ protected void updatePackageLastUpdateTime(String packageName, long increment) {
+ updatePackageInfo(packageName, pi -> {
+ pi.lastUpdateTime += increment;
+ });
+ }
+
+ protected void uninstallPackage(int userId, String packageName) {
+ if (ENABLE_DUMP) {
+ Log.v(TAG, "Unnstall package " + packageName + " / " + userId);
+ }
+ mUninstalledPackages.add(PackageWithUser.of(userId, packageName));
+ }
+
+ protected void installPackage(int userId, String packageName) {
+ if (ENABLE_DUMP) {
+ Log.v(TAG, "Install package " + packageName + " / " + userId);
+ }
+ mUninstalledPackages.remove(PackageWithUser.of(userId, packageName));
+ }
+
+ PackageInfo getInjectedPackageInfo(String packageName, @UserIdInt int userId,
+ boolean getSignatures) {
+ final PackageInfo pi = mInjectedPackages.get(packageName);
+ if (pi == null) return null;
+
+ final PackageInfo ret = new PackageInfo();
+ ret.packageName = pi.packageName;
+ ret.versionCode = pi.versionCode;
+ ret.lastUpdateTime = pi.lastUpdateTime;
+
+ ret.applicationInfo = new ApplicationInfo(pi.applicationInfo);
+ ret.applicationInfo.uid = UserHandle.getUid(userId, pi.applicationInfo.uid);
+ ret.applicationInfo.packageName = pi.packageName;
+
+ if (mUninstalledPackages.contains(PackageWithUser.of(userId, packageName))) {
+ ret.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
+ }
+
+ if (getSignatures) {
+ ret.signatures = pi.signatures;
+ }
+
+ return ret;
+ }
+
+ protected void addApplicationInfo(PackageInfo pi, List<ApplicationInfo> list) {
+ if (pi != null && pi.applicationInfo != null) {
+ list.add(pi.applicationInfo);
+ }
+ }
+
+ protected List<ApplicationInfo> getInstalledApplications(int userId) {
+ final ArrayList<ApplicationInfo> ret = new ArrayList<>();
+
+ addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_1, userId, false), ret);
+ addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_2, userId, false), ret);
+ addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_3, userId, false), ret);
+ addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_4, userId, false), ret);
+ addApplicationInfo(getInjectedPackageInfo(LAUNCHER_1, userId, false), ret);
+ addApplicationInfo(getInjectedPackageInfo(LAUNCHER_2, userId, false), ret);
+ addApplicationInfo(getInjectedPackageInfo(LAUNCHER_3, userId, false), ret);
+ addApplicationInfo(getInjectedPackageInfo(LAUNCHER_4, userId, false), ret);
+
+ return ret;
+ }
+
+ protected void addManifestShortcutResource(ComponentName activity, int resId) {
+ final String packageName = activity.getPackageName();
+ LinkedHashMap<ComponentName, Integer> map = mActivityMetadataResId.get(packageName);
+ if (map == null) {
+ map = new LinkedHashMap<>();
+ mActivityMetadataResId.put(packageName, map);
+ }
+ map.put(activity, resId);
+ }
+
+ protected PackageInfo injectGetActivitiesWithMetadata(String packageName, @UserIdInt int userId) {
+ final PackageInfo ret = getInjectedPackageInfo(packageName, userId,
+ /* getSignatures=*/ false);
+
+ final HashMap<ComponentName, Integer> activities = mActivityMetadataResId.get(packageName);
+ if (activities != null) {
+ final ArrayList<ActivityInfo> list = new ArrayList<>();
+
+ for (ComponentName cn : activities.keySet()) {
+ ActivityInfo ai = new ActivityInfo();
+ ai.packageName = cn.getPackageName();
+ ai.name = cn.getClassName();
+ ai.metaData = new Bundle();
+ ai.metaData.putInt(ShortcutParser.METADATA_KEY, activities.get(cn));
+ list.add(ai);
+ }
+ ret.activities = list.toArray(new ActivityInfo[list.size()]);
+ }
+ return ret;
+ }
+
+ protected XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
+ if (!ShortcutParser.METADATA_KEY.equals(key) || activityInfo.metaData == null) {
+ return null;
+ }
+ final int resId = activityInfo.metaData.getInt(key);
+ return getTestContext().getResources().getXml(resId);
+ }
+
+ /** Replace the current calling package */
+ protected void setCaller(String packageName, int userId) {
+ mInjectedClientPackage = packageName;
+ mInjectedCallingUid =
+ Preconditions.checkNotNull(getInjectedPackageInfo(packageName, userId, false),
+ "Unknown package").applicationInfo.uid;
+
+ // Set up LauncherApps for this caller.
+ final Pair<Integer, String> key = Pair.create(userId, packageName);
+ if (!mLauncherAppsMap.containsKey(key)) {
+ mLauncherAppsMap.put(key, new LauncherAppsTestable(mClientContext, mLauncherAppImpl));
+ }
+ mLauncherApps = mLauncherAppsMap.get(key);
+ }
+
+ protected void setCaller(String packageName) {
+ setCaller(packageName, UserHandle.USER_SYSTEM);
+ }
+
+ protected String getCallingPackage() {
+ return mInjectedClientPackage;
+ }
+
+ protected void setDefaultLauncherChecker(BiPredicate<String, Integer> p) {
+ mDefaultLauncherChecker = p;
+ }
+
+ protected void runWithCaller(String packageName, int userId, Runnable r) {
+ final String previousPackage = mInjectedClientPackage;
+ final int previousUserId = UserHandle.getUserId(mInjectedCallingUid);
+
+ setCaller(packageName, userId);
+
+ r.run();
+
+ setCaller(previousPackage, previousUserId);
+ }
+
+ protected int getCallingUserId() {
+ return UserHandle.getUserId(mInjectedCallingUid);
+ }
+
+ protected UserHandle getCallingUser() {
+ return UserHandle.of(getCallingUserId());
+ }
+
+ /** For debugging */
+ protected void dumpsysOnLogcat() {
+ dumpsysOnLogcat("");
+ }
+
+ protected void dumpsysOnLogcat(String message) {
+ dumpsysOnLogcat(message, false);
+ }
+
+ protected void dumpsysOnLogcat(String message, boolean force) {
+ if (force || !ENABLE_DUMP) return;
+
+ final ByteArrayOutputStream out = new ByteArrayOutputStream();
+ final PrintWriter pw = new PrintWriter(out);
+ mService.dumpInner(pw, null);
+ pw.close();
+
+ Log.v(TAG, "Dumping ShortcutService: " + message);
+ for (String line : out.toString().split("\n")) {
+ Log.v(TAG, line);
+ }
+ }
+
+ /**
+ * For debugging, dump arbitrary file on logcat.
+ */
+ protected void dumpFileOnLogcat(String path) {
+ dumpFileOnLogcat(path, "");
+ }
+
+ protected void dumpFileOnLogcat(String path, String message) {
+ if (!ENABLE_DUMP) return;
+
+ Log.v(TAG, "Dumping file: " + path + " " + message);
+ final StringBuilder sb = new StringBuilder();
+ try (BufferedReader br = new BufferedReader(new FileReader(path))) {
+ String line;
+ while ((line = br.readLine()) != null) {
+ Log.v(TAG, line);
+ }
+ } catch (Exception e) {
+ Log.e(TAG, "Couldn't read file", e);
+ fail("Exception " + e);
+ }
+ }
+
+ /**
+ * For debugging, dump the main state file on logcat.
+ */
+ protected void dumpBaseStateFile() {
+ mService.saveDirtyInfo();
+ dumpFileOnLogcat(mInjectedFilePathRoot.getAbsolutePath()
+ + "/system/" + ShortcutService.FILENAME_BASE_STATE);
+ }
+
+ /**
+ * For debugging, dump per-user state file on logcat.
+ */
+ protected void dumpUserFile(int userId) {
+ dumpUserFile(userId, "");
+ }
+
+ protected void dumpUserFile(int userId, String message) {
+ mService.saveDirtyInfo();
+ dumpFileOnLogcat(mInjectedFilePathRoot.getAbsolutePath()
+ + "/user-" + userId
+ + "/" + ShortcutService.FILENAME_USER_PACKAGES, message);
+ }
+
+ protected void waitOnMainThread() throws Throwable {
+ runTestOnUiThread(() -> {});
+ }
+
+ /**
+ * Make a shortcut with an ID.
+ */
+ protected ShortcutInfo makeShortcut(String id) {
+ return makeShortcut(
+ id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
+ }
+
+ protected ShortcutInfo makeShortcutWithTitle(String id, String title) {
+ return makeShortcut(
+ id, title, /* activity =*/ null, /* icon =*/ null,
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
+ }
+
+ /**
+ * Make a shortcut with an ID and timestamp.
+ */
+ protected ShortcutInfo makeShortcutWithTimestamp(String id, long timestamp) {
+ final ShortcutInfo s = makeShortcut(
+ id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
+ s.setTimestamp(timestamp);
+ return s;
+ }
+
+ /**
+ * Make a shortcut with an ID, a timestamp and an activity component
+ */
+ protected ShortcutInfo makeShortcutWithTimestampWithActivity(String id, long timestamp,
+ ComponentName activity) {
+ final ShortcutInfo s = makeShortcut(
+ id, "Title-" + id, activity, /* icon =*/ null,
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
+ s.setTimestamp(timestamp);
+ return s;
+ }
+
+ /**
+ * Make a shortcut with an ID and icon.
+ */
+ protected ShortcutInfo makeShortcutWithIcon(String id, Icon icon) {
+ return makeShortcut(
+ id, "Title-" + id, /* activity =*/ null, icon,
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
+ }
+
+ protected ShortcutInfo makePackageShortcut(String packageName, String id) {
+ String origCaller = getCallingPackage();
+
+ setCaller(packageName);
+ ShortcutInfo s = makeShortcut(
+ id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
+ setCaller(origCaller); // restore the caller
+
+ return s;
+ }
+
+ /**
+ * Make multiple shortcuts with IDs.
+ */
+ protected List<ShortcutInfo> makeShortcuts(String... ids) {
+ final ArrayList<ShortcutInfo> ret = new ArrayList();
+ for (String id : ids) {
+ ret.add(makeShortcut(id));
+ }
+ return ret;
+ }
+
+ protected ShortcutInfo.Builder makeShortcutBuilder() {
+ return new ShortcutInfo.Builder(mClientContext);
+ }
+
+ protected ShortcutInfo makeShortcutWithActivity(String id, ComponentName activity) {
+ return makeShortcut(
+ id, "Title-" + id, activity, /* icon =*/ null,
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
+ }
+
+ protected ShortcutInfo makeShortcutWithActivityAndTitle(String id, ComponentName activity,
+ String title) {
+ return makeShortcut(
+ id, title, activity, /* icon =*/ null,
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* rank =*/ 0);
+ }
+
+ protected ShortcutInfo makeShortcutWithActivityAndRank(String id, ComponentName activity,
+ int rank) {
+ return makeShortcut(
+ id, "Title-" + id, activity, /* icon =*/ null,
+ makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), rank);
+ }
+
+ /**
+ * Make a shortcut with details.
+ */
+ protected ShortcutInfo makeShortcut(String id, String title, ComponentName activity,
+ Icon icon, Intent intent, int rank) {
+ final ShortcutInfo.Builder b = new ShortcutInfo.Builder(mClientContext)
+ .setId(id)
+ .setActivity(new ComponentName(mClientContext.getPackageName(), "dummy"))
+ .setTitle(title)
+ .setRank(rank)
+ .setIntent(intent);
+ if (icon != null) {
+ b.setIcon(icon);
+ }
+ if (activity != null) {
+ b.setActivity(activity);
+ }
+ final ShortcutInfo s = b.build();
+
+ s.setTimestamp(mInjectedCurrentTimeMillis); // HACK
+
+ return s;
+ }
+
+ /**
+ * Make an intent.
+ */
+ protected Intent makeIntent(String action, Class<?> clazz, Object... bundleKeysAndValues) {
+ final Intent intent = new Intent(action);
+ intent.setComponent(makeComponent(clazz));
+ intent.replaceExtras(makeBundle(bundleKeysAndValues));
+ return intent;
+ }
+
+ /**
+ * Make an component name, with the client context.
+ */
+ @NonNull
+ protected ComponentName makeComponent(Class<?> clazz) {
+ return new ComponentName(mClientContext, clazz);
+ }
+
+ @NonNull
+ protected ShortcutInfo findById(List<ShortcutInfo> list, String id) {
+ for (ShortcutInfo s : list) {
+ if (s.getId().equals(id)) {
+ return s;
+ }
+ }
+ fail("Shortcut with id " + id + " not found");
+ return null;
+ }
+
+ protected void assertSystem() {
+ assertEquals("Caller must be system", Process.SYSTEM_UID, mInjectedCallingUid);
+ }
+
+ protected void assertResetTimes(long expectedLastResetTime, long expectedNextResetTime) {
+ assertEquals(expectedLastResetTime, mService.getLastResetTimeLocked());
+ assertEquals(expectedNextResetTime, mService.getNextResetTimeLocked());
+ }
+
+ public static List<ShortcutInfo> assertAllNotHaveIcon(
+ List<ShortcutInfo> actualShortcuts) {
+ for (ShortcutInfo s : actualShortcuts) {
+ assertNull("ID " + s.getId(), s.getIcon());
+ }
+ return actualShortcuts;
+ }
+
+ @NonNull
+ protected List<ShortcutInfo> assertAllHaveFlags(@NonNull List<ShortcutInfo> actualShortcuts,
+ int shortcutFlags) {
+ for (ShortcutInfo s : actualShortcuts) {
+ assertTrue("ID " + s.getId() + " doesn't have flags " + shortcutFlags,
+ s.hasFlags(shortcutFlags));
+ }
+ return actualShortcuts;
+ }
+
+ protected ShortcutInfo getPackageShortcut(String packageName, String shortcutId, int userId) {
+ return mService.getPackageShortcutForTest(packageName, shortcutId, userId);
+ }
+
+ protected void assertShortcutExists(String packageName, String shortcutId, int userId) {
+ assertTrue(getPackageShortcut(packageName, shortcutId, userId) != null);
+ }
+
+ protected void assertShortcutNotExists(String packageName, String shortcutId, int userId) {
+ assertTrue(getPackageShortcut(packageName, shortcutId, userId) == null);
+ }
+
+ protected Intent launchShortcutAndGetIntent(
+ @NonNull String packageName, @NonNull String shortcutId, int userId) {
+ reset(mServiceContext);
+ assertTrue(mLauncherApps.startShortcut(packageName, shortcutId, null, null,
+ UserHandle.of(userId)));
+
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mServiceContext).startActivityAsUser(
+ intentCaptor.capture(),
+ any(Bundle.class),
+ eq(UserHandle.of(userId)));
+ return intentCaptor.getValue();
+ }
+
+ protected Intent launchShortcutAndGetIntent_withShortcutInfo(
+ @NonNull String packageName, @NonNull String shortcutId, int userId) {
+ reset(mServiceContext);
+
+ assertTrue(mLauncherApps.startShortcut(
+ getShortcutInfoAsLauncher(packageName, shortcutId, userId), null, null));
+
+ final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
+ verify(mServiceContext).startActivityAsUser(
+ intentCaptor.capture(),
+ any(Bundle.class),
+ eq(UserHandle.of(userId)));
+ return intentCaptor.getValue();
+ }
+
+ protected void assertShortcutLaunchable(@NonNull String packageName, @NonNull String shortcutId,
+ int userId) {
+ assertNotNull(launchShortcutAndGetIntent(packageName, shortcutId, userId));
+ assertNotNull(launchShortcutAndGetIntent_withShortcutInfo(packageName, shortcutId, userId));
+ }
+
+ protected void assertShortcutNotLaunchable(@NonNull String packageName,
+ @NonNull String shortcutId, int userId) {
+ try {
+ final boolean ok = mLauncherApps.startShortcut(packageName, shortcutId, null, null,
+ UserHandle.of(userId));
+ if (!ok) {
+ return; // didn't launch, okay.
+ }
+ fail();
+ } catch (SecurityException expected) {
+ // security exception is okay too.
+ }
+ }
+
+ protected void assertBitmapDirectories(int userId, String... expectedDirectories) {
+ final Set<String> expected = hashSet(set(expectedDirectories));
+
+ final Set<String> actual = new HashSet<>();
+
+ final File[] files = mService.getUserBitmapFilePath(userId).listFiles();
+ if (files != null) {
+ for (File child : files) {
+ if (child.isDirectory()) {
+ actual.add(child.getName());
+ }
+ }
+ }
+
+ assertEquals(expected, actual);
+ }
+
+ protected void assertBitmapFiles(int userId, String packageName, String... expectedFiles) {
+ final Set<String> expected = hashSet(set(expectedFiles));
+
+ final Set<String> actual = new HashSet<>();
+
+ final File[] files = new File(mService.getUserBitmapFilePath(userId), packageName)
+ .listFiles();
+ if (files != null) {
+ for (File child : files) {
+ if (child.isFile()) {
+ actual.add(child.getName());
+ }
+ }
+ }
+
+ assertEquals(expected, actual);
+ }
+
+ protected String getBitmapFilename(int userId, String packageName, String shortcutId) {
+ final ShortcutInfo si = mService.getPackageShortcutForTest(packageName, shortcutId, userId);
+ if (si == null) {
+ return null;
+ }
+ return new File(si.getBitmapPath()).getName();
+ }
+
+ protected List<ShortcutInfo> getCallerShortcuts() {
+ final ShortcutPackage p = mService.getPackageShortcutForTest(
+ getCallingPackage(), getCallingUserId());
+ return p == null ? null : p.getAllShortcutsForTest();
+ }
+
+ protected ShortcutInfo getCallerShortcut(String shortcutId) {
+ return getPackageShortcut(getCallingPackage(), shortcutId, getCallingUserId());
+ }
+
+ protected List<ShortcutInfo> getLauncherShortcuts(String launcher, int userId, int queryFlags) {
+ final List<ShortcutInfo>[] ret = new List[1];
+ runWithCaller(launcher, userId, () -> {
+ final ShortcutQuery q = new ShortcutQuery();
+ q.setQueryFlags(queryFlags);
+ ret[0] = mLauncherApps.getShortcuts(q, UserHandle.of(userId));
+ });
+ return ret[0];
+ }
+
+ protected List<ShortcutInfo> getLauncherPinnedShortcuts(String launcher, int userId) {
+ return getLauncherShortcuts(launcher, userId, ShortcutQuery.FLAG_GET_PINNED);
+ }
+
+ protected ShortcutInfo getShortcutInfoAsLauncher(String packageName, String shortcutId,
+ int userId) {
+ final List<ShortcutInfo> infoList =
+ mLauncherApps.getShortcutInfo(packageName, list(shortcutId),
+ UserHandle.of(userId));
+ assertEquals("No shortcutInfo found (or too many of them)", 1, infoList.size());
+ return infoList.get(0);
+ }
+
+ protected Intent genPackageAddIntent(String pakcageName, int userId) {
+ Intent i = new Intent(Intent.ACTION_PACKAGE_ADDED);
+ i.setData(Uri.parse("package:" + pakcageName));
+ i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ return i;
+ }
+
+ protected Intent genPackageDeleteIntent(String pakcageName, int userId) {
+ Intent i = new Intent(Intent.ACTION_PACKAGE_REMOVED);
+ i.setData(Uri.parse("package:" + pakcageName));
+ i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ return i;
+ }
+
+ protected Intent genPackageUpdateIntent(String pakcageName, int userId) {
+ Intent i = new Intent(Intent.ACTION_PACKAGE_ADDED);
+ i.setData(Uri.parse("package:" + pakcageName));
+ i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ i.putExtra(Intent.EXTRA_REPLACING, true);
+ return i;
+ }
+
+ protected Intent genPackageDataClear(String packageName, int userId) {
+ Intent i = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED);
+ i.setData(Uri.parse("package:" + packageName));
+ i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
+ return i;
+ }
+
+ protected void assertExistsAndShadow(ShortcutPackageItem spi) {
+ assertNotNull(spi);
+ assertTrue(spi.getPackageInfo().isShadow());
+ }
+
+ protected File makeFile(File baseDirectory, String... paths) {
+ File ret = baseDirectory;
+
+ for (String path : paths) {
+ ret = new File(ret, path);
+ }
+
+ return ret;
+ }
+
+ protected boolean bitmapDirectoryExists(String packageName, int userId) {
+ final File path = new File(mService.getUserBitmapFilePath(userId), packageName);
+ return path.isDirectory();
+ }
+ protected static ShortcutQuery buildQuery(long changedSince,
+ String packageName, ComponentName componentName,
+ /* @ShortcutQuery.QueryFlags */ int flags) {
+ return buildQuery(changedSince, packageName, null, componentName, flags);
+ }
+
+ protected static ShortcutQuery buildQuery(long changedSince,
+ String packageName, List<String> shortcutIds, ComponentName componentName,
+ /* @ShortcutQuery.QueryFlags */ int flags) {
+ final ShortcutQuery q = new ShortcutQuery();
+ q.setChangedSince(changedSince);
+ q.setPackage(packageName);
+ q.setShortcutIds(shortcutIds);
+ q.setActivity(componentName);
+ q.setQueryFlags(flags);
+ return q;
+ }
+
+ protected static ShortcutQuery buildAllQuery(String packageName) {
+ final ShortcutQuery q = new ShortcutQuery();
+ q.setPackage(packageName);
+ q.setQueryFlags(ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED);
+ return q;
+ }
+
+ protected static ShortcutQuery buildPinnedQuery(String packageName) {
+ final ShortcutQuery q = new ShortcutQuery();
+ q.setPackage(packageName);
+ q.setQueryFlags(ShortcutQuery.FLAG_GET_PINNED);
+ return q;
+ }
+
+ protected void backupAndRestore() {
+ int prevUid = mInjectedCallingUid;
+
+ mInjectedCallingUid = Process.SYSTEM_UID; // Only system can call it.
+
+ dumpsysOnLogcat("Before backup");
+
+ final byte[] payload = mService.getBackupPayload(USER_0);
+ if (ENABLE_DUMP) {
+ final String xml = new String(payload);
+ Log.v(TAG, "Backup payload:");
+ for (String line : xml.split("\n")) {
+ Log.v(TAG, line);
+ }
+ }
+
+ // Before doing anything else, uninstall all packages.
+ for (int userId : list(USER_0, USER_P0)) {
+ for (String pkg : list(CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3,
+ LAUNCHER_1, LAUNCHER_2, LAUNCHER_3)) {
+ uninstallPackage(userId, pkg);
+ }
+ }
+
+ shutdownServices();
+
+ deleteAllSavedFiles();
+
+ initService();
+ mService.applyRestore(payload, USER_0);
+
+ // handleUnlockUser will perform the gone package check, but it shouldn't remove
+ // shadow information.
+ mService.handleUnlockUser(USER_0);
+
+ dumpsysOnLogcat("After restore");
+
+ mInjectedCallingUid = prevUid;
+ }
+
+ protected void prepareCrossProfileDataSet() {
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
+ makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
+ makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
+ makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list()));
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
+ makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("x1"), makeShortcut("x2"), makeShortcut("x3"),
+ makeShortcut("x4"), makeShortcut("x5"), makeShortcut("x6"))));
+ });
+
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s1", "s2"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s1", "s2", "s3"), HANDLE_USER_0);
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s4"), HANDLE_USER_P0);
+ });
+ runWithCaller(LAUNCHER_2, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s2", "s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s2", "s3", "s4"), HANDLE_USER_0);
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s5"), HANDLE_USER_P0);
+ });
+ runWithCaller(LAUNCHER_3, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s3", "s4", "s5"), HANDLE_USER_0);
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3", "s6"), HANDLE_USER_P0);
+ });
+ runWithCaller(LAUNCHER_4, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list(), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_4, list(), HANDLE_USER_0);
+ });
+
+ // Launcher on a managed profile is referring ot user 0!
+ runWithCaller(LAUNCHER_1, USER_P0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3", "s4"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4", "s5"), HANDLE_USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s3", "s4", "s5", "s6"),
+ HANDLE_USER_0);
+
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s4", "s1"), HANDLE_USER_P0);
+ });
+ runWithCaller(LAUNCHER_1, USER_10, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("x4", "x5"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("x4", "x5", "x6"), HANDLE_USER_10);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("x4", "x5", "x6", "x1"),
+ HANDLE_USER_10);
+ });
+
+ // Then remove some dynamic shortcuts.
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list()));
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ assertTrue(mManager.setDynamicShortcuts(list(
+ makeShortcut("x1"), makeShortcut("x2"), makeShortcut("x3"))));
+ });
+ }
+}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
similarity index 67%
rename from services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
rename to services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
index 1a0a003..c11be7a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest1.java
@@ -41,9 +41,11 @@
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertCannotUpdateImmutable;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicAndPinned;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicOnly;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertDynamicShortcutCountExceeded;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertEmpty;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertShortcutIds;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.filterByActivity;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.findShortcut;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.hashSet;
import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
@@ -59,89 +61,40 @@
import static org.mockito.Mockito.doAnswer;
import static org.mockito.Mockito.mock;
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;
import android.Manifest.permission;
-import android.annotation.NonNull;
-import android.annotation.Nullable;
-import android.annotation.RequiresPermission;
-import android.annotation.UserIdInt;
-import android.app.Activity;
-import android.app.ActivityManager;
-import android.app.IUidObserver;
-import android.content.BroadcastReceiver;
import android.content.ComponentName;
-import android.content.Context;
import android.content.Intent;
-import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
-import android.content.pm.ILauncherApps;
import android.content.pm.LauncherApps;
import android.content.pm.LauncherApps.ShortcutQuery;
-import android.content.pm.PackageInfo;
-import android.content.pm.PackageManager;
-import android.content.pm.PackageManagerInternal;
import android.content.pm.ShortcutInfo;
-import android.content.pm.ShortcutManager;
-import android.content.pm.ShortcutServiceInternal;
-import android.content.pm.Signature;
-import android.content.pm.UserInfo;
import android.content.res.Resources;
-import android.content.res.XmlResourceParser;
import android.graphics.Bitmap;
import android.graphics.Bitmap.CompressFormat;
import android.graphics.BitmapFactory;
import android.graphics.drawable.Icon;
import android.net.Uri;
-import android.os.Bundle;
-import android.os.FileUtils;
import android.os.Handler;
import android.os.Looper;
-import android.os.Parcel;
-import android.os.PersistableBundle;
import android.os.Process;
import android.os.UserHandle;
-import android.os.UserManager;
-import android.test.InstrumentationTestCase;
-import android.test.MoreAsserts;
-import android.test.mock.MockContext;
import android.test.suitebuilder.annotation.SmallTest;
import android.util.Log;
-import android.util.Pair;
import android.util.SparseArray;
import com.android.frameworks.servicestests.R;
-import com.android.internal.util.Preconditions;
-import com.android.server.LocalServices;
-import com.android.server.SystemService;
-import com.android.server.pm.LauncherAppsService.LauncherAppsImpl;
import com.android.server.pm.ShortcutService.ConfigConstants;
import com.android.server.pm.ShortcutService.FileOutputStreamWithPath;
import com.android.server.pm.ShortcutUser.PackageWithUser;
-import org.junit.Assert;
import org.mockito.ArgumentCaptor;
-import org.mockito.invocation.InvocationOnMock;
-import org.mockito.stubbing.Answer;
-import java.io.BufferedReader;
-import java.io.ByteArrayOutputStream;
import java.io.File;
-import java.io.FileReader;
import java.io.IOException;
-import java.io.PrintWriter;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.HashSet;
import java.util.List;
-import java.util.Map;
-import java.util.Set;
-import java.util.function.BiPredicate;
-import java.util.function.Consumer;
/**
* Tests for ShortcutService and ShortcutManager.
@@ -149,7 +102,7 @@
m FrameworksServicesTests &&
adb install \
-r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
- adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest \
+ adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest1 \
-w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
@@ -162,1156 +115,7 @@
* TODO: Add tests for the command line functions too.
*/
@SmallTest
-public class ShortcutManagerTest extends InstrumentationTestCase {
- private static final String TAG = "ShortcutManagerTest";
-
- /**
- * Whether to enable dump or not. Should be only true when debugging to avoid bugs where
- * dump affecting the behavior.
- */
- private static final boolean ENABLE_DUMP = true; // DO NOT SUBMIT WITH true
-
- private static final boolean DUMP_IN_TEARDOWN = true; // DO NOT SUBMIT WITH true
-
- private static final String[] EMPTY_STRINGS = new String[0]; // Just for readability.
-
- // public for mockito
- public class BaseContext extends MockContext {
- @Override
- public Object getSystemService(String name) {
- switch (name) {
- case Context.USER_SERVICE:
- return mMockUserManager;
- }
- throw new UnsupportedOperationException();
- }
-
- @Override
- public String getSystemServiceName(Class<?> serviceClass) {
- return getTestContext().getSystemServiceName(serviceClass);
- }
-
- @Override
- public PackageManager getPackageManager() {
- return mMockPackageManager;
- }
-
- @Override
- public Resources getResources() {
- return getTestContext().getResources();
- }
-
- @Override
- public Intent registerReceiverAsUser(BroadcastReceiver receiver, UserHandle user,
- IntentFilter filter, String broadcastPermission, Handler scheduler) {
- // ignore.
- return null;
- }
- }
-
- /** Context used in the client side */
- public class ClientContext extends BaseContext {
- @Override
- public String getPackageName() {
- return mInjectedClientPackage;
- }
-
- @Override
- public int getUserId() {
- return getCallingUserId();
- }
- }
-
- /** Context used in the service side */
- public class ServiceContext extends BaseContext {
- long injectClearCallingIdentity() {
- final int prevCallingUid = mInjectedCallingUid;
- mInjectedCallingUid = Process.SYSTEM_UID;
- return prevCallingUid;
- }
-
- void injectRestoreCallingIdentity(long token) {
- mInjectedCallingUid = (int) token;
- }
-
- @Override
- public void startActivityAsUser(@RequiresPermission Intent intent, @Nullable Bundle options,
- UserHandle userId) {
- }
-
- @Override
- public int getUserId() {
- return UserHandle.USER_SYSTEM;
- }
-
- public PackageInfo injectGetActivitiesWithMetadata(
- String packageName, @UserIdInt int userId) {
- return ShortcutManagerTest.this.injectGetActivitiesWithMetadata(packageName, userId);
- }
-
- public XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
- return ShortcutManagerTest.this.injectXmlMetaData(activityInfo, key);
- }
- }
-
- /** ShortcutService with injection override methods. */
- private final class ShortcutServiceTestable extends ShortcutService {
- final ServiceContext mContext;
- IUidObserver mUidObserver;
-
- public ShortcutServiceTestable(ServiceContext context, Looper looper) {
- super(context, looper);
- mContext = context;
- }
-
- @Override
- String injectShortcutManagerConstants() {
- return ConfigConstants.KEY_RESET_INTERVAL_SEC + "=" + (INTERVAL / 1000) + ","
- + ConfigConstants.KEY_MAX_SHORTCUTS + "=" + MAX_SHORTCUTS + ","
- + ConfigConstants.KEY_MAX_UPDATES_PER_INTERVAL + "="
- + MAX_UPDATES_PER_INTERVAL + ","
- + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP + "=" + MAX_ICON_DIMENSION + ","
- + ConfigConstants.KEY_MAX_ICON_DIMENSION_DP_LOWRAM + "="
- + MAX_ICON_DIMENSION_LOWRAM + ","
- + ConfigConstants.KEY_ICON_FORMAT + "=PNG,"
- + ConfigConstants.KEY_ICON_QUALITY + "=100";
- }
-
- @Override
- long injectClearCallingIdentity() {
- return mContext.injectClearCallingIdentity();
- }
-
- @Override
- void injectRestoreCallingIdentity(long token) {
- mContext.injectRestoreCallingIdentity(token);
- }
-
- @Override
- int injectDipToPixel(int dip) {
- return dip;
- }
-
- @Override
- long injectCurrentTimeMillis() {
- return mInjectedCurrentTimeLillis;
- }
-
- @Override
- long injectElapsedRealtime() {
- // TODO This should be kept separately from mInjectedCurrentTimeLillis, since
- // this should increase even if we rewind mInjectedCurrentTimeLillis in some tests.
- return mInjectedCurrentTimeLillis - START_TIME;
- }
-
- @Override
- int injectBinderCallingUid() {
- return mInjectedCallingUid;
- }
-
- @Override
- int injectGetPackageUid(String packageName, int userId) {
- return getInjectedPackageInfo(packageName, userId, false).applicationInfo.uid;
- }
-
- @Override
- File injectSystemDataPath() {
- return new File(mInjectedFilePathRoot, "system");
- }
-
- @Override
- File injectUserDataPath(@UserIdInt int userId) {
- return new File(mInjectedFilePathRoot, "user-" + userId);
- }
-
- @Override
- void injectValidateIconResPackage(ShortcutInfo shortcut, Icon icon) {
- // Can't check
- }
-
- @Override
- boolean injectIsLowRamDevice() {
- return mInjectedIsLowRamDevice;
- }
-
- @Override
- void injectRegisterUidObserver(IUidObserver observer, int which) {
- mUidObserver = observer;
- }
-
- @Override
- PackageManagerInternal injectPackageManagerInternal() {
- return mMockPackageManagerInternal;
- }
-
- @Override
- boolean hasShortcutHostPermission(@NonNull String callingPackage, int userId) {
- return mDefaultLauncherChecker.test(callingPackage, userId);
- }
-
- @Override
- PackageInfo injectPackageInfo(String packageName, @UserIdInt int userId,
- boolean getSignatures) {
- return getInjectedPackageInfo(packageName, userId, getSignatures);
- }
-
- @Override
- ApplicationInfo injectApplicationInfo(String packageName, @UserIdInt int userId) {
- PackageInfo pi = injectPackageInfo(packageName, userId, /* getSignatures= */ false);
- return pi != null ? pi.applicationInfo : null;
- }
-
- @Override
- List<ApplicationInfo> injectInstalledApplications(@UserIdInt int userId) {
- return getInstalledApplications(userId);
- }
-
- @Override
- PackageInfo injectGetActivitiesWithMetadata(String packageName, @UserIdInt int userId) {
- return mContext.injectGetActivitiesWithMetadata(packageName, userId);
- }
-
- @Override
- XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
- return mContext.injectXmlMetaData(activityInfo, key);
- }
-
- @Override
- void postToHandler(Runnable r) {
- final long token = mContext.injectClearCallingIdentity();
- r.run();
- mContext.injectRestoreCallingIdentity(token);
- }
-
- @Override
- void injectEnforceCallingPermission(String permission, String message) {
- if (!mCallerPermissions.contains(permission)) {
- throw new SecurityException("Missing permission: " + permission);
- }
- }
-
- @Override
- void wtf(String message, Exception e) {
- // During tests, WTF is fatal.
- fail(message + " exception: " + e);
- }
- }
-
- /** ShortcutManager with injection override methods. */
- private class ShortcutManagerTestable extends ShortcutManager {
- public ShortcutManagerTestable(Context context, ShortcutServiceTestable service) {
- super(context, service);
- }
-
- @Override
- protected int injectMyUserId() {
- return UserHandle.getUserId(mInjectedCallingUid);
- }
- }
-
- private class LauncherAppImplTestable extends LauncherAppsImpl {
- final ServiceContext mContext;
-
- public LauncherAppImplTestable(ServiceContext context) {
- super(context);
- mContext = context;
- }
-
- @Override
- public void verifyCallingPackage(String callingPackage) {
- // SKIP
- }
-
- @Override
- void postToPackageMonitorHandler(Runnable r) {
- final long token = mContext.injectClearCallingIdentity();
- r.run();
- mContext.injectRestoreCallingIdentity(token);
- }
-
- @Override
- int injectBinderCallingUid() {
- return mInjectedCallingUid;
- }
-
- @Override
- long injectClearCallingIdentity() {
- final int prevCallingUid = mInjectedCallingUid;
- mInjectedCallingUid = Process.SYSTEM_UID;
- return prevCallingUid;
- }
-
- @Override
- void injectRestoreCallingIdentity(long token) {
- mInjectedCallingUid = (int) token;
- }
- }
-
- private class LauncherAppsTestable extends LauncherApps {
- public LauncherAppsTestable(Context context, ILauncherApps service) {
- super(context, service);
- }
- }
-
- public static class ShortcutActivity extends Activity {
- }
-
- public static class ShortcutActivity2 extends Activity {
- }
-
- public static class ShortcutActivity3 extends Activity {
- }
-
- private ServiceContext mServiceContext;
- private ClientContext mClientContext;
-
- private ShortcutServiceTestable mService;
- private ShortcutManagerTestable mManager;
- private ShortcutServiceInternal mInternal;
-
- private LauncherAppImplTestable mLauncherAppImpl;
-
- // LauncherApps has per-instace state, so we need a differnt instance for each launcher.
- private final Map<Pair<Integer, String>, LauncherAppsTestable>
- mLauncherAppsMap = new HashMap<>();
- private LauncherAppsTestable mLauncherApps; // Current one
-
- private File mInjectedFilePathRoot;
-
- private long mInjectedCurrentTimeLillis;
-
- private boolean mInjectedIsLowRamDevice;
-
- private int mInjectedCallingUid;
- private String mInjectedClientPackage;
-
- private Map<String, PackageInfo> mInjectedPackages;
-
- private Set<PackageWithUser> mUninstalledPackages;
-
- private PackageManager mMockPackageManager;
- private PackageManagerInternal mMockPackageManagerInternal;
- private UserManager mMockUserManager;
-
- private static final String CALLING_PACKAGE_1 = "com.android.test.1";
- private static final int CALLING_UID_1 = 10001;
-
- private static final String CALLING_PACKAGE_2 = "com.android.test.2";
- private static final int CALLING_UID_2 = 10002;
-
- private static final String CALLING_PACKAGE_3 = "com.android.test.3";
- private static final int CALLING_UID_3 = 10003;
-
- private static final String CALLING_PACKAGE_4 = "com.android.test.4";
- private static final int CALLING_UID_4 = 10004;
-
- private static final String LAUNCHER_1 = "com.android.launcher.1";
- private static final int LAUNCHER_UID_1 = 10011;
-
- private static final String LAUNCHER_2 = "com.android.launcher.2";
- private static final int LAUNCHER_UID_2 = 10012;
-
- private static final String LAUNCHER_3 = "com.android.launcher.3";
- private static final int LAUNCHER_UID_3 = 10013;
-
- private static final String LAUNCHER_4 = "com.android.launcher.4";
- private static final int LAUNCHER_UID_4 = 10014;
-
- private static final int USER_0 = UserHandle.USER_SYSTEM;
- private static final int USER_10 = 10;
- private static final int USER_11 = 11;
- private static final int USER_P0 = 20; // profile of user 0
-
- private static final UserHandle HANDLE_USER_0 = UserHandle.of(USER_0);
- private static final UserHandle HANDLE_USER_10 = UserHandle.of(USER_10);
- private static final UserHandle HANDLE_USER_11 = UserHandle.of(USER_11);
- private static final UserHandle HANDLE_USER_P0 = UserHandle.of(USER_P0);
-
- private static final UserInfo USER_INFO_0 = withProfileGroupId(
- new UserInfo(USER_0, "user0",
- UserInfo.FLAG_ADMIN | UserInfo.FLAG_PRIMARY | UserInfo.FLAG_INITIALIZED), 10);
-
- private static final UserInfo USER_INFO_10 =
- new UserInfo(USER_10, "user10", UserInfo.FLAG_INITIALIZED);
-
- private static final UserInfo USER_INFO_11 =
- new UserInfo(USER_11, "user11", UserInfo.FLAG_INITIALIZED);
-
- private static final UserInfo USER_INFO_P0 = withProfileGroupId(
- new UserInfo(USER_P0, "userP0",
- UserInfo.FLAG_MANAGED_PROFILE), 10);
-
- private BiPredicate<String, Integer> mDefaultLauncherChecker =
- (callingPackage, userId) ->
- LAUNCHER_1.equals(callingPackage) || LAUNCHER_2.equals(callingPackage)
- || LAUNCHER_3.equals(callingPackage) || LAUNCHER_4.equals(callingPackage);
-
- private static final long START_TIME = 1440000000101L;
-
- private static final long INTERVAL = 10000;
-
- private static final int MAX_SHORTCUTS = 10;
-
- private static final int MAX_UPDATES_PER_INTERVAL = 3;
-
- private static final int MAX_ICON_DIMENSION = 128;
-
- private static final int MAX_ICON_DIMENSION_LOWRAM = 32;
-
- private static final ShortcutQuery QUERY_ALL = new ShortcutQuery();
-
- private final ArrayList<String> mCallerPermissions = new ArrayList<>();
-
- private final HashMap<String, HashMap<ComponentName, Integer>> mActivityMetadataResId
- = new HashMap<>();
-
- static {
- QUERY_ALL.setQueryFlags(
- ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED);
- }
-
- @Override
- protected void setUp() throws Exception {
- super.setUp();
-
- mServiceContext = spy(new ServiceContext());
- mClientContext = new ClientContext();
-
- mMockPackageManager = mock(PackageManager.class);
- mMockPackageManagerInternal = mock(PackageManagerInternal.class);
- mMockUserManager = mock(UserManager.class);
-
- // Prepare injection values.
-
- mInjectedCurrentTimeLillis = START_TIME;
-
- mInjectedPackages = new HashMap<>();;
- addPackage(CALLING_PACKAGE_1, CALLING_UID_1, 1);
- addPackage(CALLING_PACKAGE_2, CALLING_UID_2, 2);
- addPackage(CALLING_PACKAGE_3, CALLING_UID_3, 3);
- addPackage(CALLING_PACKAGE_4, CALLING_UID_4, 10);
- addPackage(LAUNCHER_1, LAUNCHER_UID_1, 4);
- addPackage(LAUNCHER_2, LAUNCHER_UID_2, 5);
- addPackage(LAUNCHER_3, LAUNCHER_UID_3, 6);
- addPackage(LAUNCHER_4, LAUNCHER_UID_4, 10);
-
- // CALLING_PACKAGE_3 / LAUNCHER_3 are not backup target.
- updatePackageInfo(CALLING_PACKAGE_3,
- pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
- updatePackageInfo(LAUNCHER_3,
- pi -> pi.applicationInfo.flags &= ~ApplicationInfo.FLAG_ALLOW_BACKUP);
-
- mUninstalledPackages = new HashSet<>();
-
- mInjectedFilePathRoot = new File(getTestContext().getCacheDir(), "test-files");
-
- deleteAllSavedFiles();
-
- // Set up users.
- doAnswer(inv -> {
- assertSystem();
- return USER_INFO_0;
- }).when(mMockUserManager).getUserInfo(eq(USER_0));
-
- doAnswer(inv -> {
- assertSystem();
- return USER_INFO_10;
- }).when(mMockUserManager).getUserInfo(eq(USER_10));
-
- doAnswer(inv -> {
- assertSystem();
- return USER_INFO_11;
- }).when(mMockUserManager).getUserInfo(eq(USER_11));
-
- doAnswer(inv -> {
- assertSystem();
- return USER_INFO_P0;
- }).when(mMockUserManager).getUserInfo(eq(USER_P0));
-
- // User 0 is always running.
- when(mMockUserManager.isUserRunning(eq(USER_0))).thenAnswer(new AnswerIsUserRunning(true));
-
- initService();
- setCaller(CALLING_PACKAGE_1);
-
- // In order to complicate the situation, we set mLocaleChangeSequenceNumber to 1 by
- // calling this. Running test with mLocaleChangeSequenceNumber == 0 might make us miss
- // some edge cases.
- mInternal.onSystemLocaleChangedNoLock();
- }
-
- /**
- * Returns a boolean but also checks if the current UID is SYSTEM_UID.
- */
- private class AnswerIsUserRunning implements Answer<Boolean> {
- private final boolean mAnswer;
-
- private AnswerIsUserRunning(boolean answer) {
- mAnswer = answer;
- }
-
- @Override
- public Boolean answer(InvocationOnMock invocation) throws Throwable {
- assertEquals("isUserRunning() must be called on SYSTEM UID.",
- Process.SYSTEM_UID, mInjectedCallingUid);
- return mAnswer;
- }
- }
-
- private static UserInfo withProfileGroupId(UserInfo in, int groupId) {
- in.profileGroupId = groupId;
- return in;
- }
-
- @Override
- protected void tearDown() throws Exception {
- if (DUMP_IN_TEARDOWN) dumpsysOnLogcat("Teardown");
-
- shutdownServices();
-
- super.tearDown();
- }
-
- private Context getTestContext() {
- return getInstrumentation().getContext();
- }
-
- private void deleteAllSavedFiles() {
- // Empty the data directory.
- if (mInjectedFilePathRoot.exists()) {
- Assert.assertTrue("failed to delete dir",
- FileUtils.deleteContents(mInjectedFilePathRoot));
- }
- mInjectedFilePathRoot.mkdirs();
- }
-
- /** (Re-) init the manager and the service. */
- private void initService() {
- shutdownServices();
-
- LocalServices.removeServiceForTest(ShortcutServiceInternal.class);
-
- // Instantiate targets.
- mService = new ShortcutServiceTestable(mServiceContext, Looper.getMainLooper());
- mManager = new ShortcutManagerTestable(mClientContext, mService);
-
- mInternal = LocalServices.getService(ShortcutServiceInternal.class);
-
- mLauncherAppImpl = new LauncherAppImplTestable(mServiceContext);
- mLauncherApps = null;
- mLauncherAppsMap.clear();
-
- // Load the setting file.
- mService.onBootPhase(SystemService.PHASE_LOCK_SETTINGS_READY);
- }
-
- private void shutdownServices() {
- if (mService != null) {
- // Flush all the unsaved data from the previous instance.
- mService.saveDirtyInfo();
- }
- LocalServices.removeServiceForTest(ShortcutServiceInternal.class);
-
- mService = null;
- mManager = null;
- mInternal = null;
- mLauncherAppImpl = null;
- mLauncherApps = null;
- mLauncherAppsMap.clear();
- }
-
- private void addPackage(String packageName, int uid, int version) {
- addPackage(packageName, uid, version, packageName);
- }
-
- private Signature[] genSignatures(String... signatures) {
- final Signature[] sigs = new Signature[signatures.length];
- for (int i = 0; i < signatures.length; i++){
- sigs[i] = new Signature(signatures[i].getBytes());
- }
- return sigs;
- }
-
- private PackageInfo genPackage(String packageName, int uid, int version, String... signatures) {
- final PackageInfo pi = new PackageInfo();
- pi.packageName = packageName;
- pi.applicationInfo = new ApplicationInfo();
- pi.applicationInfo.uid = uid;
- pi.applicationInfo.flags = ApplicationInfo.FLAG_INSTALLED
- | ApplicationInfo.FLAG_ALLOW_BACKUP;
- pi.versionCode = version;
- pi.applicationInfo.versionCode = version;
- pi.signatures = genSignatures(signatures);
-
- return pi;
- }
-
- private void addPackage(String packageName, int uid, int version, String... signatures) {
- mInjectedPackages.put(packageName, genPackage(packageName, uid, version, signatures));
- }
-
- private void updatePackageInfo(String packageName, Consumer<PackageInfo> c) {
- c.accept(mInjectedPackages.get(packageName));
- }
-
- private void updatePackageVersion(String packageName, int increment) {
- updatePackageInfo(packageName, pi -> {
- pi.versionCode += increment;
- pi.applicationInfo.versionCode += increment;
- });
- }
-
- private void updatePackageLastUpdateTime(String packageName, long increment) {
- updatePackageInfo(packageName, pi -> {
- pi.lastUpdateTime += increment;
- });
- }
-
- private void uninstallPackage(int userId, String packageName) {
- if (ENABLE_DUMP) {
- Log.i(TAG, "Unnstall package " + packageName + " / " + userId);
- }
- mUninstalledPackages.add(PackageWithUser.of(userId, packageName));
- }
-
- private void installPackage(int userId, String packageName) {
- if (ENABLE_DUMP) {
- Log.i(TAG, "Install package " + packageName + " / " + userId);
- }
- mUninstalledPackages.remove(PackageWithUser.of(userId, packageName));
- }
-
- PackageInfo getInjectedPackageInfo(String packageName, @UserIdInt int userId,
- boolean getSignatures) {
- final PackageInfo pi = mInjectedPackages.get(packageName);
- if (pi == null) return null;
-
- final PackageInfo ret = new PackageInfo();
- ret.packageName = pi.packageName;
- ret.versionCode = pi.versionCode;
- ret.lastUpdateTime = pi.lastUpdateTime;
-
- ret.applicationInfo = new ApplicationInfo(pi.applicationInfo);
- ret.applicationInfo.uid = UserHandle.getUid(userId, pi.applicationInfo.uid);
- ret.applicationInfo.packageName = pi.packageName;
-
- if (mUninstalledPackages.contains(PackageWithUser.of(userId, packageName))) {
- ret.applicationInfo.flags &= ~ApplicationInfo.FLAG_INSTALLED;
- }
-
- if (getSignatures) {
- ret.signatures = pi.signatures;
- }
-
- return ret;
- }
-
- private void addApplicationInfo(PackageInfo pi, List<ApplicationInfo> list) {
- if (pi != null && pi.applicationInfo != null) {
- list.add(pi.applicationInfo);
- }
- }
-
- private List<ApplicationInfo> getInstalledApplications(int userId) {
- final ArrayList<ApplicationInfo> ret = new ArrayList<>();
-
- addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_1, userId, false), ret);
- addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_2, userId, false), ret);
- addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_3, userId, false), ret);
- addApplicationInfo(getInjectedPackageInfo(CALLING_PACKAGE_4, userId, false), ret);
- addApplicationInfo(getInjectedPackageInfo(LAUNCHER_1, userId, false), ret);
- addApplicationInfo(getInjectedPackageInfo(LAUNCHER_2, userId, false), ret);
- addApplicationInfo(getInjectedPackageInfo(LAUNCHER_3, userId, false), ret);
- addApplicationInfo(getInjectedPackageInfo(LAUNCHER_4, userId, false), ret);
-
- return ret;
- }
-
- private void addManifestShortcutResource(ComponentName activity, int resId) {
- final String packageName = activity.getPackageName();
- HashMap<ComponentName, Integer> map = mActivityMetadataResId.get(packageName);
- if (map == null) {
- map = new HashMap<>();
- mActivityMetadataResId.put(packageName, map);
- }
- map.put(activity, resId);
- }
-
- private PackageInfo injectGetActivitiesWithMetadata(String packageName, @UserIdInt int userId) {
- final PackageInfo ret = getInjectedPackageInfo(packageName, userId,
- /* getSignatures=*/ false);
-
- final HashMap<ComponentName, Integer> activities = mActivityMetadataResId.get(packageName);
- if (activities != null) {
- final ArrayList<ActivityInfo> list = new ArrayList<>();
-
- for (ComponentName cn : activities.keySet()) {
- ActivityInfo ai = new ActivityInfo();
- ai.packageName = cn.getPackageName();
- ai.name = cn.getClassName();
- ai.metaData = new Bundle();
- ai.metaData.putInt(ShortcutParser.METADATA_KEY, activities.get(cn));
- list.add(ai);
- }
- ret.activities = list.toArray(new ActivityInfo[list.size()]);
- }
- return ret;
- }
-
- private XmlResourceParser injectXmlMetaData(ActivityInfo activityInfo, String key) {
- if (!ShortcutParser.METADATA_KEY.equals(key) || activityInfo.metaData == null) {
- return null;
- }
- final int resId = activityInfo.metaData.getInt(key);
- return getTestContext().getResources().getXml(resId);
- }
-
- /** Replace the current calling package */
- private void setCaller(String packageName, int userId) {
- mInjectedClientPackage = packageName;
- mInjectedCallingUid =
- Preconditions.checkNotNull(getInjectedPackageInfo(packageName, userId, false),
- "Unknown package").applicationInfo.uid;
-
- // Set up LauncherApps for this caller.
- final Pair<Integer, String> key = Pair.create(userId, packageName);
- if (!mLauncherAppsMap.containsKey(key)) {
- mLauncherAppsMap.put(key, new LauncherAppsTestable(mClientContext, mLauncherAppImpl));
- }
- mLauncherApps = mLauncherAppsMap.get(key);
- }
-
- private void setCaller(String packageName) {
- setCaller(packageName, UserHandle.USER_SYSTEM);
- }
-
- private String getCallingPackage() {
- return mInjectedClientPackage;
- }
-
- private void setDefaultLauncherChecker(BiPredicate<String, Integer> p) {
- mDefaultLauncherChecker = p;
- }
-
- private void runWithCaller(String packageName, int userId, Runnable r) {
- final String previousPackage = mInjectedClientPackage;
- final int previousUserId = UserHandle.getUserId(mInjectedCallingUid);
-
- setCaller(packageName, userId);
-
- r.run();
-
- setCaller(previousPackage, previousUserId);
- }
-
- private int getCallingUserId() {
- return UserHandle.getUserId(mInjectedCallingUid);
- }
-
- private UserHandle getCallingUser() {
- return UserHandle.of(getCallingUserId());
- }
-
- /** For debugging */
- private void dumpsysOnLogcat() {
- dumpsysOnLogcat("");
- }
-
- private void dumpsysOnLogcat(String message) {
- dumpsysOnLogcat(message, false);
- }
-
- private void dumpsysOnLogcat(String message, boolean force) {
- if (force || !ENABLE_DUMP) return;
-
- final ByteArrayOutputStream out = new ByteArrayOutputStream();
- final PrintWriter pw = new PrintWriter(out);
- mService.dumpInner(pw, null);
- pw.close();
-
- Log.e(TAG, "Dumping ShortcutService: " + message);
- for (String line : out.toString().split("\n")) {
- Log.e(TAG, line);
- }
- }
-
- /**
- * For debugging, dump arbitrary file on logcat.
- */
- private void dumpFileOnLogcat(String path) {
- dumpFileOnLogcat(path, "");
- }
-
- private void dumpFileOnLogcat(String path, String message) {
- if (!ENABLE_DUMP) return;
-
- Log.i(TAG, "Dumping file: " + path + " " + message);
- final StringBuilder sb = new StringBuilder();
- try (BufferedReader br = new BufferedReader(new FileReader(path))) {
- String line;
- while ((line = br.readLine()) != null) {
- Log.i(TAG, line);
- }
- } catch (Exception e) {
- Log.e(TAG, "Couldn't read file", e);
- fail("Exception " + e);
- }
- }
-
- /**
- * For debugging, dump the main state file on logcat.
- */
- private void dumpBaseStateFile() {
- mService.saveDirtyInfo();
- dumpFileOnLogcat(mInjectedFilePathRoot.getAbsolutePath()
- + "/system/" + ShortcutService.FILENAME_BASE_STATE);
- }
-
- /**
- * For debugging, dump per-user state file on logcat.
- */
- private void dumpUserFile(int userId) {
- dumpUserFile(userId, "");
- }
-
- private void dumpUserFile(int userId, String message) {
- mService.saveDirtyInfo();
- dumpFileOnLogcat(mInjectedFilePathRoot.getAbsolutePath()
- + "/user-" + userId
- + "/" + ShortcutService.FILENAME_USER_PACKAGES, message);
- }
-
- private void waitOnMainThread() throws Throwable {
- runTestOnUiThread(() -> {});
- }
-
- /**
- * Make a shortcut with an ID.
- */
- private ShortcutInfo makeShortcut(String id) {
- return makeShortcut(
- id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
- }
-
- private ShortcutInfo makeShortcutWithTitle(String id, String title) {
- return makeShortcut(
- id, title, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
- }
-
- /**
- * Make a shortcut with an ID and timestamp.
- */
- private ShortcutInfo makeShortcutWithTimestamp(String id, long timestamp) {
- final ShortcutInfo s = makeShortcut(
- id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
- s.setTimestamp(timestamp);
- return s;
- }
-
- /**
- * Make a shortcut with an ID, a timestamp and an activity component
- */
- private ShortcutInfo makeShortcutWithTimestampWithActivity(String id, long timestamp,
- ComponentName activity) {
- final ShortcutInfo s = makeShortcut(
- id, "Title-" + id, activity, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
- s.setTimestamp(timestamp);
- return s;
- }
-
- /**
- * Make a shortcut with an ID and icon.
- */
- private ShortcutInfo makeShortcutWithIcon(String id, Icon icon) {
- return makeShortcut(
- id, "Title-" + id, /* activity =*/ null, icon,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
- }
-
- private ShortcutInfo makePackageShortcut(String packageName, String id) {
- String origCaller = getCallingPackage();
-
- setCaller(packageName);
- ShortcutInfo s = makeShortcut(
- id, "Title-" + id, /* activity =*/ null, /* icon =*/ null,
- makeIntent(Intent.ACTION_VIEW, ShortcutActivity.class), /* weight =*/ 0);
- setCaller(origCaller); // restore the caller
-
- return s;
- }
-
- /**
- * Make multiple shortcuts with IDs.
- */
- private List<ShortcutInfo> makeShortcuts(String... ids) {
- final ArrayList<ShortcutInfo> ret = new ArrayList();
- for (String id : ids) {
- ret.add(makeShortcut(id));
- }
- return ret;
- }
-
- private ShortcutInfo.Builder makeShortcutBuilder() {
- return new ShortcutInfo.Builder(mClientContext);
- }
-
- /**
- * Make a shortcut with details.
- */
- private ShortcutInfo makeShortcut(String id, String title, ComponentName activity,
- Icon icon, Intent intent, int rank) {
- final ShortcutInfo.Builder b = new ShortcutInfo.Builder(mClientContext)
- .setId(id)
- .setActivity(new ComponentName(mClientContext.getPackageName(), "dummy"))
- .setTitle(title)
- .setRank(rank)
- .setIntent(intent);
- if (icon != null) {
- b.setIcon(icon);
- }
- if (activity != null) {
- b.setActivity(activity);
- }
- final ShortcutInfo s = b.build();
-
- s.setTimestamp(mInjectedCurrentTimeLillis); // HACK
-
- return s;
- }
-
- /**
- * Make an intent.
- */
- private Intent makeIntent(String action, Class<?> clazz, Object... bundleKeysAndValues) {
- final Intent intent = new Intent(action);
- intent.setComponent(makeComponent(clazz));
- intent.replaceExtras(makeBundle(bundleKeysAndValues));
- return intent;
- }
-
- /**
- * Make an component name, with the client context.
- */
- @NonNull
- private ComponentName makeComponent(Class<?> clazz) {
- return new ComponentName(mClientContext, clazz);
- }
-
- @NonNull
- private ShortcutInfo findById(List<ShortcutInfo> list, String id) {
- for (ShortcutInfo s : list) {
- if (s.getId().equals(id)) {
- return s;
- }
- }
- fail("Shortcut with id " + id + " not found");
- return null;
- }
-
- private void assertSystem() {
- assertEquals("Caller must be system", Process.SYSTEM_UID, mInjectedCallingUid);
- }
-
- private void assertResetTimes(long expectedLastResetTime, long expectedNextResetTime) {
- assertEquals(expectedLastResetTime, mService.getLastResetTimeLocked());
- assertEquals(expectedNextResetTime, mService.getNextResetTimeLocked());
- }
-
- public static List<ShortcutInfo> assertAllNotHaveIcon(
- List<ShortcutInfo> actualShortcuts) {
- for (ShortcutInfo s : actualShortcuts) {
- assertNull("ID " + s.getId(), s.getIcon());
- }
- return actualShortcuts;
- }
-
- @NonNull
- private List<ShortcutInfo> assertAllHaveFlags(@NonNull List<ShortcutInfo> actualShortcuts,
- int shortcutFlags) {
- for (ShortcutInfo s : actualShortcuts) {
- assertTrue("ID " + s.getId() + " doesn't have flags " + shortcutFlags,
- s.hasFlags(shortcutFlags));
- }
- return actualShortcuts;
- }
-
- private ShortcutInfo getPackageShortcut(String packageName, String shortcutId, int userId) {
- return mService.getPackageShortcutForTest(packageName, shortcutId, userId);
- }
-
- private void assertShortcutExists(String packageName, String shortcutId, int userId) {
- assertTrue(getPackageShortcut(packageName, shortcutId, userId) != null);
- }
-
- private void assertShortcutNotExists(String packageName, String shortcutId, int userId) {
- assertTrue(getPackageShortcut(packageName, shortcutId, userId) == null);
- }
-
- private Intent launchShortcutAndGetIntent(
- @NonNull String packageName, @NonNull String shortcutId, int userId) {
- reset(mServiceContext);
- assertTrue(mLauncherApps.startShortcut(packageName, shortcutId, null, null,
- UserHandle.of(userId)));
-
- final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(
- intentCaptor.capture(),
- any(Bundle.class),
- eq(UserHandle.of(userId)));
- return intentCaptor.getValue();
- }
-
- private Intent launchShortcutAndGetIntent_withShortcutInfo(
- @NonNull String packageName, @NonNull String shortcutId, int userId) {
- reset(mServiceContext);
-
- assertTrue(mLauncherApps.startShortcut(
- getShortcutInfoAsLauncher(packageName, shortcutId, userId), null, null));
-
- final ArgumentCaptor<Intent> intentCaptor = ArgumentCaptor.forClass(Intent.class);
- verify(mServiceContext).startActivityAsUser(
- intentCaptor.capture(),
- any(Bundle.class),
- eq(UserHandle.of(userId)));
- return intentCaptor.getValue();
- }
-
- private void assertShortcutLaunchable(@NonNull String packageName, @NonNull String shortcutId,
- int userId) {
- assertNotNull(launchShortcutAndGetIntent(packageName, shortcutId, userId));
- assertNotNull(launchShortcutAndGetIntent_withShortcutInfo(packageName, shortcutId, userId));
- }
-
- private void assertShortcutNotLaunchable(@NonNull String packageName,
- @NonNull String shortcutId, int userId) {
- try {
- final boolean ok = mLauncherApps.startShortcut(packageName, shortcutId, null, null,
- UserHandle.of(userId));
- if (!ok) {
- return; // didn't launch, okay.
- }
- fail();
- } catch (SecurityException expected) {
- // security exception is okay too.
- }
- }
-
- private void assertBitmapDirectories(int userId, String... expectedDirectories) {
- final Set<String> expected = hashSet(set(expectedDirectories));
-
- final Set<String> actual = new HashSet<>();
-
- final File[] files = mService.getUserBitmapFilePath(userId).listFiles();
- if (files != null) {
- for (File child : files) {
- if (child.isDirectory()) {
- actual.add(child.getName());
- }
- }
- }
-
- assertEquals(expected, actual);
- }
-
- private void assertBitmapFiles(int userId, String packageName, String... expectedFiles) {
- final Set<String> expected = hashSet(set(expectedFiles));
-
- final Set<String> actual = new HashSet<>();
-
- final File[] files = new File(mService.getUserBitmapFilePath(userId), packageName)
- .listFiles();
- if (files != null) {
- for (File child : files) {
- if (child.isFile()) {
- actual.add(child.getName());
- }
- }
- }
-
- assertEquals(expected, actual);
- }
-
- private String getBitmapFilename(int userId, String packageName, String shortcutId) {
- final ShortcutInfo si = mService.getPackageShortcutForTest(packageName, shortcutId, userId);
- if (si == null) {
- return null;
- }
- return new File(si.getBitmapPath()).getName();
- }
-
- private List<ShortcutInfo> getCallerShortcuts() {
- final ShortcutPackage p = mService.getPackageShortcutForTest(
- getCallingPackage(), getCallingUserId());
- return p == null ? null : p.getAllShortcutsForTest();
- }
-
- private ShortcutInfo getCallerShortcut(String shortcutId) {
- return getPackageShortcut(getCallingPackage(), shortcutId, getCallingUserId());
- }
-
- private List<ShortcutInfo> getLauncherShortcuts(String launcher, int userId, int queryFlags) {
- final List<ShortcutInfo>[] ret = new List[1];
- runWithCaller(launcher, userId, () -> {
- final ShortcutQuery q = new ShortcutQuery();
- q.setQueryFlags(queryFlags);
- ret[0] = mLauncherApps.getShortcuts(q, UserHandle.of(userId));
- });
- return ret[0];
- }
-
- private List<ShortcutInfo> getLauncherPinnedShortcuts(String launcher, int userId) {
- return getLauncherShortcuts(launcher, userId, ShortcutQuery.FLAG_GET_PINNED);
- }
-
- private ShortcutInfo getShortcutInfoAsLauncher(String packageName, String shortcutId,
- int userId) {
- final List<ShortcutInfo> infoList =
- mLauncherApps.getShortcutInfo(packageName, list(shortcutId),
- UserHandle.of(userId));
- assertEquals("No shortcutInfo found (or too many of them)", 1, infoList.size());
- return infoList.get(0);
- }
-
- private Intent genPackageAddIntent(String pakcageName, int userId) {
- Intent i = new Intent(Intent.ACTION_PACKAGE_ADDED);
- i.setData(Uri.parse("package:" + pakcageName));
- i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- return i;
- }
-
- private Intent genPackageDeleteIntent(String pakcageName, int userId) {
- Intent i = new Intent(Intent.ACTION_PACKAGE_REMOVED);
- i.setData(Uri.parse("package:" + pakcageName));
- i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- return i;
- }
-
- private Intent genPackageUpdateIntent(String pakcageName, int userId) {
- Intent i = new Intent(Intent.ACTION_PACKAGE_ADDED);
- i.setData(Uri.parse("package:" + pakcageName));
- i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- i.putExtra(Intent.EXTRA_REPLACING, true);
- return i;
- }
- private Intent genPackageDataClear(String packageName, int userId) {
- Intent i = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED);
- i.setData(Uri.parse("package:" + packageName));
- i.putExtra(Intent.EXTRA_USER_HANDLE, userId);
- return i;
- }
-
- private ShortcutInfo parceled(ShortcutInfo si) {
- Parcel p = Parcel.obtain();
- p.writeParcelable(si, 0);
- p.setDataPosition(0);
- ShortcutInfo si2 = p.readParcelable(getClass().getClassLoader());
- p.recycle();
- return si2;
- }
+public class ShortcutManagerTest1 extends BaseShortcutManagerTest {
/**
* Test for the first launch path, no settings file available.
@@ -1328,24 +132,24 @@
assertResetTimes(START_TIME, START_TIME + INTERVAL);
// Advance clock.
- mInjectedCurrentTimeLillis += 100;
+ mInjectedCurrentTimeMillis += 100;
// Shouldn't have changed.
assertResetTimes(START_TIME, START_TIME + INTERVAL);
// Advance clock, almost the reset time.
- mInjectedCurrentTimeLillis = START_TIME + INTERVAL - 1;
+ mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
// Shouldn't have changed.
assertResetTimes(START_TIME, START_TIME + INTERVAL);
// Advance clock.
- mInjectedCurrentTimeLillis += 1;
+ mInjectedCurrentTimeMillis += 1;
assertResetTimes(START_TIME + INTERVAL, START_TIME + 2 * INTERVAL);
// Advance further; 4 hours since start.
- mInjectedCurrentTimeLillis = START_TIME + 4 * INTERVAL + 50;
+ mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
assertResetTimes(START_TIME + 4 * INTERVAL, START_TIME + 5 * INTERVAL);
}
@@ -1355,7 +159,7 @@
*/
public void testInitializeFromSavedFile() {
- mInjectedCurrentTimeLillis = START_TIME + 4 * INTERVAL + 50;
+ mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
assertResetTimes(START_TIME + 4 * INTERVAL, START_TIME + 5 * INTERVAL);
mService.saveBaseStateLocked();
@@ -1427,7 +231,7 @@
assertEquals(MAX_UPDATES_PER_INTERVAL, mManager.getRemainingCallCount());
}
- public void getIconMaxDimensions() {
+ public void testGetIconMaxDimensions() {
assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxWidth());
assertEquals(MAX_ICON_DIMENSION, mManager.getIconMaxHeight());
}
@@ -1436,7 +240,7 @@
public void testGetRateLimitResetTime() {
assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
- mInjectedCurrentTimeLillis = START_TIME + 4 * INTERVAL + 50;
+ mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL + 50;
assertEquals(START_TIME + 5 * INTERVAL, mManager.getRateLimitResetTime());
}
@@ -1486,7 +290,7 @@
dumpsysOnLogcat();
- mInjectedCurrentTimeLillis++; // Need to advance the clock for reset to work.
+ mInjectedCurrentTimeMillis++; // Need to advance the clock for reset to work.
mService.resetThrottlingInner(UserHandle.USER_SYSTEM);
dumpsysOnLogcat();
@@ -1529,7 +333,7 @@
mManager.getDynamicShortcuts()),
"shortcut1", "shortcut2", "shortcut3");
- mInjectedCurrentTimeLillis += INTERVAL; // reset
+ mInjectedCurrentTimeMillis += INTERVAL; // reset
// Add with the same ID
assertTrue(mManager.addDynamicShortcuts(list(makeShortcut("shortcut1"))));
@@ -1617,183 +421,6 @@
assertEquals(1, mManager.getRemainingCallCount());
}
- public void testThrottling() {
- final ShortcutInfo si1 = makeShortcut("shortcut1");
-
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(2, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(1, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(0, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
-
- // Reached the max
-
- mInjectedCurrentTimeLillis++;
- assertFalse(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(0, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
-
- // Still throttled
- mInjectedCurrentTimeLillis = START_TIME + INTERVAL - 1;
- assertFalse(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(0, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
-
- // Now it should work.
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1))); // fail
- assertEquals(2, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(1, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(0, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
-
- mInjectedCurrentTimeLillis++;
- assertFalse(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(0, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
-
- // 4 hours later...
- mInjectedCurrentTimeLillis = START_TIME + 4 * INTERVAL;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(2, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(1, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
-
- // Make sure getRemainingCallCount() itself gets reset without calling setDynamicShortcuts().
- mInjectedCurrentTimeLillis = START_TIME + 8 * INTERVAL;
- assertEquals(3, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(2, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
- }
-
- public void testThrottling_rewind() {
- final ShortcutInfo si1 = makeShortcut("shortcut1");
-
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(2, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
-
- mInjectedCurrentTimeLillis = 12345; // Clock reset!
-
- // Since the clock looks invalid, the counter shouldn't have reset.
- assertEquals(2, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
-
- // Forward again. Still haven't reset yet.
- mInjectedCurrentTimeLillis = START_TIME + INTERVAL - 1;
- assertEquals(2, mManager.getRemainingCallCount());
- assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
-
- // Now rewind -- this will reset the counters.
- mInjectedCurrentTimeLillis = START_TIME - 100000;
- assertEquals(3, mManager.getRemainingCallCount());
-
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(2, mManager.getRemainingCallCount());
-
- // Forward again, should be reset now.
- mInjectedCurrentTimeLillis += INTERVAL;
- assertEquals(3, mManager.getRemainingCallCount());
- }
-
- public void testThrottling_perPackage() {
- final ShortcutInfo si1 = makeShortcut("shortcut1");
-
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(2, mManager.getRemainingCallCount());
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(1, mManager.getRemainingCallCount());
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(0, mManager.getRemainingCallCount());
-
- // Reached the max
-
- mInjectedCurrentTimeLillis++;
- assertFalse(mManager.setDynamicShortcuts(list(si1)));
-
- // Try from a different caller.
- mInjectedClientPackage = CALLING_PACKAGE_2;
- mInjectedCallingUid = CALLING_UID_2;
-
- // Need to create a new one wit the updated package name.
- final ShortcutInfo si2 = makeShortcut("shortcut1");
-
- assertEquals(3, mManager.getRemainingCallCount());
-
- assertTrue(mManager.setDynamicShortcuts(list(si2)));
- assertEquals(2, mManager.getRemainingCallCount());
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si2)));
- assertEquals(1, mManager.getRemainingCallCount());
-
- // Back to the original caller, still throttled.
- mInjectedClientPackage = CALLING_PACKAGE_1;
- mInjectedCallingUid = CALLING_UID_1;
-
- mInjectedCurrentTimeLillis = START_TIME + INTERVAL - 1;
- assertEquals(0, mManager.getRemainingCallCount());
- assertFalse(mManager.setDynamicShortcuts(list(si1)));
- assertEquals(0, mManager.getRemainingCallCount());
-
- // Now it should work.
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
-
- mInjectedCurrentTimeLillis++;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
-
- mInjectedCurrentTimeLillis++;
- assertFalse(mManager.setDynamicShortcuts(list(si1)));
-
- mInjectedCurrentTimeLillis = START_TIME + 4 * INTERVAL;
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertTrue(mManager.setDynamicShortcuts(list(si1)));
- assertFalse(mManager.setDynamicShortcuts(list(si1)));
-
- mInjectedClientPackage = CALLING_PACKAGE_2;
- mInjectedCallingUid = CALLING_UID_2;
-
- assertEquals(3, mManager.getRemainingCallCount());
-
- assertTrue(mManager.setDynamicShortcuts(list(si2)));
- assertTrue(mManager.setDynamicShortcuts(list(si2)));
- assertTrue(mManager.setDynamicShortcuts(list(si2)));
- assertFalse(mManager.setDynamicShortcuts(list(si2)));
- }
-
public void testIcons() throws IOException {
final Icon res32x32 = Icon.createWithResource(getTestContext(), R.drawable.black_32x32);
final Icon res64x64 = Icon.createWithResource(getTestContext(), R.drawable.black_64x64);
@@ -1944,16 +571,6 @@
assertBitmapSize(128, 128, bmp);
}
- private File makeFile(File baseDirectory, String... paths) {
- File ret = baseDirectory;
-
- for (String path : paths) {
- ret = new File(ret, path);
- }
-
- return ret;
- }
-
public void testCleanupDanglingBitmaps() throws Exception {
assertBitmapDirectories(USER_0, EMPTY_STRINGS);
assertBitmapDirectories(USER_10, EMPTY_STRINGS);
@@ -1971,7 +588,7 @@
});
// Increment the time (which actually we don't have to), which is used for filenames.
- mInjectedCurrentTimeLillis++;
+ mInjectedCurrentTimeMillis++;
runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
mManager.setDynamicShortcuts(list(
@@ -1982,7 +599,7 @@
});
// Increment the time, which is used for filenames.
- mInjectedCurrentTimeLillis++;
+ mInjectedCurrentTimeMillis++;
runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
mManager.setDynamicShortcuts(list(
@@ -2020,7 +637,7 @@
getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s1"),
getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s2"),
getBitmapFilename(USER_0, CALLING_PACKAGE_1, "s3")
- );
+ );
assertBitmapFiles(USER_0, CALLING_PACKAGE_2,
getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s4"),
getBitmapFilename(USER_0, CALLING_PACKAGE_2, "s5"),
@@ -2111,7 +728,7 @@
);
}
- private void checkShrinkBitmap(int expectedWidth, int expectedHeight, int resId, int maxSize) {
+ protected void checkShrinkBitmap(int expectedWidth, int expectedHeight, int resId, int maxSize) {
assertBitmapSize(expectedWidth, expectedHeight,
ShortcutService.shrinkBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), resId),
@@ -2132,7 +749,7 @@
checkShrinkBitmap(2048, 512, R.drawable.black_4096x1024, 2048);
}
- private File openIconFileForWriteAndGetPath(int userId, String packageName)
+ protected File openIconFileForWriteAndGetPath(int userId, String packageName)
throws IOException {
// Shortcut IDs aren't used in the path, so just pass the same ID.
final FileOutputStreamWithPath out =
@@ -2142,7 +759,7 @@
}
public void testOpenIconFileForWrite() throws IOException {
- mInjectedCurrentTimeLillis = 1000;
+ mInjectedCurrentTimeMillis = 1000;
final File p10_1_1 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
final File p10_1_2 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
@@ -2153,7 +770,7 @@
final File p11_1_1 = openIconFileForWriteAndGetPath(11, CALLING_PACKAGE_1);
final File p11_1_2 = openIconFileForWriteAndGetPath(11, CALLING_PACKAGE_1);
- mInjectedCurrentTimeLillis++;
+ mInjectedCurrentTimeMillis++;
final File p10_1_3 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
final File p10_1_4 = openIconFileForWriteAndGetPath(10, CALLING_PACKAGE_1);
@@ -2345,38 +962,6 @@
// === Test for launcher side APIs ===
- private static ShortcutQuery buildQuery(long changedSince,
- String packageName, ComponentName componentName,
- /* @ShortcutQuery.QueryFlags */ int flags) {
- return buildQuery(changedSince, packageName, null, componentName, flags);
- }
-
- private static ShortcutQuery buildQuery(long changedSince,
- String packageName, List<String> shortcutIds, ComponentName componentName,
- /* @ShortcutQuery.QueryFlags */ int flags) {
- final ShortcutQuery q = new ShortcutQuery();
- q.setChangedSince(changedSince);
- q.setPackage(packageName);
- q.setShortcutIds(shortcutIds);
- q.setActivity(componentName);
- q.setQueryFlags(flags);
- return q;
- }
-
- private static ShortcutQuery buildAllQuery(String packageName) {
- final ShortcutQuery q = new ShortcutQuery();
- q.setPackage(packageName);
- q.setQueryFlags(ShortcutQuery.FLAG_GET_DYNAMIC | ShortcutQuery.FLAG_GET_PINNED);
- return q;
- }
-
- private static ShortcutQuery buildPinnedQuery(String packageName) {
- final ShortcutQuery q = new ShortcutQuery();
- q.setPackage(packageName);
- q.setQueryFlags(ShortcutQuery.FLAG_GET_PINNED);
- return q;
- }
-
public void testGetShortcuts() {
// Set up shortcuts.
@@ -2404,10 +989,10 @@
// Get dynamic
assertAllDynamic(assertAllHaveTitle(assertAllNotHaveIntents(assertAllStringsResolved(
assertShortcutIds(
- assertAllNotKeyFieldsOnly(
- mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
+ assertAllNotKeyFieldsOnly(
+ mLauncherApps.getShortcuts(buildQuery(/* time =*/ 0, CALLING_PACKAGE_1,
/* activity =*/ null, ShortcutQuery.FLAG_GET_DYNAMIC), getCallingUser())),
- "s1", "s2")))));
+ "s1", "s2")))));
// Get pinned
assertShortcutIds(
@@ -2497,10 +1082,10 @@
assertExpectException(
IllegalArgumentException.class, "package name must also be set", () -> {
- mLauncherApps.getShortcuts(buildQuery(
+ mLauncherApps.getShortcuts(buildQuery(
/* time =*/ 0, /* package= */ null, list("id"),
/* activity =*/ null, /* flags */ 0), getCallingUser());
- });
+ });
// TODO More tests: pinned but dynamic.
}
@@ -2626,8 +1211,8 @@
// Note we don't guarantee the orders.
list = assertShortcutIds(assertAllHaveTitle(assertAllNotHaveIntents(
assertAllNotKeyFieldsOnly(
- mLauncherApps.getShortcutInfo(CALLING_PACKAGE_1,
- list("s2", "s1", "s3", null), getCallingUser())))),
+ mLauncherApps.getShortcutInfo(CALLING_PACKAGE_1,
+ list("s2", "s1", "s3", null), getCallingUser())))),
"s1", "s2");
assertEquals("Title 1", findById(list, "s1").getTitle());
assertEquals("Title 2", findById(list, "s2").getTitle());
@@ -4509,7 +3094,7 @@
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
mService.checkPackageChanges(USER_P0);
-
+
assertDynamicAndPinned(getPackageShortcut(CALLING_PACKAGE_1, "s1", USER_0));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s2", USER_0));
assertDynamicOnly(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_0));
@@ -4600,7 +3185,7 @@
assertNull(getPackageShortcut(CALLING_PACKAGE_1, "s3", USER_10));
}
- private void checkCanRestoreTo(boolean expected, ShortcutPackageInfo spi,
+ protected void checkCanRestoreTo(boolean expected, ShortcutPackageInfo spi,
int version, String... signatures) {
assertEquals(expected, spi.canRestoreTo(mService, genPackage(
"dummy", /* uid */ 0, version, signatures)));
@@ -4648,11 +3233,6 @@
checkCanRestoreTo(false, spi2, 11, "x", "sig2x", "sig1", "y");
}
- private boolean bitmapDirectoryExists(String packageName, int userId) {
- final File path = new File(mService.getUserBitmapFilePath(userId), packageName);
- return path.isDirectory();
- }
-
public void testHandlePackageDelete() {
final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
getTestContext().getResources(), R.drawable.black_32x32));
@@ -4881,7 +3461,7 @@
mLauncherApps.registerCallback(c10, new Handler(Looper.getMainLooper()));
});
- mInjectedCurrentTimeLillis = START_TIME + 100;
+ mInjectedCurrentTimeMillis = START_TIME + 100;
ArgumentCaptor<List> shortcuts;
@@ -4941,7 +3521,7 @@
// Next, send unlock even on user-10. Now we scan packages on this user and send a
// notification to the launcher.
- mInjectedCurrentTimeLillis = START_TIME + 200;
+ mInjectedCurrentTimeMillis = START_TIME + 200;
doAnswer(new AnswerIsUserRunning(true)).when(mMockUserManager).isUserRunning(eq(USER_10));
@@ -4968,7 +3548,7 @@
// Do the same thing for package 2, which doesn't have resource icons.
- mInjectedCurrentTimeLillis = START_TIME + 300;
+ mInjectedCurrentTimeMillis = START_TIME + 300;
reset(c0);
reset(c10);
@@ -4992,7 +3572,7 @@
any(UserHandle.class));
// Do the same thing for package 3
- mInjectedCurrentTimeLillis = START_TIME + 400;
+ mInjectedCurrentTimeMillis = START_TIME + 400;
reset(c0);
reset(c10);
@@ -5022,158 +3602,13 @@
findShortcut(shortcuts.getValue(), "s1").getLastChangedTimestamp());
}
- private void backupAndRestore() {
- int prevUid = mInjectedCallingUid;
-
- mInjectedCallingUid = Process.SYSTEM_UID; // Only system can call it.
-
- dumpsysOnLogcat("Before backup");
-
- final byte[] payload = mService.getBackupPayload(USER_0);
- if (ENABLE_DUMP) {
- final String xml = new String(payload);
- Log.i(TAG, "Backup payload:");
- for (String line : xml.split("\n")) {
- Log.i(TAG, line);
- }
- }
-
- // Before doing anything else, uninstall all packages.
- for (int userId : list(USER_0, USER_P0)) {
- for (String pkg : list(CALLING_PACKAGE_1, CALLING_PACKAGE_2, CALLING_PACKAGE_3,
- LAUNCHER_1, LAUNCHER_2, LAUNCHER_3)) {
- uninstallPackage(userId, pkg);
- }
- }
-
- shutdownServices();
-
- deleteAllSavedFiles();
-
- initService();
- mService.applyRestore(payload, USER_0);
-
- // handleUnlockUser will perform the gone package check, but it shouldn't remove
- // shadow information.
- mService.handleUnlockUser(USER_0);
-
- dumpsysOnLogcat("After restore");
-
- mInjectedCallingUid = prevUid;
- }
-
- private void prepareCrossProfileDataSet() {
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
- makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
- makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
- makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list()));
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"),
- makeShortcut("s4"), makeShortcut("s5"), makeShortcut("s6"))));
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("x1"), makeShortcut("x2"), makeShortcut("x3"),
- makeShortcut("x4"), makeShortcut("x5"), makeShortcut("x6"))));
- });
-
- runWithCaller(LAUNCHER_1, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s1", "s2"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s1", "s2", "s3"), HANDLE_USER_0);
-
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s1", "s4"), HANDLE_USER_P0);
- });
- runWithCaller(LAUNCHER_2, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s2", "s3"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s2", "s3", "s4"), HANDLE_USER_0);
-
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s2", "s5"), HANDLE_USER_P0);
- });
- runWithCaller(LAUNCHER_3, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s3", "s4", "s5"), HANDLE_USER_0);
-
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3", "s6"), HANDLE_USER_P0);
- });
- runWithCaller(LAUNCHER_4, USER_0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list(), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list(), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list(), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_4, list(), HANDLE_USER_0);
- });
-
- // Launcher on a managed profile is referring ot user 0!
- runWithCaller(LAUNCHER_1, USER_P0, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s3", "s4"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("s3", "s4", "s5"), HANDLE_USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("s3", "s4", "s5", "s6"),
- HANDLE_USER_0);
-
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s4", "s1"), HANDLE_USER_P0);
- });
- runWithCaller(LAUNCHER_1, USER_10, () -> {
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("x4", "x5"), HANDLE_USER_10);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_2, list("x4", "x5", "x6"), HANDLE_USER_10);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_3, list("x4", "x5", "x6", "x1"),
- HANDLE_USER_10);
- });
-
- // Then remove some dynamic shortcuts.
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list()));
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("s1"), makeShortcut("s2"), makeShortcut("s3"))));
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- assertTrue(mManager.setDynamicShortcuts(list(
- makeShortcut("x1"), makeShortcut("x2"), makeShortcut("x3"))));
- });
- }
-
- private void prepareForBackupTest() {
+ protected void prepareForBackupTest() {
prepareCrossProfileDataSet();
backupAndRestore();
}
- private void assertExistsAndShadow(ShortcutPackageItem spi) {
- assertNotNull(spi);
- assertTrue(spi.getPackageInfo().isShadow());
- }
-
/**
* Make sure the backup data doesn't have the following information:
* - Launchers on other users.
@@ -5182,7 +3617,7 @@
* But restores all other infomation.
*
* It also omits the following pieces of information, but that's tested in
- * {@link #testShortcutInfoSaveAndLoad_forBackup}.
+ * {@link ShortcutManagerTest2#testShortcutInfoSaveAndLoad_forBackup}.
* - Unpinned dynamic shortcuts
* - Bitmaps
*/
@@ -5248,7 +3683,7 @@
checkBackupAndRestore_success();
}
- private void checkBackupAndRestore_success() {
+ protected void checkBackupAndRestore_success() {
// Make sure non-system user is not restored.
final ShortcutUser userP0 = mService.getUserShortcutsLocked(USER_P0);
assertEquals(0, userP0.getAllPackagesForTest().size());
@@ -5321,7 +3756,7 @@
runWithCaller(LAUNCHER_1, USER_P0, () -> {
assertEquals(0,
mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_1), HANDLE_USER_0)
- .size());
+ .size());
assertEquals(0,
mLauncherApps.getShortcuts(buildAllQuery(CALLING_PACKAGE_2), HANDLE_USER_0)
.size());
@@ -5422,7 +3857,7 @@
checkBackupAndRestore_publisherNotRestored();
}
- private void checkBackupAndRestore_publisherNotRestored() {
+ protected void checkBackupAndRestore_publisherNotRestored() {
installPackage(USER_0, CALLING_PACKAGE_1);
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
@@ -5526,7 +3961,7 @@
checkBackupAndRestore_launcherNotRestored();
}
- private void checkBackupAndRestore_launcherNotRestored() {
+ protected void checkBackupAndRestore_launcherNotRestored() {
installPackage(USER_0, CALLING_PACKAGE_1);
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
@@ -5627,7 +4062,7 @@
checkBackupAndRestore_publisherAndLauncherNotRestored();
}
- private void checkBackupAndRestore_publisherAndLauncherNotRestored() {
+ protected void checkBackupAndRestore_publisherAndLauncherNotRestored() {
installPackage(USER_0, CALLING_PACKAGE_1);
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertEquals(0, mManager.getDynamicShortcuts().size());
@@ -5882,1210 +4317,15 @@
});
}
- public void testThrottling_localeChanges() {
- prepareCrossProfileDataSet();
-
- dumpsysOnLogcat("Before save & load");
-
- mService.saveDirtyInfo();
- initService();
-
- final long origSequenceNumber = mService.getLocaleChangeSequenceNumber();
-
- // onSystemLocaleChangedNoLock before boot completed will be ignored.
- mInternal.onSystemLocaleChangedNoLock();
- assertEquals(origSequenceNumber, mService.getLocaleChangeSequenceNumber());
-
- mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
- mInternal.onSystemLocaleChangedNoLock();
- assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
-
- // Note at this point only user-0 is loaded, and the counters are reset for this user,
- // but it will work for other users too, because we persist when
-
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
-
- mService.saveDirtyInfo();
- initService();
-
- // Make sure the counter is persisted.
- assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
- }
-
- public void testThrottling_foreground() throws Exception {
- prepareCrossProfileDataSet();
-
- dumpsysOnLogcat("Before save & load");
-
- mService.saveDirtyInfo();
- initService();
-
- // We need to update the current time from time to time, since some of the internal checks
- // rely on the time being correctly incremented.
- mInjectedCurrentTimeLillis++;
-
- // First, all packages have less than 3 (== initial value) remaining calls.
-
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
-
- mInjectedCurrentTimeLillis++;
-
- // State changed, but not foreground, so no resetting.
- mService.mUidObserver.onUidStateChanged(
- CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
-
- mInjectedCurrentTimeLillis++;
-
- // State changed, package1 foreground, reset.
- mService.mUidObserver.onUidStateChanged(
- CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- mService.mUidObserver.onUidStateChanged(
- CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
-
- mInjectedCurrentTimeLillis++;
-
- // Different app comes to foreground briefly, and goes back to background.
- // Now, make sure package 2's counter is reset, even in this case.
- mService.mUidObserver.onUidStateChanged(
- CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
- mService.mUidObserver.onUidStateChanged(
- CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
-
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
-
- mInjectedCurrentTimeLillis++;
-
- // Do the same thing one more time. This would catch the bug with mixuing up
- // the current time and the elapsed time.
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- mManager.updateShortcuts(list(makeShortcut("s")));
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
-
- mService.mUidObserver.onUidStateChanged(
- CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
- mService.mUidObserver.onUidStateChanged(
- CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
-
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
-
- mInjectedCurrentTimeLillis++;
-
- // Package 1 on user-10 comes to foreground.
- // Now, also try calling some APIs and make sure foreground apps don't get throttled.
- mService.mUidObserver.onUidStateChanged(
- UserHandle.getUid(USER_10, CALLING_UID_1),
- ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
-
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
-
- assertEquals(0, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
-
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
-
- assertEquals(0, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
-
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
-
- assertEquals(0, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
-
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
-
- assertEquals(0, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
-
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
-
- assertEquals(0, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
-
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
- mManager.setDynamicShortcuts(list(makeShortcut("s")));
-
- assertEquals(3, mManager.getRemainingCallCount()); // Still 3!
- });
- }
-
-
- public void testThrottling_resetByInternalCall() throws Exception {
- prepareCrossProfileDataSet();
-
- dumpsysOnLogcat("Before save & load");
-
- mService.saveDirtyInfo();
- initService();
-
- // First, all packages have less than 3 (== initial value) remaining calls.
-
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
-
- // Simulate a call from sys UI.
- mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING);
- mService.onApplicationActive(CALLING_PACKAGE_1, USER_0);
-
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
-
- mService.onApplicationActive(CALLING_PACKAGE_3, USER_0);
-
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
-
- mService.onApplicationActive(CALLING_PACKAGE_1, USER_10);
-
- runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
- MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
- });
- runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
- assertEquals(3, mManager.getRemainingCallCount());
- });
- }
-
public void testOnApplicationActive_permission() {
assertExpectException(SecurityException.class, "Missing permission", () ->
- mService.onApplicationActive(CALLING_PACKAGE_1, USER_0));
+ mService.onApplicationActive(CALLING_PACKAGE_1, USER_0));
// Has permission, now it should pass.
mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING);
mService.onApplicationActive(CALLING_PACKAGE_1, USER_0);
}
- // ShortcutInfo tests
-
- public void testShortcutInfoMissingMandatoryFields() {
- assertExpectException(
- IllegalArgumentException.class,
- "ID must be provided",
- () -> new ShortcutInfo.Builder(getTestContext()).build());
- assertExpectException(
- NullPointerException.class,
- "Intent action must be set",
- () -> new ShortcutInfo.Builder(getTestContext()).setIntent(new Intent()));
- assertExpectException(
- NullPointerException.class,
- "activity must be provided",
- () -> new ShortcutInfo.Builder(getTestContext()).setId("id").build()
- .enforceMandatoryFields());
- assertExpectException(
- IllegalArgumentException.class,
- "title must be provided",
- () -> new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setActivity(
- new ComponentName(getTestContext().getPackageName(), "s"))
- .build()
- .enforceMandatoryFields());
- assertExpectException(
- NullPointerException.class,
- "Intent must be provided",
- () -> new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setActivity(
- new ComponentName(getTestContext().getPackageName(), "s"))
- .setTitle("x").build()
- .enforceMandatoryFields());
- }
-
- public void testShortcutInfoParcel() {
- setCaller(CALLING_PACKAGE_1, USER_10);
- ShortcutInfo si = parceled(new ShortcutInfo.Builder(mClientContext)
- .setId("id")
- .setTitle("title")
- .setIntent(makeIntent("action", ShortcutActivity.class))
- .build());
- assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals(USER_10, si.getUserId());
- assertEquals(HANDLE_USER_10, si.getUserHandle());
- assertEquals("id", si.getId());
- assertEquals("title", si.getTitle());
- assertEquals("action", si.getIntent().getAction());
-
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
-
- si = new ShortcutInfo.Builder(getTestContext())
- .setId("id")
- .setActivity(new ComponentName("a", "b"))
- .setIcon(Icon.createWithResource(mClientContext, 123))
- .setTitle("title")
- .setText("text")
- .setDisabledMessage("dismes")
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setRank(123)
- .setExtras(pb)
- .build();
- si.addFlags(ShortcutInfo.FLAG_PINNED);
- si.setBitmapPath("abc");
- si.setIconResourceId(456);
-
- si = parceled(si);
-
- assertEquals(getTestContext().getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(new ComponentName("a", "b"), si.getActivity());
- assertEquals(123, si.getIcon().getResId());
- assertEquals("title", si.getTitle());
- assertEquals("text", si.getText());
- assertEquals("dismes", si.getDisabledMessage());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertEquals("abc", si.getBitmapPath());
- assertEquals(456, si.getIconResourceId());
- }
-
- public void testShortcutInfoParcel_resId() {
- setCaller(CALLING_PACKAGE_1, USER_10);
- ShortcutInfo si;
-
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
-
- si = new ShortcutInfo.Builder(getTestContext())
- .setId("id")
- .setActivity(new ComponentName("a", "b"))
- .setIcon(Icon.createWithResource(mClientContext, 123))
- .setTitleResId(10)
- .setTextResId(11)
- .setDisabledMessageResId(12)
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setRank(123)
- .setExtras(pb)
- .build();
- si.addFlags(ShortcutInfo.FLAG_PINNED);
- si.setBitmapPath("abc");
- si.setIconResourceId(456);
-
- si = parceled(si);
-
- assertEquals(getTestContext().getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(new ComponentName("a", "b"), si.getActivity());
- assertEquals(123, si.getIcon().getResId());
- assertEquals(10, si.getTitleResId());
- assertEquals(11, si.getTextResId());
- assertEquals(12, si.getDisabledMessageResId());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertEquals("abc", si.getBitmapPath());
- assertEquals(456, si.getIconResourceId());
- }
-
- public void testShortcutInfoClone() {
- setCaller(CALLING_PACKAGE_1, USER_11);
-
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
- ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
- .setId("id")
- .setActivity(new ComponentName("a", "b"))
- .setIcon(Icon.createWithResource(mClientContext, 123))
- .setTitle("title")
- .setText("text")
- .setDisabledMessage("dismes")
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setRank(123)
- .setExtras(pb)
- .build();
- sorig.addFlags(ShortcutInfo.FLAG_PINNED);
- sorig.setBitmapPath("abc");
- sorig.setIconResourceId(456);
-
- ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
-
- assertEquals(USER_11, si.getUserId());
- assertEquals(HANDLE_USER_11, si.getUserHandle());
- assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(new ComponentName("a", "b"), si.getActivity());
- assertEquals(123, si.getIcon().getResId());
- assertEquals("title", si.getTitle());
- assertEquals("text", si.getText());
- assertEquals("dismes", si.getDisabledMessage());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertEquals("abc", si.getBitmapPath());
- assertEquals(456, si.getIconResourceId());
-
- si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
-
- assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(new ComponentName("a", "b"), si.getActivity());
- assertEquals(null, si.getIcon());
- assertEquals("title", si.getTitle());
- assertEquals("text", si.getText());
- assertEquals("dismes", si.getDisabledMessage());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertEquals(null, si.getBitmapPath());
-
- assertEquals(456, si.getIconResourceId());
-
- si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
-
- assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(new ComponentName("a", "b"), si.getActivity());
- assertEquals(null, si.getIcon());
- assertEquals("title", si.getTitle());
- assertEquals("text", si.getText());
- assertEquals("dismes", si.getDisabledMessage());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals(null, si.getIntent());
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertEquals(null, si.getBitmapPath());
-
- assertEquals(456, si.getIconResourceId());
-
- si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
-
- assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(null, si.getActivity());
- assertEquals(null, si.getIcon());
- assertEquals(null, si.getTitle());
- assertEquals(null, si.getText());
- assertEquals(null, si.getDisabledMessage());
- assertEquals(null, si.getCategories());
- assertEquals(null, si.getIntent());
- assertEquals(0, si.getRank());
- assertEquals(null, si.getExtras());
-
- assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
- assertEquals(null, si.getBitmapPath());
-
- assertEquals(456, si.getIconResourceId());
- }
-
- public void testShortcutInfoClone_resId() {
- setCaller(CALLING_PACKAGE_1, USER_11);
-
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
- ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
- .setId("id")
- .setActivity(new ComponentName("a", "b"))
- .setIcon(Icon.createWithResource(mClientContext, 123))
- .setTitleResId(10)
- .setTextResId(11)
- .setDisabledMessageResId(12)
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setRank(123)
- .setExtras(pb)
- .build();
- sorig.addFlags(ShortcutInfo.FLAG_PINNED);
- sorig.setBitmapPath("abc");
- sorig.setIconResourceId(456);
-
- ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
-
- assertEquals(USER_11, si.getUserId());
- assertEquals(HANDLE_USER_11, si.getUserHandle());
- assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(new ComponentName("a", "b"), si.getActivity());
- assertEquals(123, si.getIcon().getResId());
- assertEquals(10, si.getTitleResId());
- assertEquals(11, si.getTextResId());
- assertEquals(12, si.getDisabledMessageResId());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertEquals("abc", si.getBitmapPath());
- assertEquals(456, si.getIconResourceId());
-
- si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
-
- assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(new ComponentName("a", "b"), si.getActivity());
- assertEquals(null, si.getIcon());
- assertEquals(10, si.getTitleResId());
- assertEquals(11, si.getTextResId());
- assertEquals(12, si.getDisabledMessageResId());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertEquals(null, si.getBitmapPath());
-
- assertEquals(456, si.getIconResourceId());
-
- si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
-
- assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(new ComponentName("a", "b"), si.getActivity());
- assertEquals(null, si.getIcon());
- assertEquals(10, si.getTitleResId());
- assertEquals(11, si.getTextResId());
- assertEquals(12, si.getDisabledMessageResId());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals(null, si.getIntent());
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertEquals(null, si.getBitmapPath());
-
- assertEquals(456, si.getIconResourceId());
-
- si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
-
- assertEquals(mClientContext.getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(null, si.getActivity());
- assertEquals(null, si.getIcon());
- assertEquals(0, si.getTitleResId());
- assertEquals(0, si.getTextResId());
- assertEquals(0, si.getDisabledMessageResId());
- assertEquals(null, si.getCategories());
- assertEquals(null, si.getIntent());
- assertEquals(0, si.getRank());
- assertEquals(null, si.getExtras());
-
- assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
- assertEquals(null, si.getBitmapPath());
-
- assertEquals(456, si.getIconResourceId());
- }
-
- public void testShortcutInfoClone_minimum() {
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
- ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
- .setId("id")
- .setTitle("title")
- .setIntent(makeIntent("action", ShortcutActivity.class))
- .build();
- ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
-
- assertEquals(getTestContext().getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals("title", si.getTitle());
- assertEquals("action", si.getIntent().getAction());
- assertEquals(null, si.getCategories());
-
- si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
-
- assertEquals(getTestContext().getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals("title", si.getTitle());
- assertEquals("action", si.getIntent().getAction());
- assertEquals(null, si.getCategories());
-
- si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
-
- assertEquals(getTestContext().getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals("title", si.getTitle());
- assertEquals(null, si.getIntent());
- assertEquals(null, si.getCategories());
-
- si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
-
- assertEquals(getTestContext().getPackageName(), si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(null, si.getTitle());
- assertEquals(null, si.getIntent());
- assertEquals(null, si.getCategories());
- }
-
- public void testShortcutInfoCopyNonNullFieldsFrom() throws InterruptedException {
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
- ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
- .setId("id")
- .setActivity(new ComponentName("a", "b"))
- .setIcon(Icon.createWithResource(mClientContext, 123))
- .setTitle("title")
- .setText("text")
- .setDisabledMessage("dismes")
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setRank(123)
- .setExtras(pb)
- .build();
- sorig.addFlags(ShortcutInfo.FLAG_PINNED);
- sorig.setBitmapPath("abc");
- sorig.setIconResourceId(456);
-
- ShortcutInfo si;
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setActivity(new ComponentName("x", "y")).build());
- assertEquals("text", si.getText());
- assertEquals(new ComponentName("x", "y"), si.getActivity());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setIcon(Icon.createWithResource(mClientContext, 456)).build());
- assertEquals("text", si.getText());
- assertEquals(456, si.getIcon().getResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setTitle("xyz").build());
- assertEquals("text", si.getText());
- assertEquals("xyz", si.getTitle());
- assertEquals(0, si.getTitleResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setTitleResId(123).build());
- assertEquals("text", si.getText());
- assertEquals(null, si.getTitle());
- assertEquals(123, si.getTitleResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setText("xxx").build());
- assertEquals(123, si.getRank());
- assertEquals("xxx", si.getText());
- assertEquals(0, si.getTextResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setTextResId(1111).build());
- assertEquals(123, si.getRank());
- assertEquals(null, si.getText());
- assertEquals(1111, si.getTextResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setDisabledMessage("xxx").build());
- assertEquals(123, si.getRank());
- assertEquals("xxx", si.getDisabledMessage());
- assertEquals(0, si.getDisabledMessageResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setDisabledMessageResId(11111).build());
- assertEquals(123, si.getRank());
- assertEquals(null, si.getDisabledMessage());
- assertEquals(11111, si.getDisabledMessageResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setCategories(set()).build());
- assertEquals("text", si.getText());
- assertEquals(set(), si.getCategories());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setCategories(set("x")).build());
- assertEquals("text", si.getText());
- assertEquals(set("x"), si.getCategories());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setIntent(makeIntent("action2", ShortcutActivity.class)).build());
- assertEquals("text", si.getText());
- assertEquals("action2", si.getIntent().getAction());
- assertEquals(null, si.getIntent().getStringExtra("key"));
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build());
- assertEquals("text", si.getText());
- assertEquals("action3", si.getIntent().getAction());
- assertEquals("x", si.getIntent().getStringExtra("key"));
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setRank(999).build());
- assertEquals("text", si.getText());
- assertEquals(999, si.getRank());
-
-
- PersistableBundle pb2 = new PersistableBundle();
- pb2.putInt("x", 99);
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setExtras(pb2).build());
- assertEquals("text", si.getText());
- assertEquals(99, si.getExtras().getInt("x"));
-
- // Make sure the timestamp gets updated too.
-
- final long timestamp = si.getLastChangedTimestamp();
- Thread.sleep(2);
-
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setTitle("xyz").build());
-
- assertTrue(si.getLastChangedTimestamp() > timestamp);
- }
-
- public void testShortcutInfoCopyNonNullFieldsFrom_resId() throws InterruptedException {
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
- ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
- .setId("id")
- .setActivity(new ComponentName("a", "b"))
- .setIcon(Icon.createWithResource(mClientContext, 123))
- .setTitleResId(10)
- .setTextResId(11)
- .setDisabledMessageResId(12)
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setRank(123)
- .setExtras(pb)
- .build();
- sorig.addFlags(ShortcutInfo.FLAG_PINNED);
- sorig.setBitmapPath("abc");
- sorig.setIconResourceId(456);
-
- ShortcutInfo si;
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setActivity(new ComponentName("x", "y")).build());
- assertEquals(11, si.getTextResId());
- assertEquals(new ComponentName("x", "y"), si.getActivity());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setIcon(Icon.createWithResource(mClientContext, 456)).build());
- assertEquals(11, si.getTextResId());
- assertEquals(456, si.getIcon().getResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setTitle("xyz").build());
- assertEquals(11, si.getTextResId());
- assertEquals("xyz", si.getTitle());
- assertEquals(0, si.getTitleResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setTitleResId(123).build());
- assertEquals(11, si.getTextResId());
- assertEquals(null, si.getTitle());
- assertEquals(123, si.getTitleResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setText("xxx").build());
- assertEquals(123, si.getRank());
- assertEquals("xxx", si.getText());
- assertEquals(0, si.getTextResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setTextResId(1111).build());
- assertEquals(123, si.getRank());
- assertEquals(null, si.getText());
- assertEquals(1111, si.getTextResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setDisabledMessage("xxx").build());
- assertEquals(123, si.getRank());
- assertEquals("xxx", si.getDisabledMessage());
- assertEquals(0, si.getDisabledMessageResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setDisabledMessageResId(11111).build());
- assertEquals(123, si.getRank());
- assertEquals(null, si.getDisabledMessage());
- assertEquals(11111, si.getDisabledMessageResId());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setCategories(set()).build());
- assertEquals(11, si.getTextResId());
- assertEquals(set(), si.getCategories());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setCategories(set("x")).build());
- assertEquals(11, si.getTextResId());
- assertEquals(set("x"), si.getCategories());
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setIntent(makeIntent("action2", ShortcutActivity.class)).build());
- assertEquals(11, si.getTextResId());
- assertEquals("action2", si.getIntent().getAction());
- assertEquals(null, si.getIntent().getStringExtra("key"));
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build());
- assertEquals(11, si.getTextResId());
- assertEquals("action3", si.getIntent().getAction());
- assertEquals("x", si.getIntent().getStringExtra("key"));
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setRank(999).build());
- assertEquals(11, si.getTextResId());
- assertEquals(999, si.getRank());
-
-
- PersistableBundle pb2 = new PersistableBundle();
- pb2.putInt("x", 99);
-
- si = sorig.clone(/* flags=*/ 0);
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setExtras(pb2).build());
- assertEquals(11, si.getTextResId());
- assertEquals(99, si.getExtras().getInt("x"));
-
- // Make sure the timestamp gets updated too.
-
- final long timestamp = si.getLastChangedTimestamp();
- Thread.sleep(2);
-
- si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
- .setTitle("xyz").build());
-
- assertTrue(si.getLastChangedTimestamp() > timestamp);
- }
-
- public void testShortcutInfoSaveAndLoad() throws InterruptedException {
- setCaller(CALLING_PACKAGE_1, USER_10);
-
- final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
- getTestContext().getResources(), R.drawable.black_32x32));
-
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
- ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
- .setId("id")
- .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
- .setIcon(bmp32x32)
- .setTitle("title")
- .setText("text")
- .setDisabledMessage("dismes")
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setRank(123)
- .setExtras(pb)
- .build();
-
- mManager.addDynamicShortcuts(list(sorig));
-
- Thread.sleep(2);
- final long now = System.currentTimeMillis();
-
- // Save and load.
- mService.saveDirtyInfo();
- initService();
- mService.handleUnlockUser(USER_10);
-
- ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
-
- assertEquals(USER_10, si.getUserId());
- assertEquals(HANDLE_USER_10, si.getUserHandle());
- assertEquals(CALLING_PACKAGE_1, si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
- assertEquals(null, si.getIcon());
- assertEquals("title", si.getTitle());
- assertEquals("text", si.getText());
- assertEquals("dismes", si.getDisabledMessage());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE, si.getFlags());
- assertNotNull(si.getBitmapPath()); // Something should be set.
- assertEquals(0, si.getIconResourceId());
- assertTrue(si.getLastChangedTimestamp() < now);
- }
-
- public void testShortcutInfoSaveAndLoad_resId() throws InterruptedException {
- setCaller(CALLING_PACKAGE_1, USER_10);
-
- final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
- getTestContext().getResources(), R.drawable.black_32x32));
-
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
- ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
- .setId("id")
- .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
- .setIcon(bmp32x32)
- .setTitleResId(10)
- .setTextResId(11)
- .setDisabledMessageResId(12)
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setRank(123)
- .setExtras(pb)
- .build();
-
- mManager.addDynamicShortcuts(list(sorig));
-
- Thread.sleep(2);
- final long now = System.currentTimeMillis();
-
- // Save and load.
- mService.saveDirtyInfo();
- initService();
- mService.handleUnlockUser(USER_10);
-
- ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
-
- assertEquals(USER_10, si.getUserId());
- assertEquals(HANDLE_USER_10, si.getUserHandle());
- assertEquals(CALLING_PACKAGE_1, si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
- assertEquals(null, si.getIcon());
- assertEquals(10, si.getTitleResId());
- assertEquals(11, si.getTextResId());
- assertEquals(12, si.getDisabledMessageResId());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE, si.getFlags());
- assertNotNull(si.getBitmapPath()); // Something should be set.
- assertEquals(0, si.getIconResourceId());
- assertTrue(si.getLastChangedTimestamp() < now);
- }
-
- public void testShortcutInfoSaveAndLoad_forBackup() {
- setCaller(CALLING_PACKAGE_1, USER_0);
-
- final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
- getTestContext().getResources(), R.drawable.black_32x32));
-
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
- ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
- .setId("id")
- .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
- .setIcon(bmp32x32)
- .setTitle("title")
- .setText("text")
- .setDisabledMessage("dismes")
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setRank(123)
- .setExtras(pb)
- .build();
-
- mManager.addDynamicShortcuts(list(sorig));
-
- // Dynamic shortcuts won't be backed up, so we need to pin it.
- setCaller(LAUNCHER_1, USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0);
-
- // Do backup & restore.
- backupAndRestore();
-
- mService.handleUnlockUser(USER_0); // Load user-0.
-
- ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
-
- assertEquals(CALLING_PACKAGE_1, si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
- assertEquals(null, si.getIcon());
- assertEquals("title", si.getTitle());
- assertEquals("text", si.getText());
- assertEquals("dismes", si.getDisabledMessage());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertNull(si.getBitmapPath()); // No icon.
- assertEquals(0, si.getIconResourceId());
- }
-
- public void testShortcutInfoSaveAndLoad_forBackup_resId() {
- setCaller(CALLING_PACKAGE_1, USER_0);
-
- final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
- getTestContext().getResources(), R.drawable.black_32x32));
-
- PersistableBundle pb = new PersistableBundle();
- pb.putInt("k", 1);
- ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
- .setId("id")
- .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
- .setIcon(bmp32x32)
- .setTitleResId(10)
- .setTextResId(11)
- .setDisabledMessageResId(12)
- .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
- .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
- .setRank(123)
- .setExtras(pb)
- .build();
-
- mManager.addDynamicShortcuts(list(sorig));
-
- // Dynamic shortcuts won't be backed up, so we need to pin it.
- setCaller(LAUNCHER_1, USER_0);
- mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0);
-
- // Do backup & restore.
- backupAndRestore();
-
- mService.handleUnlockUser(USER_0); // Load user-0.
-
- ShortcutInfo si;
- si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
-
- assertEquals(CALLING_PACKAGE_1, si.getPackage());
- assertEquals("id", si.getId());
- assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
- assertEquals(null, si.getIcon());
- assertEquals(10, si.getTitleResId());
- assertEquals(11, si.getTextResId());
- assertEquals(12, si.getDisabledMessageResId());
- assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
- assertEquals("action", si.getIntent().getAction());
- assertEquals("val", si.getIntent().getStringExtra("key"));
- assertEquals(123, si.getRank());
- assertEquals(1, si.getExtras().getInt("k"));
-
- assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
- assertNull(si.getBitmapPath()); // No icon.
- assertEquals(0, si.getIconResourceId());
- }
-
public void testDumpsys_crossProfile() {
prepareCrossProfileDataSet();
dumpsysOnLogcat("test1", /* force= */ true);
@@ -7547,11 +4787,12 @@
si.getActivity());
assertEquals(R.string.shortcut_title1, si.getTitleResId());
assertEquals(R.string.shortcut_text1, si.getTextResId());
- assertEquals(R.string.shortcut_disabled_message1, si.getDisabledMessageResId());
+ assertEquals(R.string.shortcut_disabled_message1, si.getDisabledMessageResourceId());
assertEquals(set("android.shortcut.conversation", "android.shortcut.media"),
si.getCategories());
assertEquals("action1", si.getIntent().getAction());
assertEquals(Uri.parse("http://a.b.c/1"), si.getIntent().getData());
+ assertEquals(0, si.getRank());
// check another
si = getCallerShortcut("ms2");
@@ -7560,10 +4801,11 @@
assertEquals(R.drawable.icon2, si.getIconResourceId());
assertEquals(R.string.shortcut_title2, si.getTitleResId());
assertEquals(R.string.shortcut_text2, si.getTextResId());
- assertEquals(R.string.shortcut_disabled_message2, si.getDisabledMessageResId());
+ assertEquals(R.string.shortcut_disabled_message2, si.getDisabledMessageResourceId());
assertEquals(set("android.shortcut.conversation"), si.getCategories());
assertEquals("action2", si.getIntent().getAction());
assertEquals(null, si.getIntent().getData());
+ assertEquals(1, si.getRank());
// check another
si = getCallerShortcut("ms3");
@@ -7572,10 +4814,11 @@
assertEquals(0, si.getIconResourceId());
assertEquals(R.string.shortcut_title1, si.getTitleResId());
assertEquals(0, si.getTextResId());
- assertEquals(0, si.getDisabledMessageResId());
+ assertEquals(0, si.getDisabledMessageResourceId());
assertEquals(null, si.getCategories());
assertEquals("android.intent.action.VIEW", si.getIntent().getAction());
assertEquals(null, si.getIntent().getData());
+ assertEquals(2, si.getRank());
});
}
@@ -7667,7 +4910,7 @@
assertEquals(R.drawable.icon2, si.getIconResourceId());
assertEquals(R.string.shortcut_title2, si.getTitleResId());
assertEquals(R.string.shortcut_text2, si.getTextResId());
- assertEquals(R.string.shortcut_disabled_message2, si.getDisabledMessageResId());
+ assertEquals(R.string.shortcut_disabled_message2, si.getDisabledMessageResourceId());
assertEquals(Intent.ACTION_VIEW, si.getIntent().getAction());
// Make sure there's no other dangling shortcuts.
@@ -7749,10 +4992,10 @@
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
mManager.setDynamicShortcuts(list(
makeShortcut("ms1", "title1",
- new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
/* icon */ null, new Intent("action1"), /* rank */ 0),
makeShortcut("ms2", "title2",
- new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
/* icon */ null, new Intent("action1"), /* rank */ 0)));
});
@@ -7792,7 +5035,7 @@
});
}
- private void checkManifestShortcuts_immutable_verify() {
+ protected void checkManifestShortcuts_immutable_verify() {
runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
assertShortcutIds(assertAllNotManifest(assertAllEnabled(
mManager.getDynamicShortcuts())),
@@ -7902,4 +5145,434 @@
});
checkManifestShortcuts_immutable_verify();
}
+
+
+ /**
+ * Make sure the APIs won't work on manifest shortcuts.
+ */
+ public void testManifestShortcuts_tooMany() {
+ // Change the max number of shortcuts.
+ mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
+
+ mService.handleUnlockUser(USER_0);
+
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ R.xml.shortcut_5);
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ // Only the first 3 should be published.
+ assertShortcutIds(mManager.getManifestShortcuts(), "ms1", "ms2", "ms3");
+ });
+ }
+
+ public void testMaxShortcutCount_set() {
+ // Change the max number of shortcuts.
+ mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
+ final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
+ final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
+ final ShortcutInfo s1_2 = makeShortcutWithActivity("s12", a1);
+ final ShortcutInfo s1_3 = makeShortcutWithActivity("s13", a1);
+ final ShortcutInfo s1_4 = makeShortcutWithActivity("s14", a1);
+ final ShortcutInfo s1_5 = makeShortcutWithActivity("s15", a1);
+ final ShortcutInfo s1_6 = makeShortcutWithActivity("s16", a1);
+ final ShortcutInfo s2_1 = makeShortcutWithActivity("s21", a2);
+ final ShortcutInfo s2_2 = makeShortcutWithActivity("s22", a2);
+ final ShortcutInfo s2_3 = makeShortcutWithActivity("s23", a2);
+ final ShortcutInfo s2_4 = makeShortcutWithActivity("s24", a2);
+
+ // 3 shortcuts for 2 activities -> okay
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13", "s21", "s22", "s23");
+
+ mManager.removeAllDynamicShortcuts();
+
+ // 4 shortcut for activity 1 -> too many.
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s1_4, s2_1, s2_2, s2_3));
+ });
+ assertEmpty(mManager.getDynamicShortcuts());
+
+ // 4 shortcut for activity 2 -> too many.
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3, s2_4));
+ });
+ assertEmpty(mManager.getDynamicShortcuts());
+
+ // First, set 3. Then set 4, which should be ignored.
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13");
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.setDynamicShortcuts(list(s2_1, s2_2, s2_3, s2_4));
+ });
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13");
+
+ // Set will remove the old dynamic set, unlike add, so the following should pass.
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13");
+ mManager.setDynamicShortcuts(list(s1_4, s1_5, s1_6));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s14", "s15", "s16");
+
+ // Now, test with 2 manifest shortcuts.
+ mManager.removeAllDynamicShortcuts();
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ R.xml.shortcut_2);
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ assertEquals(2, mManager.getManifestShortcuts().size());
+
+ // Setting 1 to activity 1 will work.
+ mManager.setDynamicShortcuts(list(s1_1, s2_1, s2_2, s2_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s21", "s22", "s23");
+ assertEquals(2, mManager.getManifestShortcuts().size());
+
+ // But setting 2 will not.
+ mManager.removeAllDynamicShortcuts();
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s2_1, s2_2, s2_3));
+ });
+ assertEmpty(mManager.getDynamicShortcuts());
+ assertEquals(2, mManager.getManifestShortcuts().size());
+ });
+ }
+
+ public void testMaxShortcutCount_add() {
+ // Change the max number of shortcuts.
+ mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
+ final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
+ final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
+ final ShortcutInfo s1_2 = makeShortcutWithActivity("s12", a1);
+ final ShortcutInfo s1_3 = makeShortcutWithActivity("s13", a1);
+ final ShortcutInfo s1_4 = makeShortcutWithActivity("s14", a1);
+ final ShortcutInfo s2_1 = makeShortcutWithActivity("s21", a2);
+ final ShortcutInfo s2_2 = makeShortcutWithActivity("s22", a2);
+ final ShortcutInfo s2_3 = makeShortcutWithActivity("s23", a2);
+ final ShortcutInfo s2_4 = makeShortcutWithActivity("s24", a2);
+
+ // 3 shortcuts for 2 activities -> okay
+ mManager.addDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13", "s21", "s22", "s23");
+
+ mManager.removeAllDynamicShortcuts();
+
+ // 4 shortcut for activity 1 -> too many.
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.addDynamicShortcuts(list(s1_1, s1_2, s1_3, s1_4, s2_1, s2_2, s2_3));
+ });
+ assertEmpty(mManager.getDynamicShortcuts());
+
+ // 4 shortcut for activity 2 -> too many.
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.addDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3, s2_4));
+ });
+ assertEmpty(mManager.getDynamicShortcuts());
+
+ // First, set 3. Then add 1 more, which should be ignored.
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13");
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.addDynamicShortcuts(list(s1_4, s2_1));
+ });
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13");
+
+ // Update existing one, which should work.
+ mManager.addDynamicShortcuts(list(makeShortcutWithActivityAndTitle(
+ "s11", a1, "xxx"), s2_1));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13", "s21");
+ assertEquals("xxx", getCallerShortcut("s11").getTitle());
+
+ // Make sure pinned shortcuts won't affect.
+ // - Pin s11 - s13, and remove all dynamic.
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s13"),
+ HANDLE_USER_0);
+ });
+ mManager.removeAllDynamicShortcuts();
+
+ assertEmpty(mManager.getDynamicShortcuts());
+ assertShortcutIds(mManager.getPinnedShortcuts(),
+ "s11", "s12", "s13");
+
+ // Then add dynamic.
+ mManager.addDynamicShortcuts(list(s1_4, s2_1, s2_2, s2_3));
+
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s14", "s21", "s22", "s23");
+ assertShortcutIds(mManager.getPinnedShortcuts(),
+ "s11", "s12", "s13");
+
+ // Adding "s11" and "s12" back, should work
+ mManager.addDynamicShortcuts(list(s1_1, s1_2));
+
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s14", "s11", "s12", "s21", "s22", "s23");
+ assertShortcutIds(mManager.getPinnedShortcuts(),
+ "s11", "s12", "s13");
+
+ // Adding back s13 doesn't work.
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.addDynamicShortcuts(list(s1_3));
+ });
+
+ assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
+ "s11", "s12", "s14");
+ assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
+ "s21", "s22", "s23");
+
+ // Now swap the activities.
+ mManager.updateShortcuts(list(
+ makeShortcutWithActivity("s11", a2),
+ makeShortcutWithActivity("s21", a1)));
+
+ assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
+ "s21", "s12", "s14");
+ assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
+ "s11", "s22", "s23");
+
+ // Now, test with 2 manifest shortcuts.
+ mManager.removeAllDynamicShortcuts();
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ R.xml.shortcut_2);
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+
+ assertEquals(2, mManager.getManifestShortcuts().size());
+
+ // Adding one shortcut to activity 1 works fine.
+ mManager.addDynamicShortcuts(list(s1_1, s2_1, s2_2, s2_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s21", "s22", "s23");
+ assertEquals(2, mManager.getManifestShortcuts().size());
+
+ // But adding one more doesn't.
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.addDynamicShortcuts(list(s1_4, s2_1));
+ });
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s21", "s22", "s23");
+ assertEquals(2, mManager.getManifestShortcuts().size());
+ });
+ }
+
+ public void testMaxShortcutCount_update() {
+ // Change the max number of shortcuts.
+ mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
+ final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
+ final ShortcutInfo s1_1 = makeShortcutWithActivity("s11", a1);
+ final ShortcutInfo s1_2 = makeShortcutWithActivity("s12", a1);
+ final ShortcutInfo s1_3 = makeShortcutWithActivity("s13", a1);
+ final ShortcutInfo s1_4 = makeShortcutWithActivity("s14", a1);
+ final ShortcutInfo s1_5 = makeShortcutWithActivity("s15", a1);
+ final ShortcutInfo s2_1 = makeShortcutWithActivity("s21", a2);
+ final ShortcutInfo s2_2 = makeShortcutWithActivity("s22", a2);
+ final ShortcutInfo s2_3 = makeShortcutWithActivity("s23", a2);
+ final ShortcutInfo s2_4 = makeShortcutWithActivity("s24", a2);
+
+ // 3 shortcuts for 2 activities -> okay
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13", "s21", "s22", "s23");
+
+ // Trying to move s11 from a1 to a2 should fail.
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.updateShortcuts(list(makeShortcutWithActivity("s11", a2)));
+ });
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13", "s21", "s22", "s23");
+
+ // Trying to move s21 from a2 to a1 should also fail.
+ assertDynamicShortcutCountExceeded(() -> {
+ mManager.updateShortcuts(list(makeShortcutWithActivity("s21", a1)));
+ });
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13", "s21", "s22", "s23");
+
+ // But, if we do these two at the same time, it should work.
+ mManager.updateShortcuts(list(
+ makeShortcutWithActivity("s11", a2),
+ makeShortcutWithActivity("s21", a1)));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13", "s21", "s22", "s23");
+ assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
+ "s21", "s12", "s13");
+ assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
+ "s11", "s22", "s23");
+
+ // Then reset.
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s11", "s12", "s13", "s21", "s22", "s23");
+
+ // Pin some to have more shortcuts for a1.
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s13"),
+ HANDLE_USER_0);
+ });
+ mManager.setDynamicShortcuts(list(s1_4, s1_5, s2_1, s2_2, s2_3));
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s14", "s15", "s21", "s22", "s23");
+ assertShortcutIds(mManager.getPinnedShortcuts(),
+ "s11", "s12", "s13");
+
+ // a1 already has 2 dynamic shortcuts (and 3 pinned shortcuts that used to belong on it)
+ // But that doesn't matter for update -- the following should still work.
+ mManager.updateShortcuts(list(
+ makeShortcutWithActivityAndTitle("s11", a1, "xxx1"),
+ makeShortcutWithActivityAndTitle("s12", a1, "xxx2"),
+ makeShortcutWithActivityAndTitle("s13", a1, "xxx3"),
+ makeShortcutWithActivityAndTitle("s14", a1, "xxx4"),
+ makeShortcutWithActivityAndTitle("s15", a1, "xxx5")));
+ // All the shortcuts should still exist they all belong on same activities,
+ // with the updated titles.
+ assertShortcutIds(mManager.getDynamicShortcuts(),
+ "s14", "s15", "s21", "s22", "s23");
+ assertShortcutIds(mManager.getPinnedShortcuts(),
+ "s11", "s12", "s13");
+
+ assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a1),
+ "s14", "s15");
+ assertShortcutIds(filterByActivity(mManager.getDynamicShortcuts(), a2),
+ "s21", "s22", "s23");
+
+ assertEquals("xxx1", getCallerShortcut("s11").getTitle());
+ assertEquals("xxx2", getCallerShortcut("s12").getTitle());
+ assertEquals("xxx3", getCallerShortcut("s13").getTitle());
+ assertEquals("xxx4", getCallerShortcut("s14").getTitle());
+ assertEquals("xxx5", getCallerShortcut("s15").getTitle());
+ });
+ }
+
+ public void testShortcutsPushedOutByManifest() {
+ // Change the max number of shortcuts.
+ mService.updateConfigurationLocked(ConfigConstants.KEY_MAX_SHORTCUTS + "=3");
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ final ComponentName a1 = new ComponentName(mClientContext, ShortcutActivity.class);
+ final ComponentName a2 = new ComponentName(mClientContext, ShortcutActivity2.class);
+ final ShortcutInfo s1_1 = makeShortcutWithActivityAndRank("s11", a1, 4);
+ final ShortcutInfo s1_2 = makeShortcutWithActivityAndRank("s12", a1, 3);
+ final ShortcutInfo s1_3 = makeShortcutWithActivityAndRank("s13", a1, 2);
+ final ShortcutInfo s1_4 = makeShortcutWithActivityAndRank("s14", a1, 1);
+ final ShortcutInfo s1_5 = makeShortcutWithActivityAndRank("s15", a1, 0);
+ final ShortcutInfo s2_1 = makeShortcutWithActivityAndRank("s21", a2, 0);
+ final ShortcutInfo s2_2 = makeShortcutWithActivityAndRank("s22", a2, 1);
+ final ShortcutInfo s2_3 = makeShortcutWithActivityAndRank("s23", a2, 2);
+ final ShortcutInfo s2_4 = makeShortcutWithActivityAndRank("s24", a2, 3);
+ final ShortcutInfo s2_5 = makeShortcutWithActivityAndRank("s25", a2, 4);
+
+ // Initial state.
+ mManager.setDynamicShortcuts(list(s1_1, s1_2, s1_3, s2_1, s2_2, s2_3));
+ runWithCaller(LAUNCHER_1, USER_0, () -> {
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("s11", "s12", "s21", "s22"),
+ HANDLE_USER_0);
+ });
+ mManager.setDynamicShortcuts(list(s1_2, s1_3, s1_4, s2_2, s2_3, s2_4));
+ assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
+ "s12", "s13", "s14",
+ "s22", "s23", "s24");
+ assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
+ "s11", "s12",
+ "s21", "s22");
+
+ // Add 1 manifest shortcut to a1.
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ R.xml.shortcut_1);
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ assertEquals(1, mManager.getManifestShortcuts().size());
+
+ // s12 removed.
+ assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
+ "s13", "s14",
+ "s22", "s23", "s24");
+ assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
+ "s11", "s12",
+ "s21", "s22");
+
+ // Add more manifest shortcuts.
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ R.xml.shortcut_2);
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
+ R.xml.shortcut_1_alt);
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ assertEquals(3, mManager.getManifestShortcuts().size());
+
+ // Note the ones with the highest rank values (== least important) will be removed.
+ assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
+ "s14",
+ "s22", "s23");
+ assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
+ "s11", "s12",
+ "s21", "s22");
+
+ // Add more manifest shortcuts.
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ R.xml.shortcut_2);
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
+ R.xml.shortcut_5_alt); // manifest has 5, but max is 3, so a2 will have 3.
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ assertEquals(5, mManager.getManifestShortcuts().size());
+
+ assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
+ "s14" // a1 has 1 dynamic
+ ); // a2 has no dynamic
+ assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
+ "s11", "s12",
+ "s21", "s22");
+
+ // Update, no manifest shortucts. This doesn't affect anything.
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity.class.getName()),
+ R.xml.shortcut_0);
+ addManifestShortcutResource(
+ new ComponentName(CALLING_PACKAGE_1, ShortcutActivity2.class.getName()),
+ R.xml.shortcut_0);
+ updatePackageVersion(CALLING_PACKAGE_1, 1);
+ mService.mPackageMonitor.onReceive(getTestContext(),
+ genPackageAddIntent(CALLING_PACKAGE_1, USER_0));
+ assertEquals(0, mManager.getManifestShortcuts().size());
+
+ assertShortcutIds(assertAllEnabled(mManager.getDynamicShortcuts()),
+ "s14");
+ assertShortcutIds(assertAllEnabled(mManager.getPinnedShortcuts()),
+ "s11", "s12",
+ "s21", "s22");
+ });
+ }
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
new file mode 100644
index 0000000..5011182
--- /dev/null
+++ b/services/tests/servicestests/src/com/android/server/pm/ShortcutManagerTest2.java
@@ -0,0 +1,1421 @@
+/*
+ * Copyright (C) 2016 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.android.server.pm;
+
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.assertExpectException;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.list;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.parceled;
+import static com.android.server.pm.shortcutmanagertest.ShortcutManagerTestUtils.set;
+
+import android.Manifest.permission;
+import android.app.ActivityManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.pm.ShortcutInfo;
+import android.graphics.BitmapFactory;
+import android.graphics.drawable.Icon;
+import android.os.PersistableBundle;
+import android.os.UserHandle;
+import android.test.MoreAsserts;
+import android.test.suitebuilder.annotation.SmallTest;
+
+import com.android.frameworks.servicestests.R;
+import com.android.server.SystemService;
+
+/**
+ * Tests for ShortcutService and ShortcutManager.
+ *
+ m FrameworksServicesTests &&
+ adb install \
+ -r -g ${ANDROID_PRODUCT_OUT}/data/app/FrameworksServicesTests/FrameworksServicesTests.apk &&
+ adb shell am instrument -e class com.android.server.pm.ShortcutManagerTest2 \
+ -w com.android.frameworks.servicestests/android.support.test.runner.AndroidJUnitRunner
+ */
+@SmallTest
+public class ShortcutManagerTest2 extends BaseShortcutManagerTest {
+ // ShortcutInfo tests
+
+ public void testShortcutInfoMissingMandatoryFields() {
+ assertExpectException(
+ IllegalArgumentException.class,
+ "ID must be provided",
+ () -> new ShortcutInfo.Builder(getTestContext()).build());
+ assertExpectException(
+ NullPointerException.class,
+ "Intent action must be set",
+ () -> new ShortcutInfo.Builder(getTestContext()).setIntent(new Intent()));
+ assertExpectException(
+ NullPointerException.class,
+ "activity must be provided",
+ () -> new ShortcutInfo.Builder(getTestContext()).setId("id").build()
+ .enforceMandatoryFields());
+ assertExpectException(
+ IllegalArgumentException.class,
+ "title must be provided",
+ () -> new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setActivity(
+ new ComponentName(getTestContext().getPackageName(), "s"))
+ .build()
+ .enforceMandatoryFields());
+ assertExpectException(
+ NullPointerException.class,
+ "Intent must be provided",
+ () -> new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setActivity(
+ new ComponentName(getTestContext().getPackageName(), "s"))
+ .setTitle("x").build()
+ .enforceMandatoryFields());
+ }
+
+ public void testShortcutInfoParcel() {
+ setCaller(CALLING_PACKAGE_1, USER_10);
+ ShortcutInfo si = parceled(new ShortcutInfo.Builder(mClientContext)
+ .setId("id")
+ .setTitle("title")
+ .setIntent(makeIntent("action", ShortcutActivity.class))
+ .build());
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals(USER_10, si.getUserId());
+ assertEquals(HANDLE_USER_10, si.getUserHandle());
+ assertEquals("id", si.getId());
+ assertEquals("title", si.getTitle());
+ assertEquals("action", si.getIntent().getAction());
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+
+ si = new ShortcutInfo.Builder(getTestContext())
+ .setId("id")
+ .setActivity(new ComponentName("a", "b"))
+ .setIcon(Icon.createWithResource(mClientContext, 123))
+ .setTitle("title")
+ .setText("text")
+ .setDisabledMessage("dismes")
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+ si.addFlags(ShortcutInfo.FLAG_PINNED);
+ si.setBitmapPath("abc");
+ si.setIconResourceId(456);
+
+ si = parceled(si);
+
+ assertEquals(getTestContext().getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(new ComponentName("a", "b"), si.getActivity());
+ assertEquals(123, si.getIcon().getResId());
+ assertEquals("title", si.getTitle());
+ assertEquals("text", si.getText());
+ assertEquals("dismes", si.getDisabledMessage());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertEquals("abc", si.getBitmapPath());
+ assertEquals(456, si.getIconResourceId());
+ }
+
+ public void testShortcutInfoParcel_resId() {
+ setCaller(CALLING_PACKAGE_1, USER_10);
+ ShortcutInfo si;
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+
+ si = new ShortcutInfo.Builder(getTestContext())
+ .setId("id")
+ .setActivity(new ComponentName("a", "b"))
+ .setIcon(Icon.createWithResource(mClientContext, 123))
+ .setTitleResId(10)
+ .setTextResId(11)
+ .setDisabledMessageResId(12)
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+ si.addFlags(ShortcutInfo.FLAG_PINNED);
+ si.setBitmapPath("abc");
+ si.setIconResourceId(456);
+
+ si = parceled(si);
+
+ assertEquals(getTestContext().getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(new ComponentName("a", "b"), si.getActivity());
+ assertEquals(123, si.getIcon().getResId());
+ assertEquals(10, si.getTitleResId());
+ assertEquals(11, si.getTextResId());
+ assertEquals(12, si.getDisabledMessageResourceId());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertEquals("abc", si.getBitmapPath());
+ assertEquals(456, si.getIconResourceId());
+ }
+
+ public void testShortcutInfoClone() {
+ setCaller(CALLING_PACKAGE_1, USER_11);
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+ .setId("id")
+ .setActivity(new ComponentName("a", "b"))
+ .setIcon(Icon.createWithResource(mClientContext, 123))
+ .setTitle("title")
+ .setText("text")
+ .setDisabledMessage("dismes")
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+ sorig.addFlags(ShortcutInfo.FLAG_PINNED);
+ sorig.setBitmapPath("abc");
+ sorig.setIconResourceId(456);
+
+ ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
+
+ assertEquals(USER_11, si.getUserId());
+ assertEquals(HANDLE_USER_11, si.getUserHandle());
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(new ComponentName("a", "b"), si.getActivity());
+ assertEquals(123, si.getIcon().getResId());
+ assertEquals("title", si.getTitle());
+ assertEquals("text", si.getText());
+ assertEquals("dismes", si.getDisabledMessage());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertEquals("abc", si.getBitmapPath());
+ assertEquals(456, si.getIconResourceId());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
+
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(new ComponentName("a", "b"), si.getActivity());
+ assertEquals(null, si.getIcon());
+ assertEquals("title", si.getTitle());
+ assertEquals("text", si.getText());
+ assertEquals("dismes", si.getDisabledMessage());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertEquals(null, si.getBitmapPath());
+
+ assertEquals(456, si.getIconResourceId());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
+
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(new ComponentName("a", "b"), si.getActivity());
+ assertEquals(null, si.getIcon());
+ assertEquals("title", si.getTitle());
+ assertEquals("text", si.getText());
+ assertEquals("dismes", si.getDisabledMessage());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals(null, si.getIntent());
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertEquals(null, si.getBitmapPath());
+
+ assertEquals(456, si.getIconResourceId());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
+
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(null, si.getActivity());
+ assertEquals(null, si.getIcon());
+ assertEquals(null, si.getTitle());
+ assertEquals(null, si.getText());
+ assertEquals(null, si.getDisabledMessage());
+ assertEquals(null, si.getCategories());
+ assertEquals(null, si.getIntent());
+ assertEquals(0, si.getRank());
+ assertEquals(null, si.getExtras());
+
+ assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
+ assertEquals(null, si.getBitmapPath());
+
+ assertEquals(456, si.getIconResourceId());
+ }
+
+ public void testShortcutInfoClone_resId() {
+ setCaller(CALLING_PACKAGE_1, USER_11);
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+ .setId("id")
+ .setActivity(new ComponentName("a", "b"))
+ .setIcon(Icon.createWithResource(mClientContext, 123))
+ .setTitleResId(10)
+ .setTextResId(11)
+ .setDisabledMessageResId(12)
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+ sorig.addFlags(ShortcutInfo.FLAG_PINNED);
+ sorig.setBitmapPath("abc");
+ sorig.setIconResourceId(456);
+
+ ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
+
+ assertEquals(USER_11, si.getUserId());
+ assertEquals(HANDLE_USER_11, si.getUserHandle());
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(new ComponentName("a", "b"), si.getActivity());
+ assertEquals(123, si.getIcon().getResId());
+ assertEquals(10, si.getTitleResId());
+ assertEquals(11, si.getTextResId());
+ assertEquals(12, si.getDisabledMessageResourceId());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertEquals("abc", si.getBitmapPath());
+ assertEquals(456, si.getIconResourceId());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
+
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(new ComponentName("a", "b"), si.getActivity());
+ assertEquals(null, si.getIcon());
+ assertEquals(10, si.getTitleResId());
+ assertEquals(11, si.getTextResId());
+ assertEquals(12, si.getDisabledMessageResourceId());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertEquals(null, si.getBitmapPath());
+
+ assertEquals(456, si.getIconResourceId());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
+
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(new ComponentName("a", "b"), si.getActivity());
+ assertEquals(null, si.getIcon());
+ assertEquals(10, si.getTitleResId());
+ assertEquals(11, si.getTextResId());
+ assertEquals(12, si.getDisabledMessageResourceId());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals(null, si.getIntent());
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertEquals(null, si.getBitmapPath());
+
+ assertEquals(456, si.getIconResourceId());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
+
+ assertEquals(mClientContext.getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(null, si.getActivity());
+ assertEquals(null, si.getIcon());
+ assertEquals(0, si.getTitleResId());
+ assertEquals(0, si.getTextResId());
+ assertEquals(0, si.getDisabledMessageResourceId());
+ assertEquals(null, si.getCategories());
+ assertEquals(null, si.getIntent());
+ assertEquals(0, si.getRank());
+ assertEquals(null, si.getExtras());
+
+ assertEquals(ShortcutInfo.FLAG_PINNED | ShortcutInfo.FLAG_KEY_FIELDS_ONLY, si.getFlags());
+ assertEquals(null, si.getBitmapPath());
+
+ assertEquals(456, si.getIconResourceId());
+ }
+
+ public void testShortcutInfoClone_minimum() {
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
+ .setId("id")
+ .setTitle("title")
+ .setIntent(makeIntent("action", ShortcutActivity.class))
+ .build();
+ ShortcutInfo si = sorig.clone(/* clone flags*/ 0);
+
+ assertEquals(getTestContext().getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals("title", si.getTitle());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals(null, si.getCategories());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_CREATOR);
+
+ assertEquals(getTestContext().getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals("title", si.getTitle());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals(null, si.getCategories());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_FOR_LAUNCHER);
+
+ assertEquals(getTestContext().getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals("title", si.getTitle());
+ assertEquals(null, si.getIntent());
+ assertEquals(null, si.getCategories());
+
+ si = sorig.clone(ShortcutInfo.CLONE_REMOVE_NON_KEY_INFO);
+
+ assertEquals(getTestContext().getPackageName(), si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(null, si.getTitle());
+ assertEquals(null, si.getIntent());
+ assertEquals(null, si.getCategories());
+ }
+
+ public void testShortcutInfoCopyNonNullFieldsFrom() throws InterruptedException {
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
+ .setId("id")
+ .setActivity(new ComponentName("a", "b"))
+ .setIcon(Icon.createWithResource(mClientContext, 123))
+ .setTitle("title")
+ .setText("text")
+ .setDisabledMessage("dismes")
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+ sorig.addFlags(ShortcutInfo.FLAG_PINNED);
+ sorig.setBitmapPath("abc");
+ sorig.setIconResourceId(456);
+
+ ShortcutInfo si;
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setActivity(new ComponentName("x", "y")).build());
+ assertEquals("text", si.getText());
+ assertEquals(new ComponentName("x", "y"), si.getActivity());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setIcon(Icon.createWithResource(mClientContext, 456)).build());
+ assertEquals("text", si.getText());
+ assertEquals(456, si.getIcon().getResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setTitle("xyz").build());
+ assertEquals("text", si.getText());
+ assertEquals("xyz", si.getTitle());
+ assertEquals(0, si.getTitleResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setTitleResId(123).build());
+ assertEquals("text", si.getText());
+ assertEquals(null, si.getTitle());
+ assertEquals(123, si.getTitleResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setText("xxx").build());
+ assertEquals(123, si.getRank());
+ assertEquals("xxx", si.getText());
+ assertEquals(0, si.getTextResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setTextResId(1111).build());
+ assertEquals(123, si.getRank());
+ assertEquals(null, si.getText());
+ assertEquals(1111, si.getTextResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setDisabledMessage("xxx").build());
+ assertEquals(123, si.getRank());
+ assertEquals("xxx", si.getDisabledMessage());
+ assertEquals(0, si.getDisabledMessageResourceId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setDisabledMessageResId(11111).build());
+ assertEquals(123, si.getRank());
+ assertEquals(null, si.getDisabledMessage());
+ assertEquals(11111, si.getDisabledMessageResourceId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setCategories(set()).build());
+ assertEquals("text", si.getText());
+ assertEquals(set(), si.getCategories());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setCategories(set("x")).build());
+ assertEquals("text", si.getText());
+ assertEquals(set("x"), si.getCategories());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setIntent(makeIntent("action2", ShortcutActivity.class)).build());
+ assertEquals("text", si.getText());
+ assertEquals("action2", si.getIntent().getAction());
+ assertEquals(null, si.getIntent().getStringExtra("key"));
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build());
+ assertEquals("text", si.getText());
+ assertEquals("action3", si.getIntent().getAction());
+ assertEquals("x", si.getIntent().getStringExtra("key"));
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setRank(999).build());
+ assertEquals("text", si.getText());
+ assertEquals(999, si.getRank());
+
+
+ PersistableBundle pb2 = new PersistableBundle();
+ pb2.putInt("x", 99);
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setExtras(pb2).build());
+ assertEquals("text", si.getText());
+ assertEquals(99, si.getExtras().getInt("x"));
+
+ // Make sure the timestamp gets updated too.
+
+ final long timestamp = si.getLastChangedTimestamp();
+ Thread.sleep(2);
+
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setTitle("xyz").build());
+
+ assertTrue(si.getLastChangedTimestamp() > timestamp);
+ }
+
+ public void testShortcutInfoCopyNonNullFieldsFrom_resId() throws InterruptedException {
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(getTestContext())
+ .setId("id")
+ .setActivity(new ComponentName("a", "b"))
+ .setIcon(Icon.createWithResource(mClientContext, 123))
+ .setTitleResId(10)
+ .setTextResId(11)
+ .setDisabledMessageResId(12)
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+ sorig.addFlags(ShortcutInfo.FLAG_PINNED);
+ sorig.setBitmapPath("abc");
+ sorig.setIconResourceId(456);
+
+ ShortcutInfo si;
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setActivity(new ComponentName("x", "y")).build());
+ assertEquals(11, si.getTextResId());
+ assertEquals(new ComponentName("x", "y"), si.getActivity());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setIcon(Icon.createWithResource(mClientContext, 456)).build());
+ assertEquals(11, si.getTextResId());
+ assertEquals(456, si.getIcon().getResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setTitle("xyz").build());
+ assertEquals(11, si.getTextResId());
+ assertEquals("xyz", si.getTitle());
+ assertEquals(0, si.getTitleResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setTitleResId(123).build());
+ assertEquals(11, si.getTextResId());
+ assertEquals(null, si.getTitle());
+ assertEquals(123, si.getTitleResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setText("xxx").build());
+ assertEquals(123, si.getRank());
+ assertEquals("xxx", si.getText());
+ assertEquals(0, si.getTextResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setTextResId(1111).build());
+ assertEquals(123, si.getRank());
+ assertEquals(null, si.getText());
+ assertEquals(1111, si.getTextResId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setDisabledMessage("xxx").build());
+ assertEquals(123, si.getRank());
+ assertEquals("xxx", si.getDisabledMessage());
+ assertEquals(0, si.getDisabledMessageResourceId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setDisabledMessageResId(11111).build());
+ assertEquals(123, si.getRank());
+ assertEquals(null, si.getDisabledMessage());
+ assertEquals(11111, si.getDisabledMessageResourceId());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setCategories(set()).build());
+ assertEquals(11, si.getTextResId());
+ assertEquals(set(), si.getCategories());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setCategories(set("x")).build());
+ assertEquals(11, si.getTextResId());
+ assertEquals(set("x"), si.getCategories());
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setIntent(makeIntent("action2", ShortcutActivity.class)).build());
+ assertEquals(11, si.getTextResId());
+ assertEquals("action2", si.getIntent().getAction());
+ assertEquals(null, si.getIntent().getStringExtra("key"));
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setIntent(makeIntent("action3", ShortcutActivity.class, "key", "x")).build());
+ assertEquals(11, si.getTextResId());
+ assertEquals("action3", si.getIntent().getAction());
+ assertEquals("x", si.getIntent().getStringExtra("key"));
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setRank(999).build());
+ assertEquals(11, si.getTextResId());
+ assertEquals(999, si.getRank());
+
+
+ PersistableBundle pb2 = new PersistableBundle();
+ pb2.putInt("x", 99);
+
+ si = sorig.clone(/* flags=*/ 0);
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setExtras(pb2).build());
+ assertEquals(11, si.getTextResId());
+ assertEquals(99, si.getExtras().getInt("x"));
+
+ // Make sure the timestamp gets updated too.
+
+ final long timestamp = si.getLastChangedTimestamp();
+ Thread.sleep(2);
+
+ si.copyNonNullFieldsFrom(new ShortcutInfo.Builder(getTestContext()).setId("id")
+ .setTitle("xyz").build());
+
+ assertTrue(si.getLastChangedTimestamp() > timestamp);
+ }
+
+ public void testShortcutInfoSaveAndLoad() throws InterruptedException {
+ setCaller(CALLING_PACKAGE_1, USER_10);
+
+ final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
+ getTestContext().getResources(), R.drawable.black_32x32));
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+ .setId("id")
+ .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+ .setIcon(bmp32x32)
+ .setTitle("title")
+ .setText("text")
+ .setDisabledMessage("dismes")
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+
+ mManager.addDynamicShortcuts(list(sorig));
+
+ Thread.sleep(2);
+ final long now = System.currentTimeMillis();
+
+ // Save and load.
+ mService.saveDirtyInfo();
+ initService();
+ mService.handleUnlockUser(USER_10);
+
+ ShortcutInfo si;
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
+
+ assertEquals(USER_10, si.getUserId());
+ assertEquals(HANDLE_USER_10, si.getUserHandle());
+ assertEquals(CALLING_PACKAGE_1, si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+ assertEquals(null, si.getIcon());
+ assertEquals("title", si.getTitle());
+ assertEquals("text", si.getText());
+ assertEquals("dismes", si.getDisabledMessage());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE, si.getFlags());
+ assertNotNull(si.getBitmapPath()); // Something should be set.
+ assertEquals(0, si.getIconResourceId());
+ assertTrue(si.getLastChangedTimestamp() < now);
+ }
+
+ public void testShortcutInfoSaveAndLoad_resId() throws InterruptedException {
+ setCaller(CALLING_PACKAGE_1, USER_10);
+
+ final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
+ getTestContext().getResources(), R.drawable.black_32x32));
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+ .setId("id")
+ .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+ .setIcon(bmp32x32)
+ .setTitleResId(10)
+ .setTextResId(11)
+ .setDisabledMessageResId(12)
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+
+ mManager.addDynamicShortcuts(list(sorig));
+
+ Thread.sleep(2);
+ final long now = System.currentTimeMillis();
+
+ // Save and load.
+ mService.saveDirtyInfo();
+ initService();
+ mService.handleUnlockUser(USER_10);
+
+ ShortcutInfo si;
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_10);
+
+ assertEquals(USER_10, si.getUserId());
+ assertEquals(HANDLE_USER_10, si.getUserHandle());
+ assertEquals(CALLING_PACKAGE_1, si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+ assertEquals(null, si.getIcon());
+ assertEquals(10, si.getTitleResId());
+ assertEquals(11, si.getTextResId());
+ assertEquals(12, si.getDisabledMessageResourceId());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_DYNAMIC | ShortcutInfo.FLAG_HAS_ICON_FILE, si.getFlags());
+ assertNotNull(si.getBitmapPath()); // Something should be set.
+ assertEquals(0, si.getIconResourceId());
+ assertTrue(si.getLastChangedTimestamp() < now);
+ }
+
+ public void testShortcutInfoSaveAndLoad_forBackup() {
+ setCaller(CALLING_PACKAGE_1, USER_0);
+
+ final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
+ getTestContext().getResources(), R.drawable.black_32x32));
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+ .setId("id")
+ .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+ .setIcon(bmp32x32)
+ .setTitle("title")
+ .setText("text")
+ .setDisabledMessage("dismes")
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+
+ mManager.addDynamicShortcuts(list(sorig));
+
+ // Dynamic shortcuts won't be backed up, so we need to pin it.
+ setCaller(LAUNCHER_1, USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0);
+
+ // Do backup & restore.
+ backupAndRestore();
+
+ mService.handleUnlockUser(USER_0); // Load user-0.
+
+ ShortcutInfo si;
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
+
+ assertEquals(CALLING_PACKAGE_1, si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+ assertEquals(null, si.getIcon());
+ assertEquals("title", si.getTitle());
+ assertEquals("text", si.getText());
+ assertEquals("dismes", si.getDisabledMessage());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertNull(si.getBitmapPath()); // No icon.
+ assertEquals(0, si.getIconResourceId());
+ }
+
+ public void testShortcutInfoSaveAndLoad_forBackup_resId() {
+ setCaller(CALLING_PACKAGE_1, USER_0);
+
+ final Icon bmp32x32 = Icon.createWithBitmap(BitmapFactory.decodeResource(
+ getTestContext().getResources(), R.drawable.black_32x32));
+
+ PersistableBundle pb = new PersistableBundle();
+ pb.putInt("k", 1);
+ ShortcutInfo sorig = new ShortcutInfo.Builder(mClientContext)
+ .setId("id")
+ .setActivity(new ComponentName(mClientContext, ShortcutActivity2.class))
+ .setIcon(bmp32x32)
+ .setTitleResId(10)
+ .setTextResId(11)
+ .setDisabledMessageResId(12)
+ .setCategories(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"))
+ .setIntent(makeIntent("action", ShortcutActivity.class, "key", "val"))
+ .setRank(123)
+ .setExtras(pb)
+ .build();
+
+ mManager.addDynamicShortcuts(list(sorig));
+
+ // Dynamic shortcuts won't be backed up, so we need to pin it.
+ setCaller(LAUNCHER_1, USER_0);
+ mLauncherApps.pinShortcuts(CALLING_PACKAGE_1, list("id"), HANDLE_USER_0);
+
+ // Do backup & restore.
+ backupAndRestore();
+
+ mService.handleUnlockUser(USER_0); // Load user-0.
+
+ ShortcutInfo si;
+ si = mService.getPackageShortcutForTest(CALLING_PACKAGE_1, "id", USER_0);
+
+ assertEquals(CALLING_PACKAGE_1, si.getPackage());
+ assertEquals("id", si.getId());
+ assertEquals(ShortcutActivity2.class.getName(), si.getActivity().getClassName());
+ assertEquals(null, si.getIcon());
+ assertEquals(10, si.getTitleResId());
+ assertEquals(11, si.getTextResId());
+ assertEquals(12, si.getDisabledMessageResourceId());
+ assertEquals(set(ShortcutInfo.SHORTCUT_CATEGORY_CONVERSATION, "xyz"), si.getCategories());
+ assertEquals("action", si.getIntent().getAction());
+ assertEquals("val", si.getIntent().getStringExtra("key"));
+ assertEquals(123, si.getRank());
+ assertEquals(1, si.getExtras().getInt("k"));
+
+ assertEquals(ShortcutInfo.FLAG_PINNED, si.getFlags());
+ assertNull(si.getBitmapPath()); // No icon.
+ assertEquals(0, si.getIconResourceId());
+ }
+
+
+ public void testThrottling() {
+ final ShortcutInfo si1 = makeShortcut("shortcut1");
+
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(2, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(1, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(0, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
+
+ // Reached the max
+
+ mInjectedCurrentTimeMillis++;
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(0, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
+
+ // Still throttled
+ mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(0, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
+
+ // Now it should work.
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1))); // fail
+ assertEquals(2, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(1, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(0, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
+
+ mInjectedCurrentTimeMillis++;
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(0, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL * 2, mManager.getRateLimitResetTime());
+
+ // 4 hours later...
+ mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(2, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(1, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL * 5, mManager.getRateLimitResetTime());
+
+ // Make sure getRemainingCallCount() itself gets reset without calling setDynamicShortcuts().
+ mInjectedCurrentTimeMillis = START_TIME + 8 * INTERVAL;
+ assertEquals(3, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(2, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL * 9, mManager.getRateLimitResetTime());
+ }
+
+ public void testThrottling_rewind() {
+ final ShortcutInfo si1 = makeShortcut("shortcut1");
+
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(2, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
+
+ mInjectedCurrentTimeMillis = 12345; // Clock reset!
+
+ // Since the clock looks invalid, the counter shouldn't have reset.
+ assertEquals(2, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
+
+ // Forward again. Still haven't reset yet.
+ mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
+ assertEquals(2, mManager.getRemainingCallCount());
+ assertEquals(START_TIME + INTERVAL, mManager.getRateLimitResetTime());
+
+ // Now rewind -- this will reset the counters.
+ mInjectedCurrentTimeMillis = START_TIME - 100000;
+ assertEquals(3, mManager.getRemainingCallCount());
+
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(2, mManager.getRemainingCallCount());
+
+ // Forward again, should be reset now.
+ mInjectedCurrentTimeMillis += INTERVAL;
+ assertEquals(3, mManager.getRemainingCallCount());
+ }
+
+ public void testThrottling_perPackage() {
+ final ShortcutInfo si1 = makeShortcut("shortcut1");
+
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(2, mManager.getRemainingCallCount());
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(1, mManager.getRemainingCallCount());
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(0, mManager.getRemainingCallCount());
+
+ // Reached the max
+
+ mInjectedCurrentTimeMillis++;
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
+
+ // Try from a different caller.
+ mInjectedClientPackage = CALLING_PACKAGE_2;
+ mInjectedCallingUid = CALLING_UID_2;
+
+ // Need to create a new one wit the updated package name.
+ final ShortcutInfo si2 = makeShortcut("shortcut1");
+
+ assertEquals(3, mManager.getRemainingCallCount());
+
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
+ assertEquals(2, mManager.getRemainingCallCount());
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
+ assertEquals(1, mManager.getRemainingCallCount());
+
+ // Back to the original caller, still throttled.
+ mInjectedClientPackage = CALLING_PACKAGE_1;
+ mInjectedCallingUid = CALLING_UID_1;
+
+ mInjectedCurrentTimeMillis = START_TIME + INTERVAL - 1;
+ assertEquals(0, mManager.getRemainingCallCount());
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
+ assertEquals(0, mManager.getRemainingCallCount());
+
+ // Now it should work.
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+
+ mInjectedCurrentTimeMillis++;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+
+ mInjectedCurrentTimeMillis++;
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
+
+ mInjectedCurrentTimeMillis = START_TIME + 4 * INTERVAL;
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertTrue(mManager.setDynamicShortcuts(list(si1)));
+ assertFalse(mManager.setDynamicShortcuts(list(si1)));
+
+ mInjectedClientPackage = CALLING_PACKAGE_2;
+ mInjectedCallingUid = CALLING_UID_2;
+
+ assertEquals(3, mManager.getRemainingCallCount());
+
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
+ assertTrue(mManager.setDynamicShortcuts(list(si2)));
+ assertFalse(mManager.setDynamicShortcuts(list(si2)));
+ }
+
+ public void testThrottling_localeChanges() {
+ prepareCrossProfileDataSet();
+
+ dumpsysOnLogcat("Before save & load");
+
+ mService.saveDirtyInfo();
+ initService();
+
+ final long origSequenceNumber = mService.getLocaleChangeSequenceNumber();
+
+ // onSystemLocaleChangedNoLock before boot completed will be ignored.
+ mInternal.onSystemLocaleChangedNoLock();
+ assertEquals(origSequenceNumber, mService.getLocaleChangeSequenceNumber());
+
+ mService.onBootPhase(SystemService.PHASE_BOOT_COMPLETED);
+ mInternal.onSystemLocaleChangedNoLock();
+ assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
+
+ // Note at this point only user-0 is loaded, and the counters are reset for this user,
+ // but it will work for other users too, because we persist when
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+
+ mService.saveDirtyInfo();
+ initService();
+
+ // Make sure the counter is persisted.
+ assertEquals(origSequenceNumber + 1, mService.getLocaleChangeSequenceNumber());
+ }
+
+ public void testThrottling_foreground() throws Exception {
+ prepareCrossProfileDataSet();
+
+ dumpsysOnLogcat("Before save & load");
+
+ mService.saveDirtyInfo();
+ initService();
+
+ // We need to update the current time from time to time, since some of the internal checks
+ // rely on the time being correctly incremented.
+ mInjectedCurrentTimeMillis++;
+
+ // First, all packages have less than 3 (== initial value) remaining calls.
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+
+ mInjectedCurrentTimeMillis++;
+
+ // State changed, but not foreground, so no resetting.
+ mService.mUidObserver.onUidStateChanged(
+ CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+
+ mInjectedCurrentTimeMillis++;
+
+ // State changed, package1 foreground, reset.
+ mService.mUidObserver.onUidStateChanged(
+ CALLING_UID_1, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ mService.mUidObserver.onUidStateChanged(
+ CALLING_UID_1, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+
+ mInjectedCurrentTimeMillis++;
+
+ // Different app comes to foreground briefly, and goes back to background.
+ // Now, make sure package 2's counter is reset, even in this case.
+ mService.mUidObserver.onUidStateChanged(
+ CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ mService.mUidObserver.onUidStateChanged(
+ CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+
+ mInjectedCurrentTimeMillis++;
+
+ // Do the same thing one more time. This would catch the bug with mixuing up
+ // the current time and the elapsed time.
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ mManager.updateShortcuts(list(makeShortcut("s")));
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+
+ mService.mUidObserver.onUidStateChanged(
+ CALLING_UID_2, ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ mService.mUidObserver.onUidStateChanged(
+ CALLING_UID_2, ActivityManager.PROCESS_STATE_TOP_SLEEPING);
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+
+ mInjectedCurrentTimeMillis++;
+
+ // Package 1 on user-10 comes to foreground.
+ // Now, also try calling some APIs and make sure foreground apps don't get throttled.
+ mService.mUidObserver.onUidStateChanged(
+ UserHandle.getUid(USER_10, CALLING_UID_1),
+ ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+
+ assertEquals(0, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+
+ assertEquals(0, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+
+ assertEquals(0, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+
+ assertEquals(0, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+
+ assertEquals(0, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+ mManager.setDynamicShortcuts(list(makeShortcut("s")));
+
+ assertEquals(3, mManager.getRemainingCallCount()); // Still 3!
+ });
+ }
+
+
+ public void testThrottling_resetByInternalCall() throws Exception {
+ prepareCrossProfileDataSet();
+
+ dumpsysOnLogcat("Before save & load");
+
+ mService.saveDirtyInfo();
+ initService();
+
+ // First, all packages have less than 3 (== initial value) remaining calls.
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+
+ // Simulate a call from sys UI.
+ mCallerPermissions.add(permission.RESET_SHORTCUT_MANAGER_THROTTLING);
+ mService.onApplicationActive(CALLING_PACKAGE_1, USER_0);
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+
+ mService.onApplicationActive(CALLING_PACKAGE_3, USER_0);
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+
+ mService.onApplicationActive(CALLING_PACKAGE_1, USER_10);
+
+ runWithCaller(CALLING_PACKAGE_1, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_2, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_3, USER_0, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_4, USER_0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_P0, () -> {
+ MoreAsserts.assertNotEqual(3, mManager.getRemainingCallCount());
+ });
+ runWithCaller(CALLING_PACKAGE_1, USER_10, () -> {
+ assertEquals(3, mManager.getRemainingCallCount());
+ });
+ }
+}
diff --git a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
index 7fa8a80..71878fd 100644
--- a/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
+++ b/services/tests/shortcutmanagerutils/src/com/android/server/pm/shortcutmanagertest/ShortcutManagerTestUtils.java
@@ -31,6 +31,7 @@
import static org.mockito.Mockito.verify;
import android.app.Instrumentation;
+import android.content.ComponentName;
import android.content.Context;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
@@ -38,6 +39,7 @@
import android.graphics.BitmapFactory;
import android.os.BaseBundle;
import android.os.Bundle;
+import android.os.Parcel;
import android.os.ParcelFileDescriptor;
import android.os.UserHandle;
import android.test.MoreAsserts;
@@ -63,6 +65,10 @@
import java.util.function.Function;
import java.util.function.Predicate;
+/**
+ * Common utility methods for ShortcutManager tests. This is used by both CTS and the unit tests.
+ * Because it's used by CTS too, it can only access the public APIs.
+ */
public class ShortcutManagerTestUtils {
private static final String TAG = "ShortcutManagerUtils";
@@ -252,6 +258,17 @@
return list;
}
+ public static List<ShortcutInfo> filterByActivity(List<ShortcutInfo> list,
+ ComponentName activity) {
+ final ArrayList<ShortcutInfo> ret = new ArrayList<>();
+ for (ShortcutInfo si : list) {
+ if (si.getActivity().equals(activity) && (si.isManifestShortcut() || si.isDynamic())) {
+ ret.add(si);
+ }
+ }
+ return ret;
+ }
+
public static void assertExpectException(Class<? extends Throwable> expectedExceptionType,
String expectedExceptionMessageRegex, Runnable r) {
assertExpectException("", expectedExceptionType, expectedExceptionMessageRegex, r);
@@ -317,7 +334,7 @@
public static List<ShortcutInfo> assertAllHaveTitle(
List<ShortcutInfo> actualShortcuts) {
for (ShortcutInfo s : actualShortcuts) {
- assertNotNull("ID " + s.getId(), s.getTitle());
+ assertNotNull("ID " + s.getId(), s.getShortLabel());
}
return actualShortcuts;
}
@@ -325,7 +342,7 @@
public static List<ShortcutInfo> assertAllNotHaveTitle(
List<ShortcutInfo> actualShortcuts) {
for (ShortcutInfo s : actualShortcuts) {
- assertNull("ID " + s.getId(), s.getTitle());
+ assertNull("ID " + s.getId(), s.getShortLabel());
}
return actualShortcuts;
}
@@ -555,6 +572,27 @@
}, "Shortcut IDs=[" + Arrays.toString(ids) + "]", null);
}
+ public static ShortcutInfo parceled(ShortcutInfo si) {
+ Parcel p = Parcel.obtain();
+ p.writeParcelable(si, 0);
+ p.setDataPosition(0);
+ ShortcutInfo si2 = p.readParcelable(ShortcutManagerTestUtils.class.getClassLoader());
+ p.recycle();
+ return si2;
+ }
+
+ public static List<ShortcutInfo> cloneShortcutList(List<ShortcutInfo> list) {
+ if (list == null) {
+ return null;
+ }
+ final List<ShortcutInfo> ret = new ArrayList<>(list.size());
+ for (ShortcutInfo si : list) {
+ ret.add(parceled(si));
+ }
+
+ return ret;
+ }
+
public static void waitUntil(String message, BooleanSupplier condition) {
waitUntil(message, condition, STANDARD_TIMEOUT_SEC);
}
diff --git a/services/usb/java/com/android/server/usb/MtpNotificationManager.java b/services/usb/java/com/android/server/usb/MtpNotificationManager.java
index 101e200..5c46222 100644
--- a/services/usb/java/com/android/server/usb/MtpNotificationManager.java
+++ b/services/usb/java/com/android/server/usb/MtpNotificationManager.java
@@ -139,7 +139,7 @@
if (usbInterface.getInterfaceClass() == UsbConstants.USB_SUBCLASS_VENDOR_SPEC &&
usbInterface.getInterfaceSubclass() == SUBCLASS_MTP &&
usbInterface.getInterfaceProtocol() == PROTOCOL_MTP &&
- usbInterface.getName().equals("MTP")) {
+ "MTP".equals(usbInterface.getName())) {
return true;
}
}
diff --git a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
index 51f5899..23c58fe 100644
--- a/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
+++ b/services/voiceinteraction/java/com/android/server/voiceinteraction/VoiceInteractionManagerService.java
@@ -19,7 +19,6 @@
import android.Manifest;
import android.app.ActivityManager;
import android.app.ActivityManagerInternal;
-import android.app.ActivityManagerNative;
import android.app.AppGlobals;
import android.content.ComponentName;
import android.content.ContentResolver;
@@ -415,7 +414,10 @@
VoiceInteractionServiceInfo findAvailInteractor(int userHandle, String packageName) {
List<ResolveInfo> available =
mContext.getPackageManager().queryIntentServicesAsUser(
- new Intent(VoiceInteractionService.SERVICE_INTERFACE), 0, userHandle);
+ new Intent(VoiceInteractionService.SERVICE_INTERFACE),
+ PackageManager.MATCH_DIRECT_BOOT_AWARE
+ | PackageManager.MATCH_DIRECT_BOOT_UNAWARE
+ | PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userHandle);
int numAvailable = available.size();
if (numAvailable == 0) {
diff --git a/telephony/java/android/telephony/CarrierConfigManager.java b/telephony/java/android/telephony/CarrierConfigManager.java
index 22e2882..851d643 100644
--- a/telephony/java/android/telephony/CarrierConfigManager.java
+++ b/telephony/java/android/telephony/CarrierConfigManager.java
@@ -601,6 +601,19 @@
"wfc_emergency_address_carrier_app_string";
/**
+ * Boolean to decide whether to use #KEY_CARRIER_NAME_STRING from CarrierConfig app.
+ * @hide
+ */
+ public static final String KEY_CARRIER_NAME_OVERRIDE_BOOL = "carrier_name_override_bool";
+
+ /**
+ * String to identify carrier name in CarrierConfig app. This string is used only if
+ * #KEY_CARRIER_NAME_OVERRIDE_BOOL is true
+ * @hide
+ */
+ public static final String KEY_CARRIER_NAME_STRING = "carrier_name_string";
+
+ /**
* If this is true, the SIM card (through Customer Service Profile EF file) will be able to
* prevent manual operator selection. If false, this SIM setting will be ignored and manual
* operator selection will always be available. See CPHS4_2.WW6, CPHS B.4.7.1 for more
@@ -813,6 +826,8 @@
sDefaults.putInt(KEY_WFC_DATA_SPN_FORMAT_IDX_INT, 0);
sDefaults.putString(KEY_WFC_EMERGENCY_ADDRESS_CARRIER_APP_STRING, "");
sDefaults.putBoolean(KEY_CONFIG_WIFI_DISABLE_IN_ECBM, false);
+ sDefaults.putBoolean(KEY_CARRIER_NAME_OVERRIDE_BOOL, false);
+ sDefaults.putString(KEY_CARRIER_NAME_STRING, "");
// MMS defaults
sDefaults.putBoolean(KEY_MMS_ALIAS_ENABLED_BOOL, false);
diff --git a/tools/aapt2/link/ManifestFixer.cpp b/tools/aapt2/link/ManifestFixer.cpp
index 953e87e..77a949f 100644
--- a/tools/aapt2/link/ManifestFixer.cpp
+++ b/tools/aapt2/link/ManifestFixer.cpp
@@ -180,7 +180,6 @@
manifestAction[u"uses-configuration"];
manifestAction[u"uses-feature"];
- manifestAction[u"uses-library"];
manifestAction[u"supports-screens"];
manifestAction[u"compatible-screens"];
manifestAction[u"supports-gl-texture"];
@@ -189,6 +188,9 @@
xml::XmlNodeAction& applicationAction = (*executor)[u"manifest"][u"application"];
applicationAction.action(optionalNameIsJavaClassName);
+ // Uses library actions.
+ applicationAction[u"uses-library"];
+
// Activity actions.
applicationAction[u"activity"].action(requiredNameIsJavaClassName);
applicationAction[u"activity"][u"intent-filter"] = intentFilterAction;